PageSourceSearch

https://bikeindex.org/assets/application_revised-18ce361d651dd69e2…4988459164a4e40de0264fc069bc926051bf38a5.js

js bikeindex.org collected 2026-10-01 10:23:36 UTC 1,799,027 bytes, 57,335 lines download raw bytes

vendor: 9,242 bytes, lines 1-353
1// This vendors these dependencies (see PR#2704)
2// jquery2, jquery_ujs, lodash, jquery.dirtyforms, mustache, Stickyfill, mailcheck,
3// jquery.dirtyforms/plugins/jquery.dirtyforms.dialogs.bootstrap.min.js, moment, moment-timezone
4// select2/select2.full.js, selectize/standalone/selectize.js, zoom.js
5
6/*!
7 * jQuery JavaScript Library v2.2.4
8 * http://jquery.com/
9 *
10 * Includes Sizzle.js
11 * http://sizzlejs.com/
12 *
13 * Copyright jQuery Foundation and other contributors
14 * Released under the MIT license
15 * http://jquery.org/license
16 *
17 * Date: 2016-05-20T17:23Z
18 */
19
20(function( global, factory ) {
21
22  if ( typeof module === "object" && typeof module.exports === "object" ) {
23    // For CommonJS and CommonJS-like environments where a proper `window`
24    // is present, execute the factory and get jQuery.
25    // For environments that do not have a `window` with a `document`
26    // (such as Node.js), expose a factory as module.exports.
27    // This accentuates the need for the creation of a real `window`.
28    // e.g. var jQuery = require("jquery")(window);
29    // See ticket #14549 for more info.
30    module.exports = global.document ?
31      factory( global, true ) :
32      function( w ) {
33        if ( !w.document ) {
34          throw new Error( "jQuery requires a window with a document" );
35        }
36        return factory( w );
37      };
38  } else {
39    factory( global );
40  }
41
42// Pass this if window is not defined yet
43}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
44
45// Support: Firefox 18+
46// Can't be in strict mode, several libs including ASP.NET trace
47// the stack via arguments.caller.callee and Firefox dies if
48// you try to trace through "use strict" call chains. (#13335)
49//"use strict";
50var arr = [];
51
52var document = window.document;
53
54var slice = arr.slice;
55
56var concat = arr.concat;
57
58var push = arr.push;
59
60var indexOf = arr.indexOf;
61
62var class2type = {};
63
64var toString = class2type.toString;
65
66var hasOwn = class2type.hasOwnProperty;
67
68var support = {};
69
70
71
72var
73  version = "2.2.4",
74
75  // Define a local copy of jQuery
76  jQuery = function( selector, context ) {
77
78    // The jQuery object is actually just the init constructor 'enhanced'
79    // Need init if jQuery is called (just allow error to be thrown if not included)
80    return new jQuery.fn.init( selector, context );
81  },
82
83  // Support: Android<4.1
84  // Make sure we trim BOM and NBSP
85  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
86
87  // Matches dashed string for camelizing
88  rmsPrefix = /^-ms-/,
89  rdashAlpha = /-([\da-z])/gi,
90
91  // Used by jQuery.camelCase as callback to replace()
92  fcamelCase = function( all, letter ) {
93    return letter.toUpperCase();
94  };
95
96jQuery.fn = jQuery.prototype = {
97
98  // The current version of jQuery being used
99  jquery: version,
100
101  constructor: jQuery,
102
103  // Start with an empty selector
104  selector: "",
105
106  // The default length of a jQuery object is 0
107  length: 0,
108
109  toArray: function() {
110    return slice.call( this );
111  },
112
113  // Get the Nth element in the matched element set OR
114  // Get the whole matched element set as a clean array
115  get: function( num ) {
116    return num != null ?
117
118      // Return just the one element from the set
119      ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
120
121      // Return all the elements in a clean array
122      slice.call( this );
123  },
124
125  // Take an array of elements and push it onto the stack
126  // (returning the new matched element set)
127  pushStack: function( elems ) {
128
129    // Build a new jQuery matched element set
130    var ret = jQuery.merge( this.constructor(), elems );
131
132    // Add the old object onto the stack (as a reference)
133    ret.prevObject = this;
134    ret.context = this.context;
135
136    // Return the newly-formed element set
137    return ret;
138  },
139
140  // Execute a callback for every element in the matched set.
141  each: function( callback ) {
142    return jQuery.each( this, callback );
143  },
144
145  map: function( callback ) {
146    return this.pushStack( jQuery.map( this, function( elem, i ) {
147      return callback.call( elem, i, elem );
148    } ) );
149  },
150
151  slice: function() {
152    return this.pushStack( slice.apply( this, arguments ) );
153  },
154
155  first: function() {
156    return this.eq( 0 );
157  },
158
159  last: function() {
160    return this.eq( -1 );
161  },
162
163  eq: function( i ) {
164    var len = this.length,
165      j = +i + ( i < 0 ? len : 0 );
166    return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
167  },
168
169  end: function() {
170    return this.prevObject || this.constructor();
171  },
172
173  // For internal use only.
174  // Behaves like an Array's method, not like a jQuery method.
175  push: push,
176  sort: arr.sort,
177  splice: arr.splice
178};
179
180jQuery.extend = jQuery.fn.extend = function() {
181  var options, name, src, copy, copyIsArray, clone,
182    target = arguments[ 0 ] || {},
183    i = 1,
184    length = arguments.length,
185    deep = false;
186
187  // Handle a deep copy situation
188  if ( typeof target === "boolean" ) {
189    deep = target;
190
191    // Skip the boolean and the target
192    target = arguments[ i ] || {};
193    i++;
194  }
195
196  // Handle case when target is a string or something (possible in deep copy)
197  if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
198    target = {};
199  }
200
201  // Extend jQuery itself if only one argument is passed
202  if ( i === length ) {
203    target = this;
204    i--;
205  }
206
207  for ( ; i < length; i++ ) {
208
209    // Only deal with non-null/undefined values
210    if ( ( options = arguments[ i ] ) != null ) {
211
212      // Extend the base object
213      for ( name in options ) {
214        src = target[ name ];
215        copy = options[ name ];
216
217        // Prevent never-ending loop
218        if ( target === copy ) {
219          continue;
220        }
221
222        // Recurse if we're merging plain objects or arrays
223        if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
224          ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
225
226          if ( copyIsArray ) {
227            copyIsArray = false;
228            clone = src && jQuery.isArray( src ) ? src : [];
229
230          } else {
231            clone = src && jQuery.isPlainObject( src ) ? src : {};
232          }
233
234          // Never move original objects, clone them
235          target[ name ] = jQuery.extend( deep, clone, copy );
236
237        // Don't bring in undefined values
238        } else if ( copy !== undefined ) {
239          target[ name ] = copy;
240        }
241      }
242    }
243  }
244
245  // Return the modified object
246  return target;
247};
248
249jQuery.extend( {
250
251  // Unique for each copy of jQuery on the page
252  expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
253
254  // Assume jQuery is ready without the ready module
255  isReady: true,
256
257  error: function( msg ) {
258    throw new Error( msg );
259  },
260
261  noop: function() {},
262
263  isFunction: function( obj ) {
264    return jQuery.type( obj ) === "function";
265  },
266
267  isArray: Array.isArray,
268
269  isWindow: function( obj ) {
270    return obj != null && obj === obj.window;
271  },
272
273  isNumeric: function( obj ) {
274
275    // parseFloat NaNs numeric-cast false positives (null|true|false|"")
276    // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
277    // subtraction forces infinities to NaN
278    // adding 1 corrects loss of precision from parseFloat (#15100)
279    var realStringObj = obj && obj.toString();
280    return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
281  },
282
283  isPlainObject: function( obj ) {
284    var key;
285
286    // Not plain objects:
287    // - Any object or value whose internal [[Class]] property is not "[object Object]"
288    // - DOM nodes
289    // - window
290    if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
291      return false;
292    }
293
294    // Not own constructor property must be Object
295    if ( obj.constructor &&
296        !hasOwn.call( obj, "constructor" ) &&
297        !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
298      return false;
299    }
300
301    // Own properties are enumerated firstly, so to speed up,
302    // if last one is own, then all properties are own
303    for ( key in obj ) {}
304
305    return key === undefined || hasOwn.call( obj, key );
306  },
307
308  isEmptyObject: function( obj ) {
309    var name;
310    for ( name in obj ) {
311      return false;
312    }
313    return true;
314  },
315
316  type: function( obj ) {
317    if ( obj == null ) {
318      return obj + "";
319    }
320
321    // Support: Android<4.0, iOS<6 (functionish RegExp)
322    return typeof obj === "object" || typeof obj === "function" ?
323      class2type[ toString.call( obj ) ] || "object" :
324      typeof obj;
325  },
326
327  // Evaluates a script in a global context
328  globalEval: function( code ) {
329    var script,
330      indirect = eval;
331
332    code = jQuery.trim( code );
333
334    if ( code ) {
335
336      // If the code includes a valid, prologue position
337      // strict mode pragma, execute code by injecting a
338      // script tag into the document.
339      if ( code.indexOf( "use strict" ) === 1 ) {
340        script = document.createElement( "script" );
341        script.text = code;
342        document.head.appendChild( script ).parentNode.removeChild( script );
343      } else {
344
345        // Otherwise, avoid the DOM node creation, insertion
346        // and removal by using an indirect global eval
347
348        indirect( code );
349      }
350    }
351  },
352
353  // Convert dashed to camelCase; used by the css and data modules
vendor: 4,435 bytes, lines 354-535
354  // Support: IE9-11+
355  // Microsoft forgot to hump their vendor prefix (#9572)
356  camelCase: function( string ) {
357    return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
358  },
359
360  nodeName: function( elem, name ) {
361    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
362  },
363
364  each: function( obj, callback ) {
365    var length, i = 0;
366
367    if ( isArrayLike( obj ) ) {
368      length = obj.length;
369      for ( ; i < length; i++ ) {
370        if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371          break;
372        }
373      }
374    } else {
375      for ( i in obj ) {
376        if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
377          break;
378        }
379      }
380    }
381
382    return obj;
383  },
384
385  // Support: Android<4.1
386  trim: function( text ) {
387    return text == null ?
388      "" :
389      ( text + "" ).replace( rtrim, "" );
390  },
391
392  // results is for internal usage only
393  makeArray: function( arr, results ) {
394    var ret = results || [];
395
396    if ( arr != null ) {
397      if ( isArrayLike( Object( arr ) ) ) {
398        jQuery.merge( ret,
399          typeof arr === "string" ?
400          [ arr ] : arr
401        );
402      } else {
403        push.call( ret, arr );
404      }
405    }
406
407    return ret;
408  },
409
410  inArray: function( elem, arr, i ) {
411    return arr == null ? -1 : indexOf.call( arr, elem, i );
412  },
413
414  merge: function( first, second ) {
415    var len = +second.length,
416      j = 0,
417      i = first.length;
418
419    for ( ; j < len; j++ ) {
420      first[ i++ ] = second[ j ];
421    }
422
423    first.length = i;
424
425    return first;
426  },
427
428  grep: function( elems, callback, invert ) {
429    var callbackInverse,
430      matches = [],
431      i = 0,
432      length = elems.length,
433      callbackExpect = !invert;
434
435    // Go through the array, only saving the items
436    // that pass the validator function
437    for ( ; i < length; i++ ) {
438      callbackInverse = !callback( elems[ i ], i );
439      if ( callbackInverse !== callbackExpect ) {
440        matches.push( elems[ i ] );
441      }
442    }
443
444    return matches;
445  },
446
447  // arg is for internal usage only
448  map: function( elems, callback, arg ) {
449    var length, value,
450      i = 0,
451      ret = [];
452
453    // Go through the array, translating each of the items to their new values
454    if ( isArrayLike( elems ) ) {
455      length = elems.length;
456      for ( ; i < length; i++ ) {
457        value = callback( elems[ i ], i, arg );
458
459        if ( value != null ) {
460          ret.push( value );
461        }
462      }
463
464    // Go through every key on the object,
465    } else {
466      for ( i in elems ) {
467        value = callback( elems[ i ], i, arg );
468
469        if ( value != null ) {
470          ret.push( value );
471        }
472      }
473    }
474
475    // Flatten any nested arrays
476    return concat.apply( [], ret );
477  },
478
479  // A global GUID counter for objects
480  guid: 1,
481
482  // Bind a function to a context, optionally partially applying any
483  // arguments.
484  proxy: function( fn, context ) {
485    var tmp, args, proxy;
486
487    if ( typeof context === "string" ) {
488      tmp = fn[ context ];
489      context = fn;
490      fn = tmp;
491    }
492
493    // Quick check to determine if target is callable, in the spec
494    // this throws a TypeError, but we will just return undefined.
495    if ( !jQuery.isFunction( fn ) ) {
496      return undefined;
497    }
498
499    // Simulated bind
500    args = slice.call( arguments, 2 );
501    proxy = function() {
502      return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
503    };
504
505    // Set the guid of unique handler to the same of original handler, so it can be removed
506    proxy.guid = fn.guid = fn.guid || jQuery.guid++;
507
508    return proxy;
509  },
510
511  now: Date.now,
512
513  // jQuery.support is not used in Core but other projects attach their
514  // properties to it so it needs to exist.
515  support: support
516} );
517
518// JSHint would error on this code due to the Symbol not being defined in ES5.
519// Defining this global in .jshintrc would create a danger of using the global
520// unguarded in another place, it seems safer to just disable JSHint for these
521// three lines.
522/* jshint ignore: start */
523if ( typeof Symbol === "function" ) {
524  jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
525}
526/* jshint ignore: end */
527
528// Populate the class2type map
529jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
530function( i, name ) {
531  class2type[ "[object " + name + "]" ] = name.toLowerCase();
532} );
533
534function isArrayLike( obj ) {
535
vendor: 20,062 bytes, lines 536-1197
536  // Support: iOS 8.2 (not reproducible in simulator)
537  // `in` check used to prevent JIT error (gh-2145)
538  // hasOwn isn't used here due to false negatives
539  // regarding Nodelist length in IE
540  var length = !!obj && "length" in obj && obj.length,
541    type = jQuery.type( obj );
542
543  if ( type === "function" || jQuery.isWindow( obj ) ) {
544    return false;
545  }
546
547  return type === "array" || length === 0 ||
548    typeof length === "number" && length > 0 && ( length - 1 ) in obj;
549}
550var Sizzle =
551/*!
552 * Sizzle CSS Selector Engine v2.2.1
553 * http://sizzlejs.com/
554 *
555 * Copyright jQuery Foundation and other contributors
556 * Released under the MIT license
557 * http://jquery.org/license
558 *
559 * Date: 2015-10-17
560 */
561(function( window ) {
562
563var i,
564  support,
565  Expr,
566  getText,
567  isXML,
568  tokenize,
569  compile,
570  select,
571  outermostContext,
572  sortInput,
573  hasDuplicate,
574
575  // Local document vars
576  setDocument,
577  document,
578  docElem,
579  documentIsHTML,
580  rbuggyQSA,
581  rbuggyMatches,
582  matches,
583  contains,
584
585  // Instance-specific data
586  expando = "sizzle" + 1 * new Date(),
587  preferredDoc = window.document,
588  dirruns = 0,
589  done = 0,
590  classCache = createCache(),
591  tokenCache = createCache(),
592  compilerCache = createCache(),
593  sortOrder = function( a, b ) {
594    if ( a === b ) {
595      hasDuplicate = true;
596    }
597    return 0;
598  },
599
600  // General-purpose constants
601  MAX_NEGATIVE = 1 << 31,
602
603  // Instance methods
604  hasOwn = ({}).hasOwnProperty,
605  arr = [],
606  pop = arr.pop,
607  push_native = arr.push,
608  push = arr.push,
609  slice = arr.slice,
610  // Use a stripped-down indexOf as it's faster than native
611  // http://jsperf.com/thor-indexof-vs-for/5
612  indexOf = function( list, elem ) {
613    var i = 0,
614      len = list.length;
615    for ( ; i < len; i++ ) {
616      if ( list[i] === elem ) {
617        return i;
618      }
619    }
620    return -1;
621  },
622
623  booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
624
625  // Regular expressions
626
627  // http://www.w3.org/TR/css3-selectors/#whitespace
628  whitespace = "[\\x20\\t\\r\\n\\f]",
629
630  // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
631  identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
632
633  // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
634  attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
635    // Operator (capture 2)
636    "*([*^$|!~]?=)" + whitespace +
637    // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
638    "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
639    "*\\]",
640
641  pseudos = ":(" + identifier + ")(?:\\((" +
642    // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
643    // 1. quoted (capture 3; capture 4 or capture 5)
644    "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
645    // 2. simple (capture 6)
646    "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
647    // 3. anything else (capture 2)
648    ".*" +
649    ")\\)|)",
650
651  // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
652  rwhitespace = new RegExp( whitespace + "+", "g" ),
653  rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
654
655  rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
656  rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
657
658  rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
659
660  rpseudo = new RegExp( pseudos ),
661  ridentifier = new RegExp( "^" + identifier + "$" ),
662
663  matchExpr = {
664    "ID": new RegExp( "^#(" + identifier + ")" ),
665    "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
666    "TAG": new RegExp( "^(" + identifier + "|[*])" ),
667    "ATTR": new RegExp( "^" + attributes ),
668    "PSEUDO": new RegExp( "^" + pseudos ),
669    "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
670      "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
671      "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
672    "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
673    // For use in libraries implementing .is()
674    // We use this for POS matching in `select`
675    "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
676      whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
677  },
678
679  rinputs = /^(?:input|select|textarea|button)$/i,
680  rheader = /^h\d$/i,
681
682  rnative = /^[^{]+\{\s*\[native \w/,
683
684  // Easily-parseable/retrievable ID or TAG or CLASS selectors
685  rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
686
687  rsibling = /[+~]/,
688  rescape = /'|\\/g,
689
690  // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
691  runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
692  funescape = function( _, escaped, escapedWhitespace ) {
693    var high = "0x" + escaped - 0x10000;
694    // NaN means non-codepoint
695    // Support: Firefox<24
696    // Workaround erroneous numeric interpretation of +"0x"
697    return high !== high || escapedWhitespace ?
698      escaped :
699      high < 0 ?
700        // BMP codepoint
701        String.fromCharCode( high + 0x10000 ) :
702        // Supplemental Plane codepoint (surrogate pair)
703        String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
704  },
705
706  // Used for iframes
707  // See setDocument()
708  // Removing the function wrapper causes a "Permission Denied"
709  // error in IE
710  unloadHandler = function() {
711    setDocument();
712  };
713
714// Optimize for push.apply( _, NodeList )
715try {
716  push.apply(
717    (arr = slice.call( preferredDoc.childNodes )),
718    preferredDoc.childNodes
719  );
720  // Support: Android<4.0
721  // Detect silently failing push.apply
722  arr[ preferredDoc.childNodes.length ].nodeType;
723} catch ( e ) {
724  push = { apply: arr.length ?
725
726    // Leverage slice if possible
727    function( target, els ) {
728      push_native.apply( target, slice.call(els) );
729    } :
730
731    // Support: IE<9
732    // Otherwise append directly
733    function( target, els ) {
734      var j = target.length,
735        i = 0;
736      // Can't trust NodeList.length
737      while ( (target[j++] = els[i++]) ) {}
738      target.length = j - 1;
739    }
740  };
741}
742
743function Sizzle( selector, context, results, seed ) {
744  var m, i, elem, nid, nidselect, match, groups, newSelector,
745    newContext = context && context.ownerDocument,
746
747    // nodeType defaults to 9, since context defaults to document
748    nodeType = context ? context.nodeType : 9;
749
750  results = results || [];
751
752  // Return early from calls with invalid selector or context
753  if ( typeof selector !== "string" || !selector ||
754    nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
755
756    return results;
757  }
758
759  // Try to shortcut find operations (as opposed to filters) in HTML documents
760  if ( !seed ) {
761
762    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
763      setDocument( context );
764    }
765    context = context || document;
766
767    if ( documentIsHTML ) {
768
769      // If the selector is sufficiently simple, try using a "get*By*" DOM method
770      // (excepting DocumentFragment context, where the methods don't exist)
771      if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
772
773        // ID selector
774        if ( (m = match[1]) ) {
775
776          // Document context
777          if ( nodeType === 9 ) {
778            if ( (elem = context.getElementById( m )) ) {
779
780              // Support: IE, Opera, Webkit
781              // TODO: identify versions
782              // getElementById can match elements by name instead of ID
783              if ( elem.id === m ) {
784                results.push( elem );
785                return results;
786              }
787            } else {
788              return results;
789            }
790
791          // Element context
792          } else {
793
794            // Support: IE, Opera, Webkit
795            // TODO: identify versions
796            // getElementById can match elements by name instead of ID
797            if ( newContext && (elem = newContext.getElementById( m )) &&
798              contains( context, elem ) &&
799              elem.id === m ) {
800
801              results.push( elem );
802              return results;
803            }
804          }
805
806        // Type selector
807        } else if ( match[2] ) {
808          push.apply( results, context.getElementsByTagName( selector ) );
809          return results;
810
811        // Class selector
812        } else if ( (m = match[3]) && support.getElementsByClassName &&
813          context.getElementsByClassName ) {
814
815          push.apply( results, context.getElementsByClassName( m ) );
816          return results;
817        }
818      }
819
820      // Take advantage of querySelectorAll
821      if ( support.qsa &&
822        !compilerCache[ selector + " " ] &&
823        (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
824
825        if ( nodeType !== 1 ) {
826          newContext = context;
827          newSelector = selector;
828
829        // qSA looks outside Element context, which is not what we want
830        // Thanks to Andrew Dupont for this workaround technique
831        // Support: IE <=8
832        // Exclude object elements
833        } else if ( context.nodeName.toLowerCase() !== "object" ) {
834
835          // Capture the context ID, setting it first if necessary
836          if ( (nid = context.getAttribute( "id" )) ) {
837            nid = nid.replace( rescape, "\\$&" );
838          } else {
839            context.setAttribute( "id", (nid = expando) );
840          }
841
842          // Prefix every selector in the list
843          groups = tokenize( selector );
844          i = groups.length;
845          nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
846          while ( i-- ) {
847            groups[i] = nidselect + " " + toSelector( groups[i] );
848          }
849          newSelector = groups.join( "," );
850
851          // Expand context for sibling selectors
852          newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
853            context;
854        }
855
856        if ( newSelector ) {
857          try {
858            push.apply( results,
859              newContext.querySelectorAll( newSelector )
860            );
861            return results;
862          } catch ( qsaError ) {
863          } finally {
864            if ( nid === expando ) {
865              context.removeAttribute( "id" );
866            }
867          }
868        }
869      }
870    }
871  }
872
873  // All others
874  return select( selector.replace( rtrim, "$1" ), context, results, seed );
875}
876
877/**
878 * Create key-value caches of limited size
879 * @returns {function(string, object)} Returns the Object data after storing it on itself with
880 *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
881 *  deleting the oldest entry
882 */
883function createCache() {
884  var keys = [];
885
886  function cache( key, value ) {
887    // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
888    if ( keys.push( key + " " ) > Expr.cacheLength ) {
889      // Only keep the most recent entries
890      delete cache[ keys.shift() ];
891    }
892    return (cache[ key + " " ] = value);
893  }
894  return cache;
895}
896
897/**
898 * Mark a function for special use by Sizzle
899 * @param {Function} fn The function to mark
900 */
901function markFunction( fn ) {
902  fn[ expando ] = true;
903  return fn;
904}
905
906/**
907 * Support testing using an element
908 * @param {Function} fn Passed the created div and expects a boolean result
909 */
910function assert( fn ) {
911  var div = document.createElement("div");
912
913  try {
914    return !!fn( div );
915  } catch (e) {
916    return false;
917  } finally {
918    // Remove from its parent by default
919    if ( div.parentNode ) {
920      div.parentNode.removeChild( div );
921    }
922    // release memory in IE
923    div = null;
924  }
925}
926
927/**
928 * Adds the same handler for all of the specified attrs
929 * @param {String} attrs Pipe-separated list of attributes
930 * @param {Function} handler The method that will be applied
931 */
932function addHandle( attrs, handler ) {
933  var arr = attrs.split("|"),
934    i = arr.length;
935
936  while ( i-- ) {
937    Expr.attrHandle[ arr[i] ] = handler;
938  }
939}
940
941/**
942 * Checks document order of two siblings
943 * @param {Element} a
944 * @param {Element} b
945 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
946 */
947function siblingCheck( a, b ) {
948  var cur = b && a,
949    diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
950      ( ~b.sourceIndex || MAX_NEGATIVE ) -
951      ( ~a.sourceIndex || MAX_NEGATIVE );
952
953  // Use IE sourceIndex if available on both nodes
954  if ( diff ) {
955    return diff;
956  }
957
958  // Check if b follows a
959  if ( cur ) {
960    while ( (cur = cur.nextSibling) ) {
961      if ( cur === b ) {
962        return -1;
963      }
964    }
965  }
966
967  return a ? 1 : -1;
968}
969
970/**
971 * Returns a function to use in pseudos for input types
972 * @param {String} type
973 */
974function createInputPseudo( type ) {
975  return function( elem ) {
976    var name = elem.nodeName.toLowerCase();
977    return name === "input" && elem.type === type;
978  };
979}
980
981/**
982 * Returns a function to use in pseudos for buttons
983 * @param {String} type
984 */
985function createButtonPseudo( type ) {
986  return function( elem ) {
987    var name = elem.nodeName.toLowerCase();
988    return (name === "input" || name === "button") && elem.type === type;
989  };
990}
991
992/**
993 * Returns a function to use in pseudos for positionals
994 * @param {Function} fn
995 */
996function createPositionalPseudo( fn ) {
997  return markFunction(function( argument ) {
998    argument = +argument;
999    return markFunction(function( seed, matches ) {
1000      var j,
1001        matchIndexes = fn( [], seed.length, argument ),
1002        i = matchIndexes.length;
1003
1004      // Match elements found at the specified indexes
1005      while ( i-- ) {
1006        if ( seed[ (j = matchIndexes[i]) ] ) {
1007          seed[j] = !(matches[j] = seed[j]);
1008        }
1009      }
1010    });
1011  });
1012}
1013
1014/**
1015 * Checks a node for validity as a Sizzle context
1016 * @param {Element|Object=} context
1017 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1018 */
1019function testContext( context ) {
1020  return context && typeof context.getElementsByTagName !== "undefined" && context;
1021}
1022
1023// Expose support vars for convenience
1024support = Sizzle.support = {};
1025
1026/**
1027 * Detects XML nodes
1028 * @param {Element|Object} elem An element or a document
1029 * @returns {Boolean} True iff elem is a non-HTML XML node
1030 */
1031isXML = Sizzle.isXML = function( elem ) {
1032  // documentElement is verified for cases where it doesn't yet exist
1033  // (such as loading iframes in IE - #4833)
1034  var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1035  return documentElement ? documentElement.nodeName !== "HTML" : false;
1036};
1037
1038/**
1039 * Sets document-related variables once based on the current document
1040 * @param {Element|Object} [doc] An element or document object to use to set the document
1041 * @returns {Object} Returns the current document
1042 */
1043setDocument = Sizzle.setDocument = function( node ) {
1044  var hasCompare, parent,
1045    doc = node ? node.ownerDocument || node : preferredDoc;
1046
1047  // Return early if doc is invalid or already selected
1048  if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1049    return document;
1050  }
1051
1052  // Update global variables
1053  document = doc;
1054  docElem = document.documentElement;
1055  documentIsHTML = !isXML( document );
1056
1057  // Support: IE 9-11, Edge
1058  // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1059  if ( (parent = document.defaultView) && parent.top !== parent ) {
1060    // Support: IE 11
1061    if ( parent.addEventListener ) {
1062      parent.addEventListener( "unload", unloadHandler, false );
1063
1064    // Support: IE 9 - 10 only
1065    } else if ( parent.attachEvent ) {
1066      parent.attachEvent( "onunload", unloadHandler );
1067    }
1068  }
1069
1070  /* Attributes
1071  ---------------------------------------------------------------------- */
1072
1073  // Support: IE<8
1074  // Verify that getAttribute really returns attributes and not properties
1075  // (excepting IE8 booleans)
1076  support.attributes = assert(function( div ) {
1077    div.className = "i";
1078    return !div.getAttribute("className");
1079  });
1080
1081  /* getElement(s)By*
1082  ---------------------------------------------------------------------- */
1083
1084  // Check if getElementsByTagName("*") returns only elements
1085  support.getElementsByTagName = assert(function( div ) {
1086    div.appendChild( document.createComment("") );
1087    return !div.getElementsByTagName("*").length;
1088  });
1089
1090  // Support: IE<9
1091  support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1092
1093  // Support: IE<10
1094  // Check if getElementById returns elements by name
1095  // The broken getElementById methods don't pick up programatically-set names,
1096  // so use a roundabout getElementsByName test
1097  support.getById = assert(function( div ) {
1098    docElem.appendChild( div ).id = expando;
1099    return !document.getElementsByName || !document.getElementsByName( expando ).length;
1100  });
1101
1102  // ID find and filter
1103  if ( support.getById ) {
1104    Expr.find["ID"] = function( id, context ) {
1105      if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1106        var m = context.getElementById( id );
1107        return m ? [ m ] : [];
1108      }
1109    };
1110    Expr.filter["ID"] = function( id ) {
1111      var attrId = id.replace( runescape, funescape );
1112      return function( elem ) {
1113        return elem.getAttribute("id") === attrId;
1114      };
1115    };
1116  } else {
1117    // Support: IE6/7
1118    // getElementById is not reliable as a find shortcut
1119    delete Expr.find["ID"];
1120
1121    Expr.filter["ID"] =  function( id ) {
1122      var attrId = id.replace( runescape, funescape );
1123      return function( elem ) {
1124        var node = typeof elem.getAttributeNode !== "undefined" &&
1125          elem.getAttributeNode("id");
1126        return node && node.value === attrId;
1127      };
1128    };
1129  }
1130
1131  // Tag
1132  Expr.find["TAG"] = support.getElementsByTagName ?
1133    function( tag, context ) {
1134      if ( typeof context.getElementsByTagName !== "undefined" ) {
1135        return context.getElementsByTagName( tag );
1136
1137      // DocumentFragment nodes don't have gEBTN
1138      } else if ( support.qsa ) {
1139        return context.querySelectorAll( tag );
1140      }
1141    } :
1142
1143    function( tag, context ) {
1144      var elem,
1145        tmp = [],
1146        i = 0,
1147        // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1148        results = context.getElementsByTagName( tag );
1149
1150      // Filter out possible comments
1151      if ( tag === "*" ) {
1152        while ( (elem = results[i++]) ) {
1153          if ( elem.nodeType === 1 ) {
1154            tmp.push( elem );
1155          }
1156        }
1157
1158        return tmp;
1159      }
1160      return results;
1161    };
1162
1163  // Class
1164  Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1165    if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1166      return context.getElementsByClassName( className );
1167    }
1168  };
1169
1170  /* QSA/matchesSelector
1171  ---------------------------------------------------------------------- */
1172
1173  // QSA and matchesSelector support
1174
1175  // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1176  rbuggyMatches = [];
1177
1178  // qSa(:focus) reports false when true (Chrome 21)
1179  // We allow this because of a bug in IE8/9 that throws an error
1180  // whenever `document.activeElement` is accessed on an iframe
1181  // So, we allow :focus to pass through QSA all the time to avoid the IE error
1182  // See http://bugs.jquery.com/ticket/13378
1183  rbuggyQSA = [];
1184
1185  if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1186    // Build QSA regex
1187    // Regex strategy adopted from Diego Perini
1188    assert(function( div ) {
1189      // Select is set to empty string on purpose
1190      // This is to test IE's treatment of not explicitly
1191      // setting a boolean content attribute,
1192      // since its presence should be enough
1193      // http://bugs.jquery.com/ticket/12359
1194      docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1195        "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1196        "<option selected=''></option></select>";
1197
vendor: 3,951 bytes, lines 1198-1305
1198      // Support: IE8, Opera 11-12.16
1199      // Nothing should be selected when empty strings follow ^= or $= or *=
1200      // The test attribute must be unknown in Opera but "safe" for WinRT
1201      // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1202      if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1203        rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1204      }
1205
1206      // Support: IE8
1207      // Boolean attributes and "value" are not treated correctly
1208      if ( !div.querySelectorAll("[selected]").length ) {
1209        rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1210      }
1211
1212      // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1213      if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1214        rbuggyQSA.push("~=");
1215      }
1216
1217      // Webkit/Opera - :checked should return selected option elements
1218      // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1219      // IE8 throws error here and will not see later tests
1220      if ( !div.querySelectorAll(":checked").length ) {
1221        rbuggyQSA.push(":checked");
1222      }
1223
1224      // Support: Safari 8+, iOS 8+
1225      // https://bugs.webkit.org/show_bug.cgi?id=136851
1226      // In-page `selector#id sibing-combinator selector` fails
1227      if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1228        rbuggyQSA.push(".#.+[+~]");
1229      }
1230    });
1231
1232    assert(function( div ) {
1233      // Support: Windows 8 Native Apps
1234      // The type and name attributes are restricted during .innerHTML assignment
1235      var input = document.createElement("input");
1236      input.setAttribute( "type", "hidden" );
1237      div.appendChild( input ).setAttribute( "name", "D" );
1238
1239      // Support: IE8
1240      // Enforce case-sensitivity of name attribute
1241      if ( div.querySelectorAll("[name=d]").length ) {
1242        rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1243      }
1244
1245      // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1246      // IE8 throws error here and will not see later tests
1247      if ( !div.querySelectorAll(":enabled").length ) {
1248        rbuggyQSA.push( ":enabled", ":disabled" );
1249      }
1250
1251      // Opera 10-11 does not throw on post-comma invalid pseudos
1252      div.querySelectorAll("*,:x");
1253      rbuggyQSA.push(",.*:");
1254    });
1255  }
1256
1257  if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1258    docElem.webkitMatchesSelector ||
1259    docElem.mozMatchesSelector ||
1260    docElem.oMatchesSelector ||
1261    docElem.msMatchesSelector) )) ) {
1262
1263    assert(function( div ) {
1264      // Check to see if it's possible to do matchesSelector
1265      // on a disconnected node (IE 9)
1266      support.disconnectedMatch = matches.call( div, "div" );
1267
1268      // This should fail with an exception
1269      // Gecko does not error, returns false instead
1270      matches.call( div, "[s!='']:x" );
1271      rbuggyMatches.push( "!=", pseudos );
1272    });
1273  }
1274
1275  rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1276  rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1277
1278  /* Contains
1279  ---------------------------------------------------------------------- */
1280  hasCompare = rnative.test( docElem.compareDocumentPosition );
1281
1282  // Element contains another
1283  // Purposefully self-exclusive
1284  // As in, an element does not contain itself
1285  contains = hasCompare || rnative.test( docElem.contains ) ?
1286    function( a, b ) {
1287      var adown = a.nodeType === 9 ? a.documentElement : a,
1288        bup = b && b.parentNode;
1289      return a === bup || !!( bup && bup.nodeType === 1 && (
1290        adown.contains ?
1291          adown.contains( bup ) :
1292          a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1293      ));
1294    } :
1295    function( a, b ) {
1296      if ( b ) {
1297        while ( (b = b.parentNode) ) {
1298          if ( b === a ) {
1299            return true;
1300          }
1301        }
1302      }
1303      return false;
1304    };
1305
vendor: 15,444 bytes, lines 1306-1814
1306  /* Sorting
1307  ---------------------------------------------------------------------- */
1308
1309  // Document order sorting
1310  sortOrder = hasCompare ?
1311  function( a, b ) {
1312
1313    // Flag for duplicate removal
1314    if ( a === b ) {
1315      hasDuplicate = true;
1316      return 0;
1317    }
1318
1319    // Sort on method existence if only one input has compareDocumentPosition
1320    var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1321    if ( compare ) {
1322      return compare;
1323    }
1324
1325    // Calculate position if both inputs belong to the same document
1326    compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1327      a.compareDocumentPosition( b ) :
1328
1329      // Otherwise we know they are disconnected
1330      1;
1331
1332    // Disconnected nodes
1333    if ( compare & 1 ||
1334      (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1335
1336      // Choose the first element that is related to our preferred document
1337      if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1338        return -1;
1339      }
1340      if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1341        return 1;
1342      }
1343
1344      // Maintain original order
1345      return sortInput ?
1346        ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1347        0;
1348    }
1349
1350    return compare & 4 ? -1 : 1;
1351  } :
1352  function( a, b ) {
1353    // Exit early if the nodes are identical
1354    if ( a === b ) {
1355      hasDuplicate = true;
1356      return 0;
1357    }
1358
1359    var cur,
1360      i = 0,
1361      aup = a.parentNode,
1362      bup = b.parentNode,
1363      ap = [ a ],
1364      bp = [ b ];
1365
1366    // Parentless nodes are either documents or disconnected
1367    if ( !aup || !bup ) {
1368      return a === document ? -1 :
1369        b === document ? 1 :
1370        aup ? -1 :
1371        bup ? 1 :
1372        sortInput ?
1373        ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1374        0;
1375
1376    // If the nodes are siblings, we can do a quick check
1377    } else if ( aup === bup ) {
1378      return siblingCheck( a, b );
1379    }
1380
1381    // Otherwise we need full lists of their ancestors for comparison
1382    cur = a;
1383    while ( (cur = cur.parentNode) ) {
1384      ap.unshift( cur );
1385    }
1386    cur = b;
1387    while ( (cur = cur.parentNode) ) {
1388      bp.unshift( cur );
1389    }
1390
1391    // Walk down the tree looking for a discrepancy
1392    while ( ap[i] === bp[i] ) {
1393      i++;
1394    }
1395
1396    return i ?
1397      // Do a sibling check if the nodes have a common ancestor
1398      siblingCheck( ap[i], bp[i] ) :
1399
1400      // Otherwise nodes in our document sort first
1401      ap[i] === preferredDoc ? -1 :
1402      bp[i] === preferredDoc ? 1 :
1403      0;
1404  };
1405
1406  return document;
1407};
1408
1409Sizzle.matches = function( expr, elements ) {
1410  return Sizzle( expr, null, null, elements );
1411};
1412
1413Sizzle.matchesSelector = function( elem, expr ) {
1414  // Set document vars if needed
1415  if ( ( elem.ownerDocument || elem ) !== document ) {
1416    setDocument( elem );
1417  }
1418
1419  // Make sure that attribute selectors are quoted
1420  expr = expr.replace( rattributeQuotes, "='$1']" );
1421
1422  if ( support.matchesSelector && documentIsHTML &&
1423    !compilerCache[ expr + " " ] &&
1424    ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1425    ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1426
1427    try {
1428      var ret = matches.call( elem, expr );
1429
1430      // IE 9's matchesSelector returns false on disconnected nodes
1431      if ( ret || support.disconnectedMatch ||
1432          // As well, disconnected nodes are said to be in a document
1433          // fragment in IE 9
1434          elem.document && elem.document.nodeType !== 11 ) {
1435        return ret;
1436      }
1437    } catch (e) {}
1438  }
1439
1440  return Sizzle( expr, document, null, [ elem ] ).length > 0;
1441};
1442
1443Sizzle.contains = function( context, elem ) {
1444  // Set document vars if needed
1445  if ( ( context.ownerDocument || context ) !== document ) {
1446    setDocument( context );
1447  }
1448  return contains( context, elem );
1449};
1450
1451Sizzle.attr = function( elem, name ) {
1452  // Set document vars if needed
1453  if ( ( elem.ownerDocument || elem ) !== document ) {
1454    setDocument( elem );
1455  }
1456
1457  var fn = Expr.attrHandle[ name.toLowerCase() ],
1458    // Don't get fooled by Object.prototype properties (jQuery #13807)
1459    val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1460      fn( elem, name, !documentIsHTML ) :
1461      undefined;
1462
1463  return val !== undefined ?
1464    val :
1465    support.attributes || !documentIsHTML ?
1466      elem.getAttribute( name ) :
1467      (val = elem.getAttributeNode(name)) && val.specified ?
1468        val.value :
1469        null;
1470};
1471
1472Sizzle.error = function( msg ) {
1473  throw new Error( "Syntax error, unrecognized expression: " + msg );
1474};
1475
1476/**
1477 * Document sorting and removing duplicates
1478 * @param {ArrayLike} results
1479 */
1480Sizzle.uniqueSort = function( results ) {
1481  var elem,
1482    duplicates = [],
1483    j = 0,
1484    i = 0;
1485
1486  // Unless we *know* we can detect duplicates, assume their presence
1487  hasDuplicate = !support.detectDuplicates;
1488  sortInput = !support.sortStable && results.slice( 0 );
1489  results.sort( sortOrder );
1490
1491  if ( hasDuplicate ) {
1492    while ( (elem = results[i++]) ) {
1493      if ( elem === results[ i ] ) {
1494        j = duplicates.push( i );
1495      }
1496    }
1497    while ( j-- ) {
1498      results.splice( duplicates[ j ], 1 );
1499    }
1500  }
1501
1502  // Clear input after sorting to release objects
1503  // See https://github.com/jquery/sizzle/pull/225
1504  sortInput = null;
1505
1506  return results;
1507};
1508
1509/**
1510 * Utility function for retrieving the text value of an array of DOM nodes
1511 * @param {Array|Element} elem
1512 */
1513getText = Sizzle.getText = function( elem ) {
1514  var node,
1515    ret = "",
1516    i = 0,
1517    nodeType = elem.nodeType;
1518
1519  if ( !nodeType ) {
1520    // If no nodeType, this is expected to be an array
1521    while ( (node = elem[i++]) ) {
1522      // Do not traverse comment nodes
1523      ret += getText( node );
1524    }
1525  } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1526    // Use textContent for elements
1527    // innerText usage removed for consistency of new lines (jQuery #11153)
1528    if ( typeof elem.textContent === "string" ) {
1529      return elem.textContent;
1530    } else {
1531      // Traverse its children
1532      for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1533        ret += getText( elem );
1534      }
1535    }
1536  } else if ( nodeType === 3 || nodeType === 4 ) {
1537    return elem.nodeValue;
1538  }
1539  // Do not include comment or processing instruction nodes
1540
1541  return ret;
1542};
1543
1544Expr = Sizzle.selectors = {
1545
1546  // Can be adjusted by the user
1547  cacheLength: 50,
1548
1549  createPseudo: markFunction,
1550
1551  match: matchExpr,
1552
1553  attrHandle: {},
1554
1555  find: {},
1556
1557  relative: {
1558    ">": { dir: "parentNode", first: true },
1559    " ": { dir: "parentNode" },
1560    "+": { dir: "previousSibling", first: true },
1561    "~": { dir: "previousSibling" }
1562  },
1563
1564  preFilter: {
1565    "ATTR": function( match ) {
1566      match[1] = match[1].replace( runescape, funescape );
1567
1568      // Move the given value to match[3] whether quoted or unquoted
1569      match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1570
1571      if ( match[2] === "~=" ) {
1572        match[3] = " " + match[3] + " ";
1573      }
1574
1575      return match.slice( 0, 4 );
1576    },
1577
1578    "CHILD": function( match ) {
1579      /* matches from matchExpr["CHILD"]
1580        1 type (only|nth|...)
1581        2 what (child|of-type)
1582        3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1583        4 xn-component of xn+y argument ([+-]?\d*n|)
1584        5 sign of xn-component
1585        6 x of xn-component
1586        7 sign of y-component
1587        8 y of y-component
1588      */
1589      match[1] = match[1].toLowerCase();
1590
1591      if ( match[1].slice( 0, 3 ) === "nth" ) {
1592        // nth-* requires argument
1593        if ( !match[3] ) {
1594          Sizzle.error( match[0] );
1595        }
1596
1597        // numeric x and y parameters for Expr.filter.CHILD
1598        // remember that false/true cast respectively to 0/1
1599        match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1600        match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1601
1602      // other types prohibit arguments
1603      } else if ( match[3] ) {
1604        Sizzle.error( match[0] );
1605      }
1606
1607      return match;
1608    },
1609
1610    "PSEUDO": function( match ) {
1611      var excess,
1612        unquoted = !match[6] && match[2];
1613
1614      if ( matchExpr["CHILD"].test( match[0] ) ) {
1615        return null;
1616      }
1617
1618      // Accept quoted arguments as-is
1619      if ( match[3] ) {
1620        match[2] = match[4] || match[5] || "";
1621
1622      // Strip excess characters from unquoted arguments
1623      } else if ( unquoted && rpseudo.test( unquoted ) &&
1624        // Get excess from tokenize (recursively)
1625        (excess = tokenize( unquoted, true )) &&
1626        // advance to the next closing parenthesis
1627        (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1628
1629        // excess is a negative index
1630        match[0] = match[0].slice( 0, excess );
1631        match[2] = unquoted.slice( 0, excess );
1632      }
1633
1634      // Return only captures needed by the pseudo filter method (type and argument)
1635      return match.slice( 0, 3 );
1636    }
1637  },
1638
1639  filter: {
1640
1641    "TAG": function( nodeNameSelector ) {
1642      var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1643      return nodeNameSelector === "*" ?
1644        function() { return true; } :
1645        function( elem ) {
1646          return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1647        };
1648    },
1649
1650    "CLASS": function( className ) {
1651      var pattern = classCache[ className + " " ];
1652
1653      return pattern ||
1654        (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1655        classCache( className, function( elem ) {
1656          return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1657        });
1658    },
1659
1660    "ATTR": function( name, operator, check ) {
1661      return function( elem ) {
1662        var result = Sizzle.attr( elem, name );
1663
1664        if ( result == null ) {
1665          return operator === "!=";
1666        }
1667        if ( !operator ) {
1668          return true;
1669        }
1670
1671        result += "";
1672
1673        return operator === "=" ? result === check :
1674          operator === "!=" ? result !== check :
1675          operator === "^=" ? check && result.indexOf( check ) === 0 :
1676          operator === "*=" ? check && result.indexOf( check ) > -1 :
1677          operator === "$=" ? check && result.slice( -check.length ) === check :
1678          operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1679          operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1680          false;
1681      };
1682    },
1683
1684    "CHILD": function( type, what, argument, first, last ) {
1685      var simple = type.slice( 0, 3 ) !== "nth",
1686        forward = type.slice( -4 ) !== "last",
1687        ofType = what === "of-type";
1688
1689      return first === 1 && last === 0 ?
1690
1691        // Shortcut for :nth-*(n)
1692        function( elem ) {
1693          return !!elem.parentNode;
1694        } :
1695
1696        function( elem, context, xml ) {
1697          var cache, uniqueCache, outerCache, node, nodeIndex, start,
1698            dir = simple !== forward ? "nextSibling" : "previousSibling",
1699            parent = elem.parentNode,
1700            name = ofType && elem.nodeName.toLowerCase(),
1701            useCache = !xml && !ofType,
1702            diff = false;
1703
1704          if ( parent ) {
1705
1706            // :(first|last|only)-(child|of-type)
1707            if ( simple ) {
1708              while ( dir ) {
1709                node = elem;
1710                while ( (node = node[ dir ]) ) {
1711                  if ( ofType ?
1712                    node.nodeName.toLowerCase() === name :
1713                    node.nodeType === 1 ) {
1714
1715                    return false;
1716                  }
1717                }
1718                // Reverse direction for :only-* (if we haven't yet done so)
1719                start = dir = type === "only" && !start && "nextSibling";
1720              }
1721              return true;
1722            }
1723
1724            start = [ forward ? parent.firstChild : parent.lastChild ];
1725
1726            // non-xml :nth-child(...) stores cache data on `parent`
1727            if ( forward && useCache ) {
1728
1729              // Seek `elem` from a previously-cached index
1730
1731              // ...in a gzip-friendly way
1732              node = parent;
1733              outerCache = node[ expando ] || (node[ expando ] = {});
1734
1735              // Support: IE <9 only
1736              // Defend against cloned attroperties (jQuery gh-1709)
1737              uniqueCache = outerCache[ node.uniqueID ] ||
1738                (outerCache[ node.uniqueID ] = {});
1739
1740              cache = uniqueCache[ type ] || [];
1741              nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1742              diff = nodeIndex && cache[ 2 ];
1743              node = nodeIndex && parent.childNodes[ nodeIndex ];
1744
1745              while ( (node = ++nodeIndex && node && node[ dir ] ||
1746
1747                // Fallback to seeking `elem` from the start
1748                (diff = nodeIndex = 0) || start.pop()) ) {
1749
1750                // When found, cache indexes on `parent` and break
1751                if ( node.nodeType === 1 && ++diff && node === elem ) {
1752                  uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1753                  break;
1754                }
1755              }
1756
1757            } else {
1758              // Use previously-cached element index if available
1759              if ( useCache ) {
1760                // ...in a gzip-friendly way
1761                node = elem;
1762                outerCache = node[ expando ] || (node[ expando ] = {});
1763
1764                // Support: IE <9 only
1765                // Defend against cloned attroperties (jQuery gh-1709)
1766                uniqueCache = outerCache[ node.uniqueID ] ||
1767                  (outerCache[ node.uniqueID ] = {});
1768
1769                cache = uniqueCache[ type ] || [];
1770                nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1771                diff = nodeIndex;
1772              }
1773
1774              // xml :nth-child(...)
1775              // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1776              if ( diff === false ) {
1777                // Use the same loop as above to seek `elem` from the start
1778                while ( (node = ++nodeIndex && node && node[ dir ] ||
1779                  (diff = nodeIndex = 0) || start.pop()) ) {
1780
1781                  if ( ( ofType ?
1782                    node.nodeName.toLowerCase() === name :
1783                    node.nodeType === 1 ) &&
1784                    ++diff ) {
1785
1786                    // Cache the index of each encountered element
1787                    if ( useCache ) {
1788                      outerCache = node[ expando ] || (node[ expando ] = {});
1789
1790                      // Support: IE <9 only
1791                      // Defend against cloned attroperties (jQuery gh-1709)
1792                      uniqueCache = outerCache[ node.uniqueID ] ||
1793                        (outerCache[ node.uniqueID ] = {});
1794
1795                      uniqueCache[ type ] = [ dirruns, diff ];
1796                    }
1797
1798                    if ( node === elem ) {
1799                      break;
1800                    }
1801                  }
1802                }
1803              }
1804            }
1805
1806            // Incorporate the offset, then check against cycle size
1807            diff -= last;
1808            return diff === first || ( diff % first === 0 && diff / first >= 0 );
1809          }
1810        };
1811    },
1812
1813    "PSEUDO": function( pseudo, argument ) {
1814      // pseudo-class names are case-insensitive
vendor: 4,537 bytes, lines 1815-1949
1815      // http://www.w3.org/TR/selectors/#pseudo-classes
1816      // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1817      // Remember that setFilters inherits from pseudos
1818      var args,
1819        fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1820          Sizzle.error( "unsupported pseudo: " + pseudo );
1821
1822      // The user may use createPseudo to indicate that
1823      // arguments are needed to create the filter function
1824      // just as Sizzle does
1825      if ( fn[ expando ] ) {
1826        return fn( argument );
1827      }
1828
1829      // But maintain support for old signatures
1830      if ( fn.length > 1 ) {
1831        args = [ pseudo, pseudo, "", argument ];
1832        return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1833          markFunction(function( seed, matches ) {
1834            var idx,
1835              matched = fn( seed, argument ),
1836              i = matched.length;
1837            while ( i-- ) {
1838              idx = indexOf( seed, matched[i] );
1839              seed[ idx ] = !( matches[ idx ] = matched[i] );
1840            }
1841          }) :
1842          function( elem ) {
1843            return fn( elem, 0, args );
1844          };
1845      }
1846
1847      return fn;
1848    }
1849  },
1850
1851  pseudos: {
1852    // Potentially complex pseudos
1853    "not": markFunction(function( selector ) {
1854      // Trim the selector passed to compile
1855      // to avoid treating leading and trailing
1856      // spaces as combinators
1857      var input = [],
1858        results = [],
1859        matcher = compile( selector.replace( rtrim, "$1" ) );
1860
1861      return matcher[ expando ] ?
1862        markFunction(function( seed, matches, context, xml ) {
1863          var elem,
1864            unmatched = matcher( seed, null, xml, [] ),
1865            i = seed.length;
1866
1867          // Match elements unmatched by `matcher`
1868          while ( i-- ) {
1869            if ( (elem = unmatched[i]) ) {
1870              seed[i] = !(matches[i] = elem);
1871            }
1872          }
1873        }) :
1874        function( elem, context, xml ) {
1875          input[0] = elem;
1876          matcher( input, null, xml, results );
1877          // Don't keep the element (issue #299)
1878          input[0] = null;
1879          return !results.pop();
1880        };
1881    }),
1882
1883    "has": markFunction(function( selector ) {
1884      return function( elem ) {
1885        return Sizzle( selector, elem ).length > 0;
1886      };
1887    }),
1888
1889    "contains": markFunction(function( text ) {
1890      text = text.replace( runescape, funescape );
1891      return function( elem ) {
1892        return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1893      };
1894    }),
1895
1896    // "Whether an element is represented by a :lang() selector
1897    // is based solely on the element's language value
1898    // being equal to the identifier C,
1899    // or beginning with the identifier C immediately followed by "-".
1900    // The matching of C against the element's language value is performed case-insensitively.
1901    // The identifier C does not have to be a valid language name."
1902    // http://www.w3.org/TR/selectors/#lang-pseudo
1903    "lang": markFunction( function( lang ) {
1904      // lang value must be a valid identifier
1905      if ( !ridentifier.test(lang || "") ) {
1906        Sizzle.error( "unsupported lang: " + lang );
1907      }
1908      lang = lang.replace( runescape, funescape ).toLowerCase();
1909      return function( elem ) {
1910        var elemLang;
1911        do {
1912          if ( (elemLang = documentIsHTML ?
1913            elem.lang :
1914            elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1915
1916            elemLang = elemLang.toLowerCase();
1917            return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1918          }
1919        } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1920        return false;
1921      };
1922    }),
1923
1924    // Miscellaneous
1925    "target": function( elem ) {
1926      var hash = window.location && window.location.hash;
1927      return hash && hash.slice( 1 ) === elem.id;
1928    },
1929
1930    "root": function( elem ) {
1931      return elem === docElem;
1932    },
1933
1934    "focus": function( elem ) {
1935      return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1936    },
1937
1938    // Boolean properties
1939    "enabled": function( elem ) {
1940      return elem.disabled === false;
1941    },
1942
1943    "disabled": function( elem ) {
1944      return elem.disabled === true;
1945    },
1946
1947    "checked": function( elem ) {
1948      // In CSS3, :checked should return both checked and selected elements
1949      // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#
vendor: 11,328 bytes, lines 1949-2344
1949checked
1950      var nodeName = elem.nodeName.toLowerCase();
1951      return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1952    },
1953
1954    "selected": function( elem ) {
1955      // Accessing this property makes selected-by-default
1956      // options in Safari work properly
1957      if ( elem.parentNode ) {
1958        elem.parentNode.selectedIndex;
1959      }
1960
1961      return elem.selected === true;
1962    },
1963
1964    // Contents
1965    "empty": function( elem ) {
1966      // http://www.w3.org/TR/selectors/#empty-pseudo
1967      // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1968      //   but not by others (comment: 8; processing instruction: 7; etc.)
1969      // nodeType < 6 works because attributes (2) do not appear as children
1970      for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1971        if ( elem.nodeType < 6 ) {
1972          return false;
1973        }
1974      }
1975      return true;
1976    },
1977
1978    "parent": function( elem ) {
1979      return !Expr.pseudos["empty"]( elem );
1980    },
1981
1982    // Element/input types
1983    "header": function( elem ) {
1984      return rheader.test( elem.nodeName );
1985    },
1986
1987    "input": function( elem ) {
1988      return rinputs.test( elem.nodeName );
1989    },
1990
1991    "button": function( elem ) {
1992      var name = elem.nodeName.toLowerCase();
1993      return name === "input" && elem.type === "button" || name === "button";
1994    },
1995
1996    "text": function( elem ) {
1997      var attr;
1998      return elem.nodeName.toLowerCase() === "input" &&
1999        elem.type === "text" &&
2000
2001        // Support: IE<8
2002        // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2003        ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2004    },
2005
2006    // Position-in-collection
2007    "first": createPositionalPseudo(function() {
2008      return [ 0 ];
2009    }),
2010
2011    "last": createPositionalPseudo(function( matchIndexes, length ) {
2012      return [ length - 1 ];
2013    }),
2014
2015    "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2016      return [ argument < 0 ? argument + length : argument ];
2017    }),
2018
2019    "even": createPositionalPseudo(function( matchIndexes, length ) {
2020      var i = 0;
2021      for ( ; i < length; i += 2 ) {
2022        matchIndexes.push( i );
2023      }
2024      return matchIndexes;
2025    }),
2026
2027    "odd": createPositionalPseudo(function( matchIndexes, length ) {
2028      var i = 1;
2029      for ( ; i < length; i += 2 ) {
2030        matchIndexes.push( i );
2031      }
2032      return matchIndexes;
2033    }),
2034
2035    "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2036      var i = argument < 0 ? argument + length : argument;
2037      for ( ; --i >= 0; ) {
2038        matchIndexes.push( i );
2039      }
2040      return matchIndexes;
2041    }),
2042
2043    "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2044      var i = argument < 0 ? argument + length : argument;
2045      for ( ; ++i < length; ) {
2046        matchIndexes.push( i );
2047      }
2048      return matchIndexes;
2049    })
2050  }
2051};
2052
2053Expr.pseudos["nth"] = Expr.pseudos["eq"];
2054
2055// Add button/input type pseudos
2056for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2057  Expr.pseudos[ i ] = createInputPseudo( i );
2058}
2059for ( i in { submit: true, reset: true } ) {
2060  Expr.pseudos[ i ] = createButtonPseudo( i );
2061}
2062
2063// Easy API for creating new setFilters
2064function setFilters() {}
2065setFilters.prototype = Expr.filters = Expr.pseudos;
2066Expr.setFilters = new setFilters();
2067
2068tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2069  var matched, match, tokens, type,
2070    soFar, groups, preFilters,
2071    cached = tokenCache[ selector + " " ];
2072
2073  if ( cached ) {
2074    return parseOnly ? 0 : cached.slice( 0 );
2075  }
2076
2077  soFar = selector;
2078  groups = [];
2079  preFilters = Expr.preFilter;
2080
2081  while ( soFar ) {
2082
2083    // Comma and first run
2084    if ( !matched || (match = rcomma.exec( soFar )) ) {
2085      if ( match ) {
2086        // Don't consume trailing commas as valid
2087        soFar = soFar.slice( match[0].length ) || soFar;
2088      }
2089      groups.push( (tokens = []) );
2090    }
2091
2092    matched = false;
2093
2094    // Combinators
2095    if ( (match = rcombinators.exec( soFar )) ) {
2096      matched = match.shift();
2097      tokens.push({
2098        value: matched,
2099        // Cast descendant combinators to space
2100        type: match[0].replace( rtrim, " " )
2101      });
2102      soFar = soFar.slice( matched.length );
2103    }
2104
2105    // Filters
2106    for ( type in Expr.filter ) {
2107      if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2108        (match = preFilters[ type ]( match ))) ) {
2109        matched = match.shift();
2110        tokens.push({
2111          value: matched,
2112          type: type,
2113          matches: match
2114        });
2115        soFar = soFar.slice( matched.length );
2116      }
2117    }
2118
2119    if ( !matched ) {
2120      break;
2121    }
2122  }
2123
2124  // Return the length of the invalid excess
2125  // if we're just parsing
2126  // Otherwise, throw an error or return tokens
2127  return parseOnly ?
2128    soFar.length :
2129    soFar ?
2130      Sizzle.error( selector ) :
2131      // Cache the tokens
2132      tokenCache( selector, groups ).slice( 0 );
2133};
2134
2135function toSelector( tokens ) {
2136  var i = 0,
2137    len = tokens.length,
2138    selector = "";
2139  for ( ; i < len; i++ ) {
2140    selector += tokens[i].value;
2141  }
2142  return selector;
2143}
2144
2145function addCombinator( matcher, combinator, base ) {
2146  var dir = combinator.dir,
2147    checkNonElements = base && dir === "parentNode",
2148    doneName = done++;
2149
2150  return combinator.first ?
2151    // Check against closest ancestor/preceding element
2152    function( elem, context, xml ) {
2153      while ( (elem = elem[ dir ]) ) {
2154        if ( elem.nodeType === 1 || checkNonElements ) {
2155          return matcher( elem, context, xml );
2156        }
2157      }
2158    } :
2159
2160    // Check against all ancestor/preceding elements
2161    function( elem, context, xml ) {
2162      var oldCache, uniqueCache, outerCache,
2163        newCache = [ dirruns, doneName ];
2164
2165      // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2166      if ( xml ) {
2167        while ( (elem = elem[ dir ]) ) {
2168          if ( elem.nodeType === 1 || checkNonElements ) {
2169            if ( matcher( elem, context, xml ) ) {
2170              return true;
2171            }
2172          }
2173        }
2174      } else {
2175        while ( (elem = elem[ dir ]) ) {
2176          if ( elem.nodeType === 1 || checkNonElements ) {
2177            outerCache = elem[ expando ] || (elem[ expando ] = {});
2178
2179            // Support: IE <9 only
2180            // Defend against cloned attroperties (jQuery gh-1709)
2181            uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2182
2183            if ( (oldCache = uniqueCache[ dir ]) &&
2184              oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2185
2186              // Assign to newCache so results back-propagate to previous elements
2187              return (newCache[ 2 ] = oldCache[ 2 ]);
2188            } else {
2189              // Reuse newcache so results back-propagate to previous elements
2190              uniqueCache[ dir ] = newCache;
2191
2192              // A match means we're done; a fail means we have to keep checking
2193              if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2194                return true;
2195              }
2196            }
2197          }
2198        }
2199      }
2200    };
2201}
2202
2203function elementMatcher( matchers ) {
2204  return matchers.length > 1 ?
2205    function( elem, context, xml ) {
2206      var i = matchers.length;
2207      while ( i-- ) {
2208        if ( !matchers[i]( elem, context, xml ) ) {
2209          return false;
2210        }
2211      }
2212      return true;
2213    } :
2214    matchers[0];
2215}
2216
2217function multipleContexts( selector, contexts, results ) {
2218  var i = 0,
2219    len = contexts.length;
2220  for ( ; i < len; i++ ) {
2221    Sizzle( selector, contexts[i], results );
2222  }
2223  return results;
2224}
2225
2226function condense( unmatched, map, filter, context, xml ) {
2227  var elem,
2228    newUnmatched = [],
2229    i = 0,
2230    len = unmatched.length,
2231    mapped = map != null;
2232
2233  for ( ; i < len; i++ ) {
2234    if ( (elem = unmatched[i]) ) {
2235      if ( !filter || filter( elem, context, xml ) ) {
2236        newUnmatched.push( elem );
2237        if ( mapped ) {
2238          map.push( i );
2239        }
2240      }
2241    }
2242  }
2243
2244  return newUnmatched;
2245}
2246
2247function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2248  if ( postFilter && !postFilter[ expando ] ) {
2249    postFilter = setMatcher( postFilter );
2250  }
2251  if ( postFinder && !postFinder[ expando ] ) {
2252    postFinder = setMatcher( postFinder, postSelector );
2253  }
2254  return markFunction(function( seed, results, context, xml ) {
2255    var temp, i, elem,
2256      preMap = [],
2257      postMap = [],
2258      preexisting = results.length,
2259
2260      // Get initial elements from seed or context
2261      elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2262
2263      // Prefilter to get matcher input, preserving a map for seed-results synchronization
2264      matcherIn = preFilter && ( seed || !selector ) ?
2265        condense( elems, preMap, preFilter, context, xml ) :
2266        elems,
2267
2268      matcherOut = matcher ?
2269        // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2270        postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2271
2272          // ...intermediate processing is necessary
2273          [] :
2274
2275          // ...otherwise use results directly
2276          results :
2277        matcherIn;
2278
2279    // Find primary matches
2280    if ( matcher ) {
2281      matcher( matcherIn, matcherOut, context, xml );
2282    }
2283
2284    // Apply postFilter
2285    if ( postFilter ) {
2286      temp = condense( matcherOut, postMap );
2287      postFilter( temp, [], context, xml );
2288
2289      // Un-match failing elements by moving them back to matcherIn
2290      i = temp.length;
2291      while ( i-- ) {
2292        if ( (elem = temp[i]) ) {
2293          matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2294        }
2295      }
2296    }
2297
2298    if ( seed ) {
2299      if ( postFinder || preFilter ) {
2300        if ( postFinder ) {
2301          // Get the final matcherOut by condensing this intermediate into postFinder contexts
2302          temp = [];
2303          i = matcherOut.length;
2304          while ( i-- ) {
2305            if ( (elem = matcherOut[i]) ) {
2306              // Restore matcherIn since elem is not yet a final match
2307              temp.push( (matcherIn[i] = elem) );
2308            }
2309          }
2310          postFinder( null, (matcherOut = []), temp, xml );
2311        }
2312
2313        // Move matched elements from seed to results to keep them synchronized
2314        i = matcherOut.length;
2315        while ( i-- ) {
2316          if ( (elem = matcherOut[i]) &&
2317            (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2318
2319            seed[temp] = !(results[temp] = elem);
2320          }
2321        }
2322      }
2323
2324    // Add elements to results, through postFinder if defined
2325    } else {
2326      matcherOut = condense(
2327        matcherOut === results ?
2328          matcherOut.splice( preexisting, matcherOut.length ) :
2329          matcherOut
2330      );
2331      if ( postFinder ) {
2332        postFinder( null, results, matcherOut, xml );
2333      } else {
2334        push.apply( results, matcherOut );
2335      }
2336    }
2337  });
2338}
2339
2340function matcherFromTokens( tokens ) {
2341  var checkContext, matcher, j,
2342    len = tokens.length,
2343    leadingRelative = Expr.relative[ tokens[0].type ],
2344    implicitRelative = leadingRelative || Expr.relative[" "],
vendor: 8,519 bytes, lines 2345-2589
2345    i = leadingRelative ? 1 : 0,
2346
2347    // The foundational matcher ensures that elements are reachable from top-level context(s)
2348    matchContext = addCombinator( function( elem ) {
2349      return elem === checkContext;
2350    }, implicitRelative, true ),
2351    matchAnyContext = addCombinator( function( elem ) {
2352      return indexOf( checkContext, elem ) > -1;
2353    }, implicitRelative, true ),
2354    matchers = [ function( elem, context, xml ) {
2355      var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2356        (checkContext = context).nodeType ?
2357          matchContext( elem, context, xml ) :
2358          matchAnyContext( elem, context, xml ) );
2359      // Avoid hanging onto element (issue #299)
2360      checkContext = null;
2361      return ret;
2362    } ];
2363
2364  for ( ; i < len; i++ ) {
2365    if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2366      matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2367    } else {
2368      matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2369
2370      // Return special upon seeing a positional matcher
2371      if ( matcher[ expando ] ) {
2372        // Find the next relative operator (if any) for proper handling
2373        j = ++i;
2374        for ( ; j < len; j++ ) {
2375          if ( Expr.relative[ tokens[j].type ] ) {
2376            break;
2377          }
2378        }
2379        return setMatcher(
2380          i > 1 && elementMatcher( matchers ),
2381          i > 1 && toSelector(
2382            // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2383            tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2384          ).replace( rtrim, "$1" ),
2385          matcher,
2386          i < j && matcherFromTokens( tokens.slice( i, j ) ),
2387          j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2388          j < len && toSelector( tokens )
2389        );
2390      }
2391      matchers.push( matcher );
2392    }
2393  }
2394
2395  return elementMatcher( matchers );
2396}
2397
2398function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2399  var bySet = setMatchers.length > 0,
2400    byElement = elementMatchers.length > 0,
2401    superMatcher = function( seed, context, xml, results, outermost ) {
2402      var elem, j, matcher,
2403        matchedCount = 0,
2404        i = "0",
2405        unmatched = seed && [],
2406        setMatched = [],
2407        contextBackup = outermostContext,
2408        // We must always have either seed elements or outermost context
2409        elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2410        // Use integer dirruns iff this is the outermost matcher
2411        dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2412        len = elems.length;
2413
2414      if ( outermost ) {
2415        outermostContext = context === document || context || outermost;
2416      }
2417
2418      // Add elements passing elementMatchers directly to results
2419      // Support: IE<9, Safari
2420      // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2421      for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2422        if ( byElement && elem ) {
2423          j = 0;
2424          if ( !context && elem.ownerDocument !== document ) {
2425            setDocument( elem );
2426            xml = !documentIsHTML;
2427          }
2428          while ( (matcher = elementMatchers[j++]) ) {
2429            if ( matcher( elem, context || document, xml) ) {
2430              results.push( elem );
2431              break;
2432            }
2433          }
2434          if ( outermost ) {
2435            dirruns = dirrunsUnique;
2436          }
2437        }
2438
2439        // Track unmatched elements for set filters
2440        if ( bySet ) {
2441          // They will have gone through all possible matchers
2442          if ( (elem = !matcher && elem) ) {
2443            matchedCount--;
2444          }
2445
2446          // Lengthen the array for every element, matched or not
2447          if ( seed ) {
2448            unmatched.push( elem );
2449          }
2450        }
2451      }
2452
2453      // `i` is now the count of elements visited above, and adding it to `matchedCount`
2454      // makes the latter nonnegative.
2455      matchedCount += i;
2456
2457      // Apply set filters to unmatched elements
2458      // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2459      // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2460      // no element matchers and no seed.
2461      // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2462      // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2463      // numerically zero.
2464      if ( bySet && i !== matchedCount ) {
2465        j = 0;
2466        while ( (matcher = setMatchers[j++]) ) {
2467          matcher( unmatched, setMatched, context, xml );
2468        }
2469
2470        if ( seed ) {
2471          // Reintegrate element matches to eliminate the need for sorting
2472          if ( matchedCount > 0 ) {
2473            while ( i-- ) {
2474              if ( !(unmatched[i] || setMatched[i]) ) {
2475                setMatched[i] = pop.call( results );
2476              }
2477            }
2478          }
2479
2480          // Discard index placeholder values to get only actual matches
2481          setMatched = condense( setMatched );
2482        }
2483
2484        // Add matches to results
2485        push.apply( results, setMatched );
2486
2487        // Seedless set matches succeeding multiple successful matchers stipulate sorting
2488        if ( outermost && !seed && setMatched.length > 0 &&
2489          ( matchedCount + setMatchers.length ) > 1 ) {
2490
2491          Sizzle.uniqueSort( results );
2492        }
2493      }
2494
2495      // Override manipulation of globals by nested matchers
2496      if ( outermost ) {
2497        dirruns = dirrunsUnique;
2498        outermostContext = contextBackup;
2499      }
2500
2501      return unmatched;
2502    };
2503
2504  return bySet ?
2505    markFunction( superMatcher ) :
2506    superMatcher;
2507}
2508
2509compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2510  var i,
2511    setMatchers = [],
2512    elementMatchers = [],
2513    cached = compilerCache[ selector + " " ];
2514
2515  if ( !cached ) {
2516    // Generate a function of recursive functions that can be used to check each element
2517    if ( !match ) {
2518      match = tokenize( selector );
2519    }
2520    i = match.length;
2521    while ( i-- ) {
2522      cached = matcherFromTokens( match[i] );
2523      if ( cached[ expando ] ) {
2524        setMatchers.push( cached );
2525      } else {
2526        elementMatchers.push( cached );
2527      }
2528    }
2529
2530    // Cache the compiled function
2531    cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2532
2533    // Save selector and tokenization
2534    cached.selector = selector;
2535  }
2536  return cached;
2537};
2538
2539/**
2540 * A low-level selection function that works with Sizzle's compiled
2541 *  selector functions
2542 * @param {String|Function} selector A selector or a pre-compiled
2543 *  selector function built with Sizzle.compile
2544 * @param {Element} context
2545 * @param {Array} [results]
2546 * @param {Array} [seed] A set of elements to match against
2547 */
2548select = Sizzle.select = function( selector, context, results, seed ) {
2549  var i, tokens, token, type, find,
2550    compiled = typeof selector === "function" && selector,
2551    match = !seed && tokenize( (selector = compiled.selector || selector) );
2552
2553  results = results || [];
2554
2555  // Try to minimize operations if there is only one selector in the list and no seed
2556  // (the latter of which guarantees us context)
2557  if ( match.length === 1 ) {
2558
2559    // Reduce context if the leading compound selector is an ID
2560    tokens = match[0] = match[0].slice( 0 );
2561    if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2562        support.getById && context.nodeType === 9 && documentIsHTML &&
2563        Expr.relative[ tokens[1].type ] ) {
2564
2565      context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2566      if ( !context ) {
2567        return results;
2568
2569      // Precompiled matchers will still verify ancestry, so step up a level
2570      } else if ( compiled ) {
2571        context = context.parentNode;
2572      }
2573
2574      selector = selector.slice( tokens.shift().value.length );
2575    }
2576
2577    // Fetch a seed set for right-to-left matching
2578    i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2579    while ( i-- ) {
2580      token = tokens[i];
2581
2582      // Abort if we hit a combinator
2583      if ( Expr.relative[ (type = token.type) ] ) {
2584        break;
2585      }
2586      if ( (find = Expr.find[ type ]) ) {
2587        // Search, expanding context for leading sibling combinators
2588        if ( (seed = find(
2589          token.matches[0].replace( runescape, funescape ),
vendor: 48,150 bytes, lines 2590-4351
2590          rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2591        )) ) {
2592
2593          // If seed is empty or no tokens remain, we can return early
2594          tokens.splice( i, 1 );
2595          selector = seed.length && toSelector( tokens );
2596          if ( !selector ) {
2597            push.apply( results, seed );
2598            return results;
2599          }
2600
2601          break;
2602        }
2603      }
2604    }
2605  }
2606
2607  // Compile and execute a filtering function if one is not provided
2608  // Provide `match` to avoid retokenization if we modified the selector above
2609  ( compiled || compile( selector, match ) )(
2610    seed,
2611    context,
2612    !documentIsHTML,
2613    results,
2614    !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2615  );
2616  return results;
2617};
2618
2619// One-time assignments
2620
2621// Sort stability
2622support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2623
2624// Support: Chrome 14-35+
2625// Always assume duplicates if they aren't passed to the comparison function
2626support.detectDuplicates = !!hasDuplicate;
2627
2628// Initialize against the default document
2629setDocument();
2630
2631// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2632// Detached nodes confoundingly follow *each other*
2633support.sortDetached = assert(function( div1 ) {
2634  // Should return 1, but returns 4 (following)
2635  return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2636});
2637
2638// Support: IE<8
2639// Prevent attribute/property "interpolation"
2640// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2641if ( !assert(function( div ) {
2642  div.innerHTML = "<a href='#'></a>";
2643  return div.firstChild.getAttribute("href") === "#" ;
2644}) ) {
2645  addHandle( "type|href|height|width", function( elem, name, isXML ) {
2646    if ( !isXML ) {
2647      return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2648    }
2649  });
2650}
2651
2652// Support: IE<9
2653// Use defaultValue in place of getAttribute("value")
2654if ( !support.attributes || !assert(function( div ) {
2655  div.innerHTML = "<input/>";
2656  div.firstChild.setAttribute( "value", "" );
2657  return div.firstChild.getAttribute( "value" ) === "";
2658}) ) {
2659  addHandle( "value", function( elem, name, isXML ) {
2660    if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2661      return elem.defaultValue;
2662    }
2663  });
2664}
2665
2666// Support: IE<9
2667// Use getAttributeNode to fetch booleans when getAttribute lies
2668if ( !assert(function( div ) {
2669  return div.getAttribute("disabled") == null;
2670}) ) {
2671  addHandle( booleans, function( elem, name, isXML ) {
2672    var val;
2673    if ( !isXML ) {
2674      return elem[ name ] === true ? name.toLowerCase() :
2675          (val = elem.getAttributeNode( name )) && val.specified ?
2676          val.value :
2677        null;
2678    }
2679  });
2680}
2681
2682return Sizzle;
2683
2684})( window );
2685
2686
2687
2688jQuery.find = Sizzle;
2689jQuery.expr = Sizzle.selectors;
2690jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2691jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2692jQuery.text = Sizzle.getText;
2693jQuery.isXMLDoc = Sizzle.isXML;
2694jQuery.contains = Sizzle.contains;
2695
2696
2697
2698var dir = function( elem, dir, until ) {
2699  var matched = [],
2700    truncate = until !== undefined;
2701
2702  while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2703    if ( elem.nodeType === 1 ) {
2704      if ( truncate && jQuery( elem ).is( until ) ) {
2705        break;
2706      }
2707      matched.push( elem );
2708    }
2709  }
2710  return matched;
2711};
2712
2713
2714var siblings = function( n, elem ) {
2715  var matched = [];
2716
2717  for ( ; n; n = n.nextSibling ) {
2718    if ( n.nodeType === 1 && n !== elem ) {
2719      matched.push( n );
2720    }
2721  }
2722
2723  return matched;
2724};
2725
2726
2727var rneedsContext = jQuery.expr.match.needsContext;
2728
2729var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2730
2731
2732
2733var risSimple = /^.[^:#\[\.,]*$/;
2734
2735// Implement the identical functionality for filter and not
2736function winnow( elements, qualifier, not ) {
2737  if ( jQuery.isFunction( qualifier ) ) {
2738    return jQuery.grep( elements, function( elem, i ) {
2739      /* jshint -W018 */
2740      return !!qualifier.call( elem, i, elem ) !== not;
2741    } );
2742
2743  }
2744
2745  if ( qualifier.nodeType ) {
2746    return jQuery.grep( elements, function( elem ) {
2747      return ( elem === qualifier ) !== not;
2748    } );
2749
2750  }
2751
2752  if ( typeof qualifier === "string" ) {
2753    if ( risSimple.test( qualifier ) ) {
2754      return jQuery.filter( qualifier, elements, not );
2755    }
2756
2757    qualifier = jQuery.filter( qualifier, elements );
2758  }
2759
2760  return jQuery.grep( elements, function( elem ) {
2761    return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2762  } );
2763}
2764
2765jQuery.filter = function( expr, elems, not ) {
2766  var elem = elems[ 0 ];
2767
2768  if ( not ) {
2769    expr = ":not(" + expr + ")";
2770  }
2771
2772  return elems.length === 1 && elem.nodeType === 1 ?
2773    jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2774    jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2775      return elem.nodeType === 1;
2776    } ) );
2777};
2778
2779jQuery.fn.extend( {
2780  find: function( selector ) {
2781    var i,
2782      len = this.length,
2783      ret = [],
2784      self = this;
2785
2786    if ( typeof selector !== "string" ) {
2787      return this.pushStack( jQuery( selector ).filter( function() {
2788        for ( i = 0; i < len; i++ ) {
2789          if ( jQuery.contains( self[ i ], this ) ) {
2790            return true;
2791          }
2792        }
2793      } ) );
2794    }
2795
2796    for ( i = 0; i < len; i++ ) {
2797      jQuery.find( selector, self[ i ], ret );
2798    }
2799
2800    // Needed because $( selector, context ) becomes $( context ).find( selector )
2801    ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2802    ret.selector = this.selector ? this.selector + " " + selector : selector;
2803    return ret;
2804  },
2805  filter: function( selector ) {
2806    return this.pushStack( winnow( this, selector || [], false ) );
2807  },
2808  not: function( selector ) {
2809    return this.pushStack( winnow( this, selector || [], true ) );
2810  },
2811  is: function( selector ) {
2812    return !!winnow(
2813      this,
2814
2815      // If this is a positional/relative selector, check membership in the returned set
2816      // so $("p:first").is("p:last") won't return true for a doc with two "p".
2817      typeof selector === "string" && rneedsContext.test( selector ) ?
2818        jQuery( selector ) :
2819        selector || [],
2820      false
2821    ).length;
2822  }
2823} );
2824
2825
2826// Initialize a jQuery object
2827
2828
2829// A central reference to the root jQuery(document)
2830var rootjQuery,
2831
2832  // A simple way to check for HTML strings
2833  // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2834  // Strict HTML recognition (#11290: must start with <)
2835  rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2836
2837  init = jQuery.fn.init = function( selector, context, root ) {
2838    var match, elem;
2839
2840    // HANDLE: $(""), $(null), $(undefined), $(false)
2841    if ( !selector ) {
2842      return this;
2843    }
2844
2845    // Method init() accepts an alternate rootjQuery
2846    // so migrate can support jQuery.sub (gh-2101)
2847    root = root || rootjQuery;
2848
2849    // Handle HTML strings
2850    if ( typeof selector === "string" ) {
2851      if ( selector[ 0 ] === "<" &&
2852        selector[ selector.length - 1 ] === ">" &&
2853        selector.length >= 3 ) {
2854
2855        // Assume that strings that start and end with <> are HTML and skip the regex check
2856        match = [ null, selector, null ];
2857
2858      } else {
2859        match = rquickExpr.exec( selector );
2860      }
2861
2862      // Match html or make sure no context is specified for #id
2863      if ( match && ( match[ 1 ] || !context ) ) {
2864
2865        // HANDLE: $(html) -> $(array)
2866        if ( match[ 1 ] ) {
2867          context = context instanceof jQuery ? context[ 0 ] : context;
2868
2869          // Option to run scripts is true for back-compat
2870          // Intentionally let the error be thrown if parseHTML is not present
2871          jQuery.merge( this, jQuery.parseHTML(
2872            match[ 1 ],
2873            context && context.nodeType ? context.ownerDocument || context : document,
2874            true
2875          ) );
2876
2877          // HANDLE: $(html, props)
2878          if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2879            for ( match in context ) {
2880
2881              // Properties of context are called as methods if possible
2882              if ( jQuery.isFunction( this[ match ] ) ) {
2883                this[ match ]( context[ match ] );
2884
2885              // ...and otherwise set as attributes
2886              } else {
2887                this.attr( match, context[ match ] );
2888              }
2889            }
2890          }
2891
2892          return this;
2893
2894        // HANDLE: $(#id)
2895        } else {
2896          elem = document.getElementById( match[ 2 ] );
2897
2898          // Support: Blackberry 4.6
2899          // gEBID returns nodes no longer in the document (#6963)
2900          if ( elem && elem.parentNode ) {
2901
2902            // Inject the element directly into the jQuery object
2903            this.length = 1;
2904            this[ 0 ] = elem;
2905          }
2906
2907          this.context = document;
2908          this.selector = selector;
2909          return this;
2910        }
2911
2912      // HANDLE: $(expr, $(...))
2913      } else if ( !context || context.jquery ) {
2914        return ( context || root ).find( selector );
2915
2916      // HANDLE: $(expr, context)
2917      // (which is just equivalent to: $(context).find(expr)
2918      } else {
2919        return this.constructor( context ).find( selector );
2920      }
2921
2922    // HANDLE: $(DOMElement)
2923    } else if ( selector.nodeType ) {
2924      this.context = this[ 0 ] = selector;
2925      this.length = 1;
2926      return this;
2927
2928    // HANDLE: $(function)
2929    // Shortcut for document ready
2930    } else if ( jQuery.isFunction( selector ) ) {
2931      return root.ready !== undefined ?
2932        root.ready( selector ) :
2933
2934        // Execute immediately if ready is not present
2935        selector( jQuery );
2936    }
2937
2938    if ( selector.selector !== undefined ) {
2939      this.selector = selector.selector;
2940      this.context = selector.context;
2941    }
2942
2943    return jQuery.makeArray( selector, this );
2944  };
2945
2946// Give the init function the jQuery prototype for later instantiation
2947init.prototype = jQuery.fn;
2948
2949// Initialize central reference
2950rootjQuery = jQuery( document );
2951
2952
2953var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2954
2955  // Methods guaranteed to produce a unique set when starting from a unique set
2956  guaranteedUnique = {
2957    children: true,
2958    contents: true,
2959    next: true,
2960    prev: true
2961  };
2962
2963jQuery.fn.extend( {
2964  has: function( target ) {
2965    var targets = jQuery( target, this ),
2966      l = targets.length;
2967
2968    return this.filter( function() {
2969      var i = 0;
2970      for ( ; i < l; i++ ) {
2971        if ( jQuery.contains( this, targets[ i ] ) ) {
2972          return true;
2973        }
2974      }
2975    } );
2976  },
2977
2978  closest: function( selectors, context ) {
2979    var cur,
2980      i = 0,
2981      l = this.length,
2982      matched = [],
2983      pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2984        jQuery( selectors, context || this.context ) :
2985        0;
2986
2987    for ( ; i < l; i++ ) {
2988      for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
2989
2990        // Always skip document fragments
2991        if ( cur.nodeType < 11 && ( pos ?
2992          pos.index( cur ) > -1 :
2993
2994          // Don't pass non-elements to Sizzle
2995          cur.nodeType === 1 &&
2996            jQuery.find.matchesSelector( cur, selectors ) ) ) {
2997
2998          matched.push( cur );
2999          break;
3000        }
3001      }
3002    }
3003
3004    return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3005  },
3006
3007  // Determine the position of an element within the set
3008  index: function( elem ) {
3009
3010    // No argument, return index in parent
3011    if ( !elem ) {
3012      return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3013    }
3014
3015    // Index in selector
3016    if ( typeof elem === "string" ) {
3017      return indexOf.call( jQuery( elem ), this[ 0 ] );
3018    }
3019
3020    // Locate the position of the desired element
3021    return indexOf.call( this,
3022
3023      // If it receives a jQuery object, the first element is used
3024      elem.jquery ? elem[ 0 ] : elem
3025    );
3026  },
3027
3028  add: function( selector, context ) {
3029    return this.pushStack(
3030      jQuery.uniqueSort(
3031        jQuery.merge( this.get(), jQuery( selector, context ) )
3032      )
3033    );
3034  },
3035
3036  addBack: function( selector ) {
3037    return this.add( selector == null ?
3038      this.prevObject : this.prevObject.filter( selector )
3039    );
3040  }
3041} );
3042
3043function sibling( cur, dir ) {
3044  while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3045  return cur;
3046}
3047
3048jQuery.each( {
3049  parent: function( elem ) {
3050    var parent = elem.parentNode;
3051    return parent && parent.nodeType !== 11 ? parent : null;
3052  },
3053  parents: function( elem ) {
3054    return dir( elem, "parentNode" );
3055  },
3056  parentsUntil: function( elem, i, until ) {
3057    return dir( elem, "parentNode", until );
3058  },
3059  next: function( elem ) {
3060    return sibling( elem, "nextSibling" );
3061  },
3062  prev: function( elem ) {
3063    return sibling( elem, "previousSibling" );
3064  },
3065  nextAll: function( elem ) {
3066    return dir( elem, "nextSibling" );
3067  },
3068  prevAll: function( elem ) {
3069    return dir( elem, "previousSibling" );
3070  },
3071  nextUntil: function( elem, i, until ) {
3072    return dir( elem, "nextSibling", until );
3073  },
3074  prevUntil: function( elem, i, until ) {
3075    return dir( elem, "previousSibling", until );
3076  },
3077  siblings: function( elem ) {
3078    return siblings( ( elem.parentNode || {} ).firstChild, elem );
3079  },
3080  children: function( elem ) {
3081    return siblings( elem.firstChild );
3082  },
3083  contents: function( elem ) {
3084    return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3085  }
3086}, function( name, fn ) {
3087  jQuery.fn[ name ] = function( until, selector ) {
3088    var matched = jQuery.map( this, fn, until );
3089
3090    if ( name.slice( -5 ) !== "Until" ) {
3091      selector = until;
3092    }
3093
3094    if ( selector && typeof selector === "string" ) {
3095      matched = jQuery.filter( selector, matched );
3096    }
3097
3098    if ( this.length > 1 ) {
3099
3100      // Remove duplicates
3101      if ( !guaranteedUnique[ name ] ) {
3102        jQuery.uniqueSort( matched );
3103      }
3104
3105      // Reverse order for parents* and prev-derivatives
3106      if ( rparentsprev.test( name ) ) {
3107        matched.reverse();
3108      }
3109    }
3110
3111    return this.pushStack( matched );
3112  };
3113} );
3114var rnotwhite = ( /\S+/g );
3115
3116
3117
3118// Convert String-formatted options into Object-formatted ones
3119function createOptions( options ) {
3120  var object = {};
3121  jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3122    object[ flag ] = true;
3123  } );
3124  return object;
3125}
3126
3127/*
3128 * Create a callback list using the following parameters:
3129 *
3130 *  options: an optional list of space-separated options that will change how
3131 *      the callback list behaves or a more traditional option object
3132 *
3133 * By default a callback list will act like an event callback list and can be
3134 * "fired" multiple times.
3135 *
3136 * Possible options:
3137 *
3138 *  once:     will ensure the callback list can only be fired once (like a Deferred)
3139 *
3140 *  memory:     will keep track of previous values and will call any callback added
3141 *          after the list has been fired right away with the latest "memorized"
3142 *          values (like a Deferred)
3143 *
3144 *  unique:     will ensure a callback can only be added once (no duplicate in the list)
3145 *
3146 *  stopOnFalse:  interrupt callings when a callback returns false
3147 *
3148 */
3149jQuery.Callbacks = function( options ) {
3150
3151  // Convert options from String-formatted to Object-formatted if needed
3152  // (we check in cache first)
3153  options = typeof options === "string" ?
3154    createOptions( options ) :
3155    jQuery.extend( {}, options );
3156
3157  var // Flag to know if list is currently firing
3158    firing,
3159
3160    // Last fire value for non-forgettable lists
3161    memory,
3162
3163    // Flag to know if list was already fired
3164    fired,
3165
3166    // Flag to prevent firing
3167    locked,
3168
3169    // Actual callback list
3170    list = [],
3171
3172    // Queue of execution data for repeatable lists
3173    queue = [],
3174
3175    // Index of currently firing callback (modified by add/remove as needed)
3176    firingIndex = -1,
3177
3178    // Fire callbacks
3179    fire = function() {
3180
3181      // Enforce single-firing
3182      locked = options.once;
3183
3184      // Execute callbacks for all pending executions,
3185      // respecting firingIndex overrides and runtime changes
3186      fired = firing = true;
3187      for ( ; queue.length; firingIndex = -1 ) {
3188        memory = queue.shift();
3189        while ( ++firingIndex < list.length ) {
3190
3191          // Run callback and check for early termination
3192          if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3193            options.stopOnFalse ) {
3194
3195            // Jump to end and forget the data so .add doesn't re-fire
3196            firingIndex = list.length;
3197            memory = false;
3198          }
3199        }
3200      }
3201
3202      // Forget the data if we're done with it
3203      if ( !options.memory ) {
3204        memory = false;
3205      }
3206
3207      firing = false;
3208
3209      // Clean up if we're done firing for good
3210      if ( locked ) {
3211
3212        // Keep an empty list if we have data for future add calls
3213        if ( memory ) {
3214          list = [];
3215
3216        // Otherwise, this object is spent
3217        } else {
3218          list = "";
3219        }
3220      }
3221    },
3222
3223    // Actual Callbacks object
3224    self = {
3225
3226      // Add a callback or a collection of callbacks to the list
3227      add: function() {
3228        if ( list ) {
3229
3230          // If we have memory from a past run, we should fire after adding
3231          if ( memory && !firing ) {
3232            firingIndex = list.length - 1;
3233            queue.push( memory );
3234          }
3235
3236          ( function add( args ) {
3237            jQuery.each( args, function( _, arg ) {
3238              if ( jQuery.isFunction( arg ) ) {
3239                if ( !options.unique || !self.has( arg ) ) {
3240                  list.push( arg );
3241                }
3242              } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3243
3244                // Inspect recursively
3245                add( arg );
3246              }
3247            } );
3248          } )( arguments );
3249
3250          if ( memory && !firing ) {
3251            fire();
3252          }
3253        }
3254        return this;
3255      },
3256
3257      // Remove a callback from the list
3258      remove: function() {
3259        jQuery.each( arguments, function( _, arg ) {
3260          var index;
3261          while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3262            list.splice( index, 1 );
3263
3264            // Handle firing indexes
3265            if ( index <= firingIndex ) {
3266              firingIndex--;
3267            }
3268          }
3269        } );
3270        return this;
3271      },
3272
3273      // Check if a given callback is in the list.
3274      // If no argument is given, return whether or not list has callbacks attached.
3275      has: function( fn ) {
3276        return fn ?
3277          jQuery.inArray( fn, list ) > -1 :
3278          list.length > 0;
3279      },
3280
3281      // Remove all callbacks from the list
3282      empty: function() {
3283        if ( list ) {
3284          list = [];
3285        }
3286        return this;
3287      },
3288
3289      // Disable .fire and .add
3290      // Abort any current/pending executions
3291      // Clear all callbacks and values
3292      disable: function() {
3293        locked = queue = [];
3294        list = memory = "";
3295        return this;
3296      },
3297      disabled: function() {
3298        return !list;
3299      },
3300
3301      // Disable .fire
3302      // Also disable .add unless we have memory (since it would have no effect)
3303      // Abort any pending executions
3304      lock: function() {
3305        locked = queue = [];
3306        if ( !memory ) {
3307          list = memory = "";
3308        }
3309        return this;
3310      },
3311      locked: function() {
3312        return !!locked;
3313      },
3314
3315      // Call all callbacks with the given context and arguments
3316      fireWith: function( context, args ) {
3317        if ( !locked ) {
3318          args = args || [];
3319          args = [ context, args.slice ? args.slice() : args ];
3320          queue.push( args );
3321          if ( !firing ) {
3322            fire();
3323          }
3324        }
3325        return this;
3326      },
3327
3328      // Call all the callbacks with the given arguments
3329      fire: function() {
3330        self.fireWith( this, arguments );
3331        return this;
3332      },
3333
3334      // To know if the callbacks have already been called at least once
3335      fired: function() {
3336        return !!fired;
3337      }
3338    };
3339
3340  return self;
3341};
3342
3343
3344jQuery.extend( {
3345
3346  Deferred: function( func ) {
3347    var tuples = [
3348
3349        // action, add listener, listener list, final state
3350        [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3351        [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3352        [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3353      ],
3354      state = "pending",
3355      promise = {
3356        state: function() {
3357          return state;
3358        },
3359        always: function() {
3360          deferred.done( arguments ).fail( arguments );
3361          return this;
3362        },
3363        then: function( /* fnDone, fnFail, fnProgress */ ) {
3364          var fns = arguments;
3365          return jQuery.Deferred( function( newDefer ) {
3366            jQuery.each( tuples, function( i, tuple ) {
3367              var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3368
3369              // deferred[ done | fail | progress ] for forwarding actions to newDefer
3370              deferred[ tuple[ 1 ] ]( function() {
3371                var returned = fn && fn.apply( this, arguments );
3372                if ( returned && jQuery.isFunction( returned.promise ) ) {
3373                  returned.promise()
3374                    .progress( newDefer.notify )
3375                    .done( newDefer.resolve )
3376                    .fail( newDefer.reject );
3377                } else {
3378                  newDefer[ tuple[ 0 ] + "With" ](
3379                    this === promise ? newDefer.promise() : this,
3380                    fn ? [ returned ] : arguments
3381                  );
3382                }
3383              } );
3384            } );
3385            fns = null;
3386          } ).promise();
3387        },
3388
3389        // Get a promise for this deferred
3390        // If obj is provided, the promise aspect is added to the object
3391        promise: function( obj ) {
3392          return obj != null ? jQuery.extend( obj, promise ) : promise;
3393        }
3394      },
3395      deferred = {};
3396
3397    // Keep pipe for back-compat
3398    promise.pipe = promise.then;
3399
3400    // Add list-specific methods
3401    jQuery.each( tuples, function( i, tuple ) {
3402      var list = tuple[ 2 ],
3403        stateString = tuple[ 3 ];
3404
3405      // promise[ done | fail | progress ] = list.add
3406      promise[ tuple[ 1 ] ] = list.add;
3407
3408      // Handle state
3409      if ( stateString ) {
3410        list.add( function() {
3411
3412          // state = [ resolved | rejected ]
3413          state = stateString;
3414
3415        // [ reject_list | resolve_list ].disable; progress_list.lock
3416        }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3417      }
3418
3419      // deferred[ resolve | reject | notify ]
3420      deferred[ tuple[ 0 ] ] = function() {
3421        deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3422        return this;
3423      };
3424      deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3425    } );
3426
3427    // Make the deferred a promise
3428    promise.promise( deferred );
3429
3430    // Call given func if any
3431    if ( func ) {
3432      func.call( deferred, deferred );
3433    }
3434
3435    // All done!
3436    return deferred;
3437  },
3438
3439  // Deferred helper
3440  when: function( subordinate /* , ..., subordinateN */ ) {
3441    var i = 0,
3442      resolveValues = slice.call( arguments ),
3443      length = resolveValues.length,
3444
3445      // the count of uncompleted subordinates
3446      remaining = length !== 1 ||
3447        ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3448
3449      // the master Deferred.
3450      // If resolveValues consist of only a single Deferred, just use that.
3451      deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3452
3453      // Update function for both resolve and progress values
3454      updateFunc = function( i, contexts, values ) {
3455        return function( value ) {
3456          contexts[ i ] = this;
3457          values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3458          if ( values === progressValues ) {
3459            deferred.notifyWith( contexts, values );
3460          } else if ( !( --remaining ) ) {
3461            deferred.resolveWith( contexts, values );
3462          }
3463        };
3464      },
3465
3466      progressValues, progressContexts, resolveContexts;
3467
3468    // Add listeners to Deferred subordinates; treat others as resolved
3469    if ( length > 1 ) {
3470      progressValues = new Array( length );
3471      progressContexts = new Array( length );
3472      resolveContexts = new Array( length );
3473      for ( ; i < length; i++ ) {
3474        if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3475          resolveValues[ i ].promise()
3476            .progress( updateFunc( i, progressContexts, progressValues ) )
3477            .done( updateFunc( i, resolveContexts, resolveValues ) )
3478            .fail( deferred.reject );
3479        } else {
3480          --remaining;
3481        }
3482      }
3483    }
3484
3485    // If we're not waiting on anything, resolve the master
3486    if ( !remaining ) {
3487      deferred.resolveWith( resolveContexts, resolveValues );
3488    }
3489
3490    return deferred.promise();
3491  }
3492} );
3493
3494
3495// The deferred used on DOM ready
3496var readyList;
3497
3498jQuery.fn.ready = function( fn ) {
3499
3500  // Add the callback
3501  jQuery.ready.promise().done( fn );
3502
3503  return this;
3504};
3505
3506jQuery.extend( {
3507
3508  // Is the DOM ready to be used? Set to true once it occurs.
3509  isReady: false,
3510
3511  // A counter to track how many items to wait for before
3512  // the ready event fires. See #6781
3513  readyWait: 1,
3514
3515  // Hold (or release) the ready event
3516  holdReady: function( hold ) {
3517    if ( hold ) {
3518      jQuery.readyWait++;
3519    } else {
3520      jQuery.ready( true );
3521    }
3522  },
3523
3524  // Handle when the DOM is ready
3525  ready: function( wait ) {
3526
3527    // Abort if there are pending holds or we're already ready
3528    if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3529      return;
3530    }
3531
3532    // Remember that the DOM is ready
3533    jQuery.isReady = true;
3534
3535    // If a normal DOM Ready event fired, decrement, and wait if need be
3536    if ( wait !== true && --jQuery.readyWait > 0 ) {
3537      return;
3538    }
3539
3540    // If there are functions bound, to execute
3541    readyList.resolveWith( document, [ jQuery ] );
3542
3543    // Trigger any bound ready events
3544    if ( jQuery.fn.triggerHandler ) {
3545      jQuery( document ).triggerHandler( "ready" );
3546      jQuery( document ).off( "ready" );
3547    }
3548  }
3549} );
3550
3551/**
3552 * The ready event handler and self cleanup method
3553 */
3554function completed() {
3555  document.removeEventListener( "DOMContentLoaded", completed );
3556  window.removeEventListener( "load", completed );
3557  jQuery.ready();
3558}
3559
3560jQuery.ready.promise = function( obj ) {
3561  if ( !readyList ) {
3562
3563    readyList = jQuery.Deferred();
3564
3565    // Catch cases where $(document).ready() is called
3566    // after the browser event has already occurred.
3567    // Support: IE9-10 only
3568    // Older IE sometimes signals "interactive" too soon
3569    if ( document.readyState === "complete" ||
3570      ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3571
3572      // Handle it asynchronously to allow scripts the opportunity to delay ready
3573      window.setTimeout( jQuery.ready );
3574
3575    } else {
3576
3577      // Use the handy event callback
3578      document.addEventListener( "DOMContentLoaded", completed );
3579
3580      // A fallback to window.onload, that will always work
3581      window.addEventListener( "load", completed );
3582    }
3583  }
3584  return readyList.promise( obj );
3585};
3586
3587// Kick off the DOM ready check even if the user does not
3588jQuery.ready.promise();
3589
3590
3591
3592
3593// Multifunctional method to get and set values of a collection
3594// The value/s can optionally be executed if it's a function
3595var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3596  var i = 0,
3597    len = elems.length,
3598    bulk = key == null;
3599
3600  // Sets many values
3601  if ( jQuery.type( key ) === "object" ) {
3602    chainable = true;
3603    for ( i in key ) {
3604      access( elems, fn, i, key[ i ], true, emptyGet, raw );
3605    }
3606
3607  // Sets one value
3608  } else if ( value !== undefined ) {
3609    chainable = true;
3610
3611    if ( !jQuery.isFunction( value ) ) {
3612      raw = true;
3613    }
3614
3615    if ( bulk ) {
3616
3617      // Bulk operations run against the entire set
3618      if ( raw ) {
3619        fn.call( elems, value );
3620        fn = null;
3621
3622      // ...except when executing function values
3623      } else {
3624        bulk = fn;
3625        fn = function( elem, key, value ) {
3626          return bulk.call( jQuery( elem ), value );
3627        };
3628      }
3629    }
3630
3631    if ( fn ) {
3632      for ( ; i < len; i++ ) {
3633        fn(
3634          elems[ i ], key, raw ?
3635          value :
3636          value.call( elems[ i ], i, fn( elems[ i ], key ) )
3637        );
3638      }
3639    }
3640  }
3641
3642  return chainable ?
3643    elems :
3644
3645    // Gets
3646    bulk ?
3647      fn.call( elems ) :
3648      len ? fn( elems[ 0 ], key ) : emptyGet;
3649};
3650var acceptData = function( owner ) {
3651
3652  // Accepts only:
3653  //  - Node
3654  //    - Node.ELEMENT_NODE
3655  //    - Node.DOCUMENT_NODE
3656  //  - Object
3657  //    - Any
3658  /* jshint -W018 */
3659  return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3660};
3661
3662
3663
3664
3665function Data() {
3666  this.expando = jQuery.expando + Data.uid++;
3667}
3668
3669Data.uid = 1;
3670
3671Data.prototype = {
3672
3673  register: function( owner, initial ) {
3674    var value = initial || {};
3675
3676    // If it is a node unlikely to be stringify-ed or looped over
3677    // use plain assignment
3678    if ( owner.nodeType ) {
3679      owner[ this.expando ] = value;
3680
3681    // Otherwise secure it in a non-enumerable, non-writable property
3682    // configurability must be true to allow the property to be
3683    // deleted with the delete operator
3684    } else {
3685      Object.defineProperty( owner, this.expando, {
3686        value: value,
3687        writable: true,
3688        configurable: true
3689      } );
3690    }
3691    return owner[ this.expando ];
3692  },
3693  cache: function( owner ) {
3694
3695    // We can accept data for non-element nodes in modern browsers,
3696    // but we should not, see #8335.
3697    // Always return an empty object.
3698    if ( !acceptData( owner ) ) {
3699      return {};
3700    }
3701
3702    // Check if the owner object already has a cache
3703    var value = owner[ this.expando ];
3704
3705    // If not, create one
3706    if ( !value ) {
3707      value = {};
3708
3709      // We can accept data for non-element nodes in modern browsers,
3710      // but we should not, see #8335.
3711      // Always return an empty object.
3712      if ( acceptData( owner ) ) {
3713
3714        // If it is a node unlikely to be stringify-ed or looped over
3715        // use plain assignment
3716        if ( owner.nodeType ) {
3717          owner[ this.expando ] = value;
3718
3719        // Otherwise secure it in a non-enumerable property
3720        // configurable must be true to allow the property to be
3721        // deleted when data is removed
3722        } else {
3723          Object.defineProperty( owner, this.expando, {
3724            value: value,
3725            configurable: true
3726          } );
3727        }
3728      }
3729    }
3730
3731    return value;
3732  },
3733  set: function( owner, data, value ) {
3734    var prop,
3735      cache = this.cache( owner );
3736
3737    // Handle: [ owner, key, value ] args
3738    if ( typeof data === "string" ) {
3739      cache[ data ] = value;
3740
3741    // Handle: [ owner, { properties } ] args
3742    } else {
3743
3744      // Copy the properties one-by-one to the cache object
3745      for ( prop in data ) {
3746        cache[ prop ] = data[ prop ];
3747      }
3748    }
3749    return cache;
3750  },
3751  get: function( owner, key ) {
3752    return key === undefined ?
3753      this.cache( owner ) :
3754      owner[ this.expando ] && owner[ this.expando ][ key ];
3755  },
3756  access: function( owner, key, value ) {
3757    var stored;
3758
3759    // In cases where either:
3760    //
3761    //   1. No key was specified
3762    //   2. A string key was specified, but no value provided
3763    //
3764    // Take the "read" path and allow the get method to determine
3765    // which value to return, respectively either:
3766    //
3767    //   1. The entire cache object
3768    //   2. The data stored at the key
3769    //
3770    if ( key === undefined ||
3771        ( ( key && typeof key === "string" ) && value === undefined ) ) {
3772
3773      stored = this.get( owner, key );
3774
3775      return stored !== undefined ?
3776        stored : this.get( owner, jQuery.camelCase( key ) );
3777    }
3778
3779    // When the key is not a string, or both a key and value
3780    // are specified, set or extend (existing objects) with either:
3781    //
3782    //   1. An object of properties
3783    //   2. A key and value
3784    //
3785    this.set( owner, key, value );
3786
3787    // Since the "set" path can have two possible entry points
3788    // return the expected data based on which path was taken[*]
3789    return value !== undefined ? value : key;
3790  },
3791  remove: function( owner, key ) {
3792    var i, name, camel,
3793      cache = owner[ this.expando ];
3794
3795    if ( cache === undefined ) {
3796      return;
3797    }
3798
3799    if ( key === undefined ) {
3800      this.register( owner );
3801
3802    } else {
3803
3804      // Support array or space separated string of keys
3805      if ( jQuery.isArray( key ) ) {
3806
3807        // If "name" is an array of keys...
3808        // When data is initially created, via ("key", "val") signature,
3809        // keys will be converted to camelCase.
3810        // Since there is no way to tell _how_ a key was added, remove
3811        // both plain key and camelCase key. #12786
3812        // This will only penalize the array argument path.
3813        name = key.concat( key.map( jQuery.camelCase ) );
3814      } else {
3815        camel = jQuery.camelCase( key );
3816
3817        // Try the string as a key before any manipulation
3818        if ( key in cache ) {
3819          name = [ key, camel ];
3820        } else {
3821
3822          // If a key with the spaces exists, use it.
3823          // Otherwise, create an array by matching non-whitespace
3824          name = camel;
3825          name = name in cache ?
3826            [ name ] : ( name.match( rnotwhite ) || [] );
3827        }
3828      }
3829
3830      i = name.length;
3831
3832      while ( i-- ) {
3833        delete cache[ name[ i ] ];
3834      }
3835    }
3836
3837    // Remove the expando if there's no more data
3838    if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
3839
3840      // Support: Chrome <= 35-45+
3841      // Webkit & Blink performance suffers when deleting properties
3842      // from DOM nodes, so set to undefined instead
3843      // https://code.google.com/p/chromium/issues/detail?id=378607
3844      if ( owner.nodeType ) {
3845        owner[ this.expando ] = undefined;
3846      } else {
3847        delete owner[ this.expando ];
3848      }
3849    }
3850  },
3851  hasData: function( owner ) {
3852    var cache = owner[ this.expando ];
3853    return cache !== undefined && !jQuery.isEmptyObject( cache );
3854  }
3855};
3856var dataPriv = new Data();
3857
3858var dataUser = new Data();
3859
3860
3861
3862//  Implementation Summary
3863//
3864//  1. Enforce API surface and semantic compatibility with 1.9.x branch
3865//  2. Improve the module's maintainability by reducing the storage
3866//    paths to a single mechanism.
3867//  3. Use the same single mechanism to support "private" and "user" data.
3868//  4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3869//  5. Avoid exposing implementation details on user objects (eg. expando properties)
3870//  6. Provide a clear path for implementation upgrade to WeakMap in 2014
3871
3872var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3873  rmultiDash = /[A-Z]/g;
3874
3875function dataAttr( elem, key, data ) {
3876  var name;
3877
3878  // If nothing was found internally, try to fetch any
3879  // data from the HTML5 data-* attribute
3880  if ( data === undefined && elem.nodeType === 1 ) {
3881    name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
3882    data = elem.getAttribute( name );
3883
3884    if ( typeof data === "string" ) {
3885      try {
3886        data = data === "true" ? true :
3887          data === "false" ? false :
3888          data === "null" ? null :
3889
3890          // Only convert to a number if it doesn't change the string
3891          +data + "" === data ? +data :
3892          rbrace.test( data ) ? jQuery.parseJSON( data ) :
3893          data;
3894      } catch ( e ) {}
3895
3896      // Make sure we set the data so it isn't changed later
3897      dataUser.set( elem, key, data );
3898    } else {
3899      data = undefined;
3900    }
3901  }
3902  return data;
3903}
3904
3905jQuery.extend( {
3906  hasData: function( elem ) {
3907    return dataUser.hasData( elem ) || dataPriv.hasData( elem );
3908  },
3909
3910  data: function( elem, name, data ) {
3911    return dataUser.access( elem, name, data );
3912  },
3913
3914  removeData: function( elem, name ) {
3915    dataUser.remove( elem, name );
3916  },
3917
3918  // TODO: Now that all calls to _data and _removeData have been replaced
3919  // with direct calls to dataPriv methods, these can be deprecated.
3920  _data: function( elem, name, data ) {
3921    return dataPriv.access( elem, name, data );
3922  },
3923
3924  _removeData: function( elem, name ) {
3925    dataPriv.remove( elem, name );
3926  }
3927} );
3928
3929jQuery.fn.extend( {
3930  data: function( key, value ) {
3931    var i, name, data,
3932      elem = this[ 0 ],
3933      attrs = elem && elem.attributes;
3934
3935    // Gets all values
3936    if ( key === undefined ) {
3937      if ( this.length ) {
3938        data = dataUser.get( elem );
3939
3940        if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
3941          i = attrs.length;
3942          while ( i-- ) {
3943
3944            // Support: IE11+
3945            // The attrs elements can be null (#14894)
3946            if ( attrs[ i ] ) {
3947              name = attrs[ i ].name;
3948              if ( name.indexOf( "data-" ) === 0 ) {
3949                name = jQuery.camelCase( name.slice( 5 ) );
3950                dataAttr( elem, name, data[ name ] );
3951              }
3952            }
3953          }
3954          dataPriv.set( elem, "hasDataAttrs", true );
3955        }
3956      }
3957
3958      return data;
3959    }
3960
3961    // Sets multiple values
3962    if ( typeof key === "object" ) {
3963      return this.each( function() {
3964        dataUser.set( this, key );
3965      } );
3966    }
3967
3968    return access( this, function( value ) {
3969      var data, camelKey;
3970
3971      // The calling jQuery object (element matches) is not empty
3972      // (and therefore has an element appears at this[ 0 ]) and the
3973      // `value` parameter was not undefined. An empty jQuery object
3974      // will result in `undefined` for elem = this[ 0 ] which will
3975      // throw an exception if an attempt to read a data cache is made.
3976      if ( elem && value === undefined ) {
3977
3978        // Attempt to get data from the cache
3979        // with the key as-is
3980        data = dataUser.get( elem, key ) ||
3981
3982          // Try to find dashed key if it exists (gh-2779)
3983          // This is for 2.2.x only
3984          dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
3985
3986        if ( data !== undefined ) {
3987          return data;
3988        }
3989
3990        camelKey = jQuery.camelCase( key );
3991
3992        // Attempt to get data from the cache
3993        // with the key camelized
3994        data = dataUser.get( elem, camelKey );
3995        if ( data !== undefined ) {
3996          return data;
3997        }
3998
3999        // Attempt to "discover" the data in
4000        // HTML5 custom data-* attrs
4001        data = dataAttr( elem, camelKey, undefined );
4002        if ( data !== undefined ) {
4003          return data;
4004        }
4005
4006        // We tried really hard, but the data doesn't exist.
4007        return;
4008      }
4009
4010      // Set the data...
4011      camelKey = jQuery.camelCase( key );
4012      this.each( function() {
4013
4014        // First, attempt to store a copy or reference of any
4015        // data that might've been store with a camelCased key.
4016        var data = dataUser.get( this, camelKey );
4017
4018        // For HTML5 data-* attribute interop, we have to
4019        // store property names with dashes in a camelCase form.
4020        // This might not apply to all properties...*
4021        dataUser.set( this, camelKey, value );
4022
4023        // *... In the case of properties that might _actually_
4024        // have dashes, we need to also store a copy of that
4025        // unchanged property.
4026        if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
4027          dataUser.set( this, key, value );
4028        }
4029      } );
4030    }, null, value, arguments.length > 1, null, true );
4031  },
4032
4033  removeData: function( key ) {
4034    return this.each( function() {
4035      dataUser.remove( this, key );
4036    } );
4037  }
4038} );
4039
4040
4041jQuery.extend( {
4042  queue: function( elem, type, data ) {
4043    var queue;
4044
4045    if ( elem ) {
4046      type = ( type || "fx" ) + "queue";
4047      queue = dataPriv.get( elem, type );
4048
4049      // Speed up dequeue by getting out quickly if this is just a lookup
4050      if ( data ) {
4051        if ( !queue || jQuery.isArray( data ) ) {
4052          queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4053        } else {
4054          queue.push( data );
4055        }
4056      }
4057      return queue || [];
4058    }
4059  },
4060
4061  dequeue: function( elem, type ) {
4062    type = type || "fx";
4063
4064    var queue = jQuery.queue( elem, type ),
4065      startLength = queue.length,
4066      fn = queue.shift(),
4067      hooks = jQuery._queueHooks( elem, type ),
4068      next = function() {
4069        jQuery.dequeue( elem, type );
4070      };
4071
4072    // If the fx queue is dequeued, always remove the progress sentinel
4073    if ( fn === "inprogress" ) {
4074      fn = queue.shift();
4075      startLength--;
4076    }
4077
4078    if ( fn ) {
4079
4080      // Add a progress sentinel to prevent the fx queue from being
4081      // automatically dequeued
4082      if ( type === "fx" ) {
4083        queue.unshift( "inprogress" );
4084      }
4085
4086      // Clear up the last queue stop function
4087      delete hooks.stop;
4088      fn.call( elem, next, hooks );
4089    }
4090
4091    if ( !startLength && hooks ) {
4092      hooks.empty.fire();
4093    }
4094  },
4095
4096  // Not public - generate a queueHooks object, or return the current one
4097  _queueHooks: function( elem, type ) {
4098    var key = type + "queueHooks";
4099    return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4100      empty: jQuery.Callbacks( "once memory" ).add( function() {
4101        dataPriv.remove( elem, [ type + "queue", key ] );
4102      } )
4103    } );
4104  }
4105} );
4106
4107jQuery.fn.extend( {
4108  queue: function( type, data ) {
4109    var setter = 2;
4110
4111    if ( typeof type !== "string" ) {
4112      data = type;
4113      type = "fx";
4114      setter--;
4115    }
4116
4117    if ( arguments.length < setter ) {
4118      return jQuery.queue( this[ 0 ], type );
4119    }
4120
4121    return data === undefined ?
4122      this :
4123      this.each( function() {
4124        var queue = jQuery.queue( this, type, data );
4125
4126        // Ensure a hooks for this queue
4127        jQuery._queueHooks( this, type );
4128
4129        if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4130          jQuery.dequeue( this, type );
4131        }
4132      } );
4133  },
4134  dequeue: function( type ) {
4135    return this.each( function() {
4136      jQuery.dequeue( this, type );
4137    } );
4138  },
4139  clearQueue: function( type ) {
4140    return this.queue( type || "fx", [] );
4141  },
4142
4143  // Get a promise resolved when queues of a certain type
4144  // are emptied (fx is the type by default)
4145  promise: function( type, obj ) {
4146    var tmp,
4147      count = 1,
4148      defer = jQuery.Deferred(),
4149      elements = this,
4150      i = this.length,
4151      resolve = function() {
4152        if ( !( --count ) ) {
4153          defer.resolveWith( elements, [ elements ] );
4154        }
4155      };
4156
4157    if ( typeof type !== "string" ) {
4158      obj = type;
4159      type = undefined;
4160    }
4161    type = type || "fx";
4162
4163    while ( i-- ) {
4164      tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4165      if ( tmp && tmp.empty ) {
4166        count++;
4167        tmp.empty.add( resolve );
4168      }
4169    }
4170    resolve();
4171    return defer.promise( obj );
4172  }
4173} );
4174var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4175
4176var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4177
4178
4179var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4180
4181var isHidden = function( elem, el ) {
4182
4183    // isHidden might be called from jQuery#filter function;
4184    // in that case, element will be second argument
4185    elem = el || elem;
4186    return jQuery.css( elem, "display" ) === "none" ||
4187      !jQuery.contains( elem.ownerDocument, elem );
4188  };
4189
4190
4191
4192function adjustCSS( elem, prop, valueParts, tween ) {
4193  var adjusted,
4194    scale = 1,
4195    maxIterations = 20,
4196    currentValue = tween ?
4197      function() { return tween.cur(); } :
4198      function() { return jQuery.css( elem, prop, "" ); },
4199    initial = currentValue(),
4200    unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4201
4202    // Starting value computation is required for potential unit mismatches
4203    initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4204      rcssNum.exec( jQuery.css( elem, prop ) );
4205
4206  if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4207
4208    // Trust units reported by jQuery.css
4209    unit = unit || initialInUnit[ 3 ];
4210
4211    // Make sure we update the tween properties later on
4212    valueParts = valueParts || [];
4213
4214    // Iteratively approximate from a nonzero starting point
4215    initialInUnit = +initial || 1;
4216
4217    do {
4218
4219      // If previous iteration zeroed out, double until we get *something*.
4220      // Use string for doubling so we don't accidentally see scale as unchanged below
4221      scale = scale || ".5";
4222
4223      // Adjust and apply
4224      initialInUnit = initialInUnit / scale;
4225      jQuery.style( elem, prop, initialInUnit + unit );
4226
4227    // Update scale, tolerating zero or NaN from tween.cur()
4228    // Break the loop if scale is unchanged or perfect, or if we've just had enough.
4229    } while (
4230      scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4231    );
4232  }
4233
4234  if ( valueParts ) {
4235    initialInUnit = +initialInUnit || +initial || 0;
4236
4237    // Apply relative offset (+=/-=) if specified
4238    adjusted = valueParts[ 1 ] ?
4239      initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4240      +valueParts[ 2 ];
4241    if ( tween ) {
4242      tween.unit = unit;
4243      tween.start = initialInUnit;
4244      tween.end = adjusted;
4245    }
4246  }
4247  return adjusted;
4248}
4249var rcheckableType = ( /^(?:checkbox|radio)$/i );
4250
4251var rtagName = ( /<([\w:-]+)/ );
4252
4253var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4254
4255
4256
4257// We have to close these tags to support XHTML (#13200)
4258var wrapMap = {
4259
4260  // Support: IE9
4261  option: [ 1, "<select multiple='multiple'>", "</select>" ],
4262
4263  // XHTML parsers do not magically insert elements in the
4264  // same way that tag soup parsers do. So we cannot shorten
4265  // this by omitting <tbody> or other required elements.
4266  thead: [ 1, "<table>", "</table>" ],
4267  col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4268  tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4269  td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4270
4271  _default: [ 0, "", "" ]
4272};
4273
4274// Support: IE9
4275wrapMap.optgroup = wrapMap.option;
4276
4277wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4278wrapMap.th = wrapMap.td;
4279
4280
4281function getAll( context, tag ) {
4282
4283  // Support: IE9-11+
4284  // Use typeof to avoid zero-argument method invocation on host objects (#15151)
4285  var ret = typeof context.getElementsByTagName !== "undefined" ?
4286      context.getElementsByTagName( tag || "*" ) :
4287      typeof context.querySelectorAll !== "undefined" ?
4288        context.querySelectorAll( tag || "*" ) :
4289      [];
4290
4291  return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4292    jQuery.merge( [ context ], ret ) :
4293    ret;
4294}
4295
4296
4297// Mark scripts as having already been evaluated
4298function setGlobalEval( elems, refElements ) {
4299  var i = 0,
4300    l = elems.length;
4301
4302  for ( ; i < l; i++ ) {
4303    dataPriv.set(
4304      elems[ i ],
4305      "globalEval",
4306      !refElements || dataPriv.get( refElements[ i ], "globalEval" )
4307    );
4308  }
4309}
4310
4311
4312var rhtml = /<|&#?\w+;/;
4313
4314function buildFragment( elems, context, scripts, selection, ignored ) {
4315  var elem, tmp, tag, wrap, contains, j,
4316    fragment = context.createDocumentFragment(),
4317    nodes = [],
4318    i = 0,
4319    l = elems.length;
4320
4321  for ( ; i < l; i++ ) {
4322    elem = elems[ i ];
4323
4324    if ( elem || elem === 0 ) {
4325
4326      // Add nodes directly
4327      if ( jQuery.type( elem ) === "object" ) {
4328
4329        // Support: Android<4.1, PhantomJS<2
4330        // push.apply(_, arraylike) throws on ancient WebKit
4331        jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4332
4333      // Convert non-html into a text node
4334      } else if ( !rhtml.test( elem ) ) {
4335        nodes.push( context.createTextNode( elem ) );
4336
4337      // Convert html into DOM nodes
4338      } else {
4339        tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4340
4341        // Deserialize a standard representation
4342        tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4343        wrap = wrapMap[ tag ] || wrapMap._default;
4344        tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4345
4346        // Descend through wrappers to the right content
4347        j = wrap[ 0 ];
4348        while ( j-- ) {
4349          tmp = tmp.lastChild;
4350        }
4351
vendor: 1,722 bytes, lines 4352-4419
4352        // Support: Android<4.1, PhantomJS<2
4353        // push.apply(_, arraylike) throws on ancient WebKit
4354        jQuery.merge( nodes, tmp.childNodes );
4355
4356        // Remember the top-level container
4357        tmp = fragment.firstChild;
4358
4359        // Ensure the created nodes are orphaned (#12392)
4360        tmp.textContent = "";
4361      }
4362    }
4363  }
4364
4365  // Remove wrapper from fragment
4366  fragment.textContent = "";
4367
4368  i = 0;
4369  while ( ( elem = nodes[ i++ ] ) ) {
4370
4371    // Skip elements already in the context collection (trac-4087)
4372    if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4373      if ( ignored ) {
4374        ignored.push( elem );
4375      }
4376      continue;
4377    }
4378
4379    contains = jQuery.contains( elem.ownerDocument, elem );
4380
4381    // Append to fragment
4382    tmp = getAll( fragment.appendChild( elem ), "script" );
4383
4384    // Preserve script evaluation history
4385    if ( contains ) {
4386      setGlobalEval( tmp );
4387    }
4388
4389    // Capture executables
4390    if ( scripts ) {
4391      j = 0;
4392      while ( ( elem = tmp[ j++ ] ) ) {
4393        if ( rscriptType.test( elem.type || "" ) ) {
4394          scripts.push( elem );
4395        }
4396      }
4397    }
4398  }
4399
4400  return fragment;
4401}
4402
4403
4404( function() {
4405  var fragment = document.createDocumentFragment(),
4406    div = fragment.appendChild( document.createElement( "div" ) ),
4407    input = document.createElement( "input" );
4408
4409  // Support: Android 4.0-4.3, Safari<=5.1
4410  // Check state lost if the name is set (#11217)
4411  // Support: Windows Web Apps (WWA)
4412  // `name` and `type` must use .setAttribute for WWA (#14901)
4413  input.setAttribute( "type", "radio" );
4414  input.setAttribute( "checked", "checked" );
4415  input.setAttribute( "name", "t" );
4416
4417  div.appendChild( input );
4418
4419  // Support: Safari<=5.1, Android<4.2
vendor: 28,749 bytes, lines 4420-5394
4420  // Older WebKit doesn't clone checked state correctly in fragments
4421  support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4422
4423  // Support: IE<=11+
4424  // Make sure textarea (and checkbox) defaultValue is properly cloned
4425  div.innerHTML = "<textarea>x</textarea>";
4426  support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4427} )();
4428
4429
4430var
4431  rkeyEvent = /^key/,
4432  rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4433  rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4434
4435function returnTrue() {
4436  return true;
4437}
4438
4439function returnFalse() {
4440  return false;
4441}
4442
4443// Support: IE9
4444// See #13393 for more info
4445function safeActiveElement() {
4446  try {
4447    return document.activeElement;
4448  } catch ( err ) { }
4449}
4450
4451function on( elem, types, selector, data, fn, one ) {
4452  var origFn, type;
4453
4454  // Types can be a map of types/handlers
4455  if ( typeof types === "object" ) {
4456
4457    // ( types-Object, selector, data )
4458    if ( typeof selector !== "string" ) {
4459
4460      // ( types-Object, data )
4461      data = data || selector;
4462      selector = undefined;
4463    }
4464    for ( type in types ) {
4465      on( elem, type, selector, data, types[ type ], one );
4466    }
4467    return elem;
4468  }
4469
4470  if ( data == null && fn == null ) {
4471
4472    // ( types, fn )
4473    fn = selector;
4474    data = selector = undefined;
4475  } else if ( fn == null ) {
4476    if ( typeof selector === "string" ) {
4477
4478      // ( types, selector, fn )
4479      fn = data;
4480      data = undefined;
4481    } else {
4482
4483      // ( types, data, fn )
4484      fn = data;
4485      data = selector;
4486      selector = undefined;
4487    }
4488  }
4489  if ( fn === false ) {
4490    fn = returnFalse;
4491  } else if ( !fn ) {
4492    return elem;
4493  }
4494
4495  if ( one === 1 ) {
4496    origFn = fn;
4497    fn = function( event ) {
4498
4499      // Can use an empty set, since event contains the info
4500      jQuery().off( event );
4501      return origFn.apply( this, arguments );
4502    };
4503
4504    // Use same guid so caller can remove using origFn
4505    fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4506  }
4507  return elem.each( function() {
4508    jQuery.event.add( this, types, fn, data, selector );
4509  } );
4510}
4511
4512/*
4513 * Helper functions for managing events -- not part of the public interface.
4514 * Props to Dean Edwards' addEvent library for many of the ideas.
4515 */
4516jQuery.event = {
4517
4518  global: {},
4519
4520  add: function( elem, types, handler, data, selector ) {
4521
4522    var handleObjIn, eventHandle, tmp,
4523      events, t, handleObj,
4524      special, handlers, type, namespaces, origType,
4525      elemData = dataPriv.get( elem );
4526
4527    // Don't attach events to noData or text/comment nodes (but allow plain objects)
4528    if ( !elemData ) {
4529      return;
4530    }
4531
4532    // Caller can pass in an object of custom data in lieu of the handler
4533    if ( handler.handler ) {
4534      handleObjIn = handler;
4535      handler = handleObjIn.handler;
4536      selector = handleObjIn.selector;
4537    }
4538
4539    // Make sure that the handler has a unique ID, used to find/remove it later
4540    if ( !handler.guid ) {
4541      handler.guid = jQuery.guid++;
4542    }
4543
4544    // Init the element's event structure and main handler, if this is the first
4545    if ( !( events = elemData.events ) ) {
4546      events = elemData.events = {};
4547    }
4548    if ( !( eventHandle = elemData.handle ) ) {
4549      eventHandle = elemData.handle = function( e ) {
4550
4551        // Discard the second event of a jQuery.event.trigger() and
4552        // when an event is called after a page has unloaded
4553        return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4554          jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4555      };
4556    }
4557
4558    // Handle multiple events separated by a space
4559    types = ( types || "" ).match( rnotwhite ) || [ "" ];
4560    t = types.length;
4561    while ( t-- ) {
4562      tmp = rtypenamespace.exec( types[ t ] ) || [];
4563      type = origType = tmp[ 1 ];
4564      namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4565
4566      // There *must* be a type, no attaching namespace-only handlers
4567      if ( !type ) {
4568        continue;
4569      }
4570
4571      // If event changes its type, use the special event handlers for the changed type
4572      special = jQuery.event.special[ type ] || {};
4573
4574      // If selector defined, determine special event api type, otherwise given type
4575      type = ( selector ? special.delegateType : special.bindType ) || type;
4576
4577      // Update special based on newly reset type
4578      special = jQuery.event.special[ type ] || {};
4579
4580      // handleObj is passed to all event handlers
4581      handleObj = jQuery.extend( {
4582        type: type,
4583        origType: origType,
4584        data: data,
4585        handler: handler,
4586        guid: handler.guid,
4587        selector: selector,
4588        needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4589        namespace: namespaces.join( "." )
4590      }, handleObjIn );
4591
4592      // Init the event handler queue if we're the first
4593      if ( !( handlers = events[ type ] ) ) {
4594        handlers = events[ type ] = [];
4595        handlers.delegateCount = 0;
4596
4597        // Only use addEventListener if the special events handler returns false
4598        if ( !special.setup ||
4599          special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4600
4601          if ( elem.addEventListener ) {
4602            elem.addEventListener( type, eventHandle );
4603          }
4604        }
4605      }
4606
4607      if ( special.add ) {
4608        special.add.call( elem, handleObj );
4609
4610        if ( !handleObj.handler.guid ) {
4611          handleObj.handler.guid = handler.guid;
4612        }
4613      }
4614
4615      // Add to the element's handler list, delegates in front
4616      if ( selector ) {
4617        handlers.splice( handlers.delegateCount++, 0, handleObj );
4618      } else {
4619        handlers.push( handleObj );
4620      }
4621
4622      // Keep track of which events have ever been used, for event optimization
4623      jQuery.event.global[ type ] = true;
4624    }
4625
4626  },
4627
4628  // Detach an event or set of events from an element
4629  remove: function( elem, types, handler, selector, mappedTypes ) {
4630
4631    var j, origCount, tmp,
4632      events, t, handleObj,
4633      special, handlers, type, namespaces, origType,
4634      elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
4635
4636    if ( !elemData || !( events = elemData.events ) ) {
4637      return;
4638    }
4639
4640    // Once for each type.namespace in types; type may be omitted
4641    types = ( types || "" ).match( rnotwhite ) || [ "" ];
4642    t = types.length;
4643    while ( t-- ) {
4644      tmp = rtypenamespace.exec( types[ t ] ) || [];
4645      type = origType = tmp[ 1 ];
4646      namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4647
4648      // Unbind all events (on this namespace, if provided) for the element
4649      if ( !type ) {
4650        for ( type in events ) {
4651          jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4652        }
4653        continue;
4654      }
4655
4656      special = jQuery.event.special[ type ] || {};
4657      type = ( selector ? special.delegateType : special.bindType ) || type;
4658      handlers = events[ type ] || [];
4659      tmp = tmp[ 2 ] &&
4660        new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4661
4662      // Remove matching events
4663      origCount = j = handlers.length;
4664      while ( j-- ) {
4665        handleObj = handlers[ j ];
4666
4667        if ( ( mappedTypes || origType === handleObj.origType ) &&
4668          ( !handler || handler.guid === handleObj.guid ) &&
4669          ( !tmp || tmp.test( handleObj.namespace ) ) &&
4670          ( !selector || selector === handleObj.selector ||
4671            selector === "**" && handleObj.selector ) ) {
4672          handlers.splice( j, 1 );
4673
4674          if ( handleObj.selector ) {
4675            handlers.delegateCount--;
4676          }
4677          if ( special.remove ) {
4678            special.remove.call( elem, handleObj );
4679          }
4680        }
4681      }
4682
4683      // Remove generic event handler if we removed something and no more handlers exist
4684      // (avoids potential for endless recursion during removal of special event handlers)
4685      if ( origCount && !handlers.length ) {
4686        if ( !special.teardown ||
4687          special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4688
4689          jQuery.removeEvent( elem, type, elemData.handle );
4690        }
4691
4692        delete events[ type ];
4693      }
4694    }
4695
4696    // Remove data and the expando if it's no longer used
4697    if ( jQuery.isEmptyObject( events ) ) {
4698      dataPriv.remove( elem, "handle events" );
4699    }
4700  },
4701
4702  dispatch: function( event ) {
4703
4704    // Make a writable jQuery.Event from the native event object
4705    event = jQuery.event.fix( event );
4706
4707    var i, j, ret, matched, handleObj,
4708      handlerQueue = [],
4709      args = slice.call( arguments ),
4710      handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
4711      special = jQuery.event.special[ event.type ] || {};
4712
4713    // Use the fix-ed jQuery.Event rather than the (read-only) native event
4714    args[ 0 ] = event;
4715    event.delegateTarget = this;
4716
4717    // Call the preDispatch hook for the mapped type, and let it bail if desired
4718    if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4719      return;
4720    }
4721
4722    // Determine handlers
4723    handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4724
4725    // Run delegates first; they may want to stop propagation beneath us
4726    i = 0;
4727    while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
4728      event.currentTarget = matched.elem;
4729
4730      j = 0;
4731      while ( ( handleObj = matched.handlers[ j++ ] ) &&
4732        !event.isImmediatePropagationStopped() ) {
4733
4734        // Triggered event must either 1) have no namespace, or 2) have namespace(s)
4735        // a subset or equal to those in the bound event (both can have no namespace).
4736        if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
4737
4738          event.handleObj = handleObj;
4739          event.data = handleObj.data;
4740
4741          ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
4742            handleObj.handler ).apply( matched.elem, args );
4743
4744          if ( ret !== undefined ) {
4745            if ( ( event.result = ret ) === false ) {
4746              event.preventDefault();
4747              event.stopPropagation();
4748            }
4749          }
4750        }
4751      }
4752    }
4753
4754    // Call the postDispatch hook for the mapped type
4755    if ( special.postDispatch ) {
4756      special.postDispatch.call( this, event );
4757    }
4758
4759    return event.result;
4760  },
4761
4762  handlers: function( event, handlers ) {
4763    var i, matches, sel, handleObj,
4764      handlerQueue = [],
4765      delegateCount = handlers.delegateCount,
4766      cur = event.target;
4767
4768    // Support (at least): Chrome, IE9
4769    // Find delegate handlers
4770    // Black-hole SVG <use> instance trees (#13180)
4771    //
4772    // Support: Firefox<=42+
4773    // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
4774    if ( delegateCount && cur.nodeType &&
4775      ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
4776
4777      for ( ; cur !== this; cur = cur.parentNode || this ) {
4778
4779        // Don't check non-elements (#13208)
4780        // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4781        if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
4782          matches = [];
4783          for ( i = 0; i < delegateCount; i++ ) {
4784            handleObj = handlers[ i ];
4785
4786            // Don't conflict with Object.prototype properties (#13203)
4787            sel = handleObj.selector + " ";
4788
4789            if ( matches[ sel ] === undefined ) {
4790              matches[ sel ] = handleObj.needsContext ?
4791                jQuery( sel, this ).index( cur ) > -1 :
4792                jQuery.find( sel, this, null, [ cur ] ).length;
4793            }
4794            if ( matches[ sel ] ) {
4795              matches.push( handleObj );
4796            }
4797          }
4798          if ( matches.length ) {
4799            handlerQueue.push( { elem: cur, handlers: matches } );
4800          }
4801        }
4802      }
4803    }
4804
4805    // Add the remaining (directly-bound) handlers
4806    if ( delegateCount < handlers.length ) {
4807      handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
4808    }
4809
4810    return handlerQueue;
4811  },
4812
4813  // Includes some event props shared by KeyEvent and MouseEvent
4814  props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
4815    "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
4816
4817  fixHooks: {},
4818
4819  keyHooks: {
4820    props: "char charCode key keyCode".split( " " ),
4821    filter: function( event, original ) {
4822
4823      // Add which for key events
4824      if ( event.which == null ) {
4825        event.which = original.charCode != null ? original.charCode : original.keyCode;
4826      }
4827
4828      return event;
4829    }
4830  },
4831
4832  mouseHooks: {
4833    props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
4834      "screenX screenY toElement" ).split( " " ),
4835    filter: function( event, original ) {
4836      var eventDoc, doc, body,
4837        button = original.button;
4838
4839      // Calculate pageX/Y if missing and clientX/Y available
4840      if ( event.pageX == null && original.clientX != null ) {
4841        eventDoc = event.target.ownerDocument || document;
4842        doc = eventDoc.documentElement;
4843        body = eventDoc.body;
4844
4845        event.pageX = original.clientX +
4846          ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
4847          ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4848        event.pageY = original.clientY +
4849          ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
4850          ( doc && doc.clientTop  || body && body.clientTop  || 0 );
4851      }
4852
4853      // Add which for click: 1 === left; 2 === middle; 3 === right
4854      // Note: button is not normalized, so don't use it
4855      if ( !event.which && button !== undefined ) {
4856        event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4857      }
4858
4859      return event;
4860    }
4861  },
4862
4863  fix: function( event ) {
4864    if ( event[ jQuery.expando ] ) {
4865      return event;
4866    }
4867
4868    // Create a writable copy of the event object and normalize some properties
4869    var i, prop, copy,
4870      type = event.type,
4871      originalEvent = event,
4872      fixHook = this.fixHooks[ type ];
4873
4874    if ( !fixHook ) {
4875      this.fixHooks[ type ] = fixHook =
4876        rmouseEvent.test( type ) ? this.mouseHooks :
4877        rkeyEvent.test( type ) ? this.keyHooks :
4878        {};
4879    }
4880    copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4881
4882    event = new jQuery.Event( originalEvent );
4883
4884    i = copy.length;
4885    while ( i-- ) {
4886      prop = copy[ i ];
4887      event[ prop ] = originalEvent[ prop ];
4888    }
4889
4890    // Support: Cordova 2.5 (WebKit) (#13255)
4891    // All events should have a target; Cordova deviceready doesn't
4892    if ( !event.target ) {
4893      event.target = document;
4894    }
4895
4896    // Support: Safari 6.0+, Chrome<28
4897    // Target should not be a text node (#504, #13143)
4898    if ( event.target.nodeType === 3 ) {
4899      event.target = event.target.parentNode;
4900    }
4901
4902    return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4903  },
4904
4905  special: {
4906    load: {
4907
4908      // Prevent triggered image.load events from bubbling to window.load
4909      noBubble: true
4910    },
4911    focus: {
4912
4913      // Fire native event if possible so blur/focus sequence is correct
4914      trigger: function() {
4915        if ( this !== safeActiveElement() && this.focus ) {
4916          this.focus();
4917          return false;
4918        }
4919      },
4920      delegateType: "focusin"
4921    },
4922    blur: {
4923      trigger: function() {
4924        if ( this === safeActiveElement() && this.blur ) {
4925          this.blur();
4926          return false;
4927        }
4928      },
4929      delegateType: "focusout"
4930    },
4931    click: {
4932
4933      // For checkbox, fire native event so checked state will be right
4934      trigger: function() {
4935        if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4936          this.click();
4937          return false;
4938        }
4939      },
4940
4941      // For cross-browser consistency, don't fire native .click() on links
4942      _default: function( event ) {
4943        return jQuery.nodeName( event.target, "a" );
4944      }
4945    },
4946
4947    beforeunload: {
4948      postDispatch: function( event ) {
4949
4950        // Support: Firefox 20+
4951        // Firefox doesn't alert if the returnValue field is not set.
4952        if ( event.result !== undefined && event.originalEvent ) {
4953          event.originalEvent.returnValue = event.result;
4954        }
4955      }
4956    }
4957  }
4958};
4959
4960jQuery.removeEvent = function( elem, type, handle ) {
4961
4962  // This "if" is needed for plain objects
4963  if ( elem.removeEventListener ) {
4964    elem.removeEventListener( type, handle );
4965  }
4966};
4967
4968jQuery.Event = function( src, props ) {
4969
4970  // Allow instantiation without the 'new' keyword
4971  if ( !( this instanceof jQuery.Event ) ) {
4972    return new jQuery.Event( src, props );
4973  }
4974
4975  // Event object
4976  if ( src && src.type ) {
4977    this.originalEvent = src;
4978    this.type = src.type;
4979
4980    // Events bubbling up the document may have been marked as prevented
4981    // by a handler lower down the tree; reflect the correct value.
4982    this.isDefaultPrevented = src.defaultPrevented ||
4983        src.defaultPrevented === undefined &&
4984
4985        // Support: Android<4.0
4986        src.returnValue === false ?
4987      returnTrue :
4988      returnFalse;
4989
4990  // Event type
4991  } else {
4992    this.type = src;
4993  }
4994
4995  // Put explicitly provided properties onto the event object
4996  if ( props ) {
4997    jQuery.extend( this, props );
4998  }
4999
5000  // Create a timestamp if incoming event doesn't have one
5001  this.timeStamp = src && src.timeStamp || jQuery.now();
5002
5003  // Mark it as fixed
5004  this[ jQuery.expando ] = true;
5005};
5006
5007// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5008// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5009jQuery.Event.prototype = {
5010  constructor: jQuery.Event,
5011  isDefaultPrevented: returnFalse,
5012  isPropagationStopped: returnFalse,
5013  isImmediatePropagationStopped: returnFalse,
5014  isSimulated: false,
5015
5016  preventDefault: function() {
5017    var e = this.originalEvent;
5018
5019    this.isDefaultPrevented = returnTrue;
5020
5021    if ( e && !this.isSimulated ) {
5022      e.preventDefault();
5023    }
5024  },
5025  stopPropagation: function() {
5026    var e = this.originalEvent;
5027
5028    this.isPropagationStopped = returnTrue;
5029
5030    if ( e && !this.isSimulated ) {
5031      e.stopPropagation();
5032    }
5033  },
5034  stopImmediatePropagation: function() {
5035    var e = this.originalEvent;
5036
5037    this.isImmediatePropagationStopped = returnTrue;
5038
5039    if ( e && !this.isSimulated ) {
5040      e.stopImmediatePropagation();
5041    }
5042
5043    this.stopPropagation();
5044  }
5045};
5046
5047// Create mouseenter/leave events using mouseover/out and event-time checks
5048// so that event delegation works in jQuery.
5049// Do the same for pointerenter/pointerleave and pointerover/pointerout
5050//
5051// Support: Safari 7 only
5052// Safari sends mouseenter too often; see:
5053// https://code.google.com/p/chromium/issues/detail?id=470258
5054// for the description of the bug (it existed in older Chrome versions as well).
5055jQuery.each( {
5056  mouseenter: "mouseover",
5057  mouseleave: "mouseout",
5058  pointerenter: "pointerover",
5059  pointerleave: "pointerout"
5060}, function( orig, fix ) {
5061  jQuery.event.special[ orig ] = {
5062    delegateType: fix,
5063    bindType: fix,
5064
5065    handle: function( event ) {
5066      var ret,
5067        target = this,
5068        related = event.relatedTarget,
5069        handleObj = event.handleObj;
5070
5071      // For mouseenter/leave call the handler if related is outside the target.
5072      // NB: No relatedTarget if the mouse left/entered the browser window
5073      if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5074        event.type = handleObj.origType;
5075        ret = handleObj.handler.apply( this, arguments );
5076        event.type = fix;
5077      }
5078      return ret;
5079    }
5080  };
5081} );
5082
5083jQuery.fn.extend( {
5084  on: function( types, selector, data, fn ) {
5085    return on( this, types, selector, data, fn );
5086  },
5087  one: function( types, selector, data, fn ) {
5088    return on( this, types, selector, data, fn, 1 );
5089  },
5090  off: function( types, selector, fn ) {
5091    var handleObj, type;
5092    if ( types && types.preventDefault && types.handleObj ) {
5093
5094      // ( event )  dispatched jQuery.Event
5095      handleObj = types.handleObj;
5096      jQuery( types.delegateTarget ).off(
5097        handleObj.namespace ?
5098          handleObj.origType + "." + handleObj.namespace :
5099          handleObj.origType,
5100        handleObj.selector,
5101        handleObj.handler
5102      );
5103      return this;
5104    }
5105    if ( typeof types === "object" ) {
5106
5107      // ( types-object [, selector] )
5108      for ( type in types ) {
5109        this.off( type, selector, types[ type ] );
5110      }
5111      return this;
5112    }
5113    if ( selector === false || typeof selector === "function" ) {
5114
5115      // ( types [, fn] )
5116      fn = selector;
5117      selector = undefined;
5118    }
5119    if ( fn === false ) {
5120      fn = returnFalse;
5121    }
5122    return this.each( function() {
5123      jQuery.event.remove( this, types, fn, selector );
5124    } );
5125  }
5126} );
5127
5128
5129var
5130  rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5131
5132  // Support: IE 10-11, Edge 10240+
5133  // In IE/Edge using regex groups here causes severe slowdowns.
5134  // See https://connect.microsoft.com/IE/feedback/details/1736512/
5135  rnoInnerhtml = /<script|<style|<link/i,
5136
5137  // checked="checked" or checked
5138  rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5139  rscriptTypeMasked = /^true\/(.*)/,
5140  rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5141
5142// Manipulating tables requires a tbody
5143function manipulationTarget( elem, content ) {
5144  return jQuery.nodeName( elem, "table" ) &&
5145    jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5146
5147    elem.getElementsByTagName( "tbody" )[ 0 ] ||
5148      elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5149    elem;
5150}
5151
5152// Replace/restore the type attribute of script elements for safe DOM manipulation
5153function disableScript( elem ) {
5154  elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5155  return elem;
5156}
5157function restoreScript( elem ) {
5158  var match = rscriptTypeMasked.exec( elem.type );
5159
5160  if ( match ) {
5161    elem.type = match[ 1 ];
5162  } else {
5163    elem.removeAttribute( "type" );
5164  }
5165
5166  return elem;
5167}
5168
5169function cloneCopyEvent( src, dest ) {
5170  var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5171
5172  if ( dest.nodeType !== 1 ) {
5173    return;
5174  }
5175
5176  // 1. Copy private data: events, handlers, etc.
5177  if ( dataPriv.hasData( src ) ) {
5178    pdataOld = dataPriv.access( src );
5179    pdataCur = dataPriv.set( dest, pdataOld );
5180    events = pdataOld.events;
5181
5182    if ( events ) {
5183      delete pdataCur.handle;
5184      pdataCur.events = {};
5185
5186      for ( type in events ) {
5187        for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5188          jQuery.event.add( dest, type, events[ type ][ i ] );
5189        }
5190      }
5191    }
5192  }
5193
5194  // 2. Copy user data
5195  if ( dataUser.hasData( src ) ) {
5196    udataOld = dataUser.access( src );
5197    udataCur = jQuery.extend( {}, udataOld );
5198
5199    dataUser.set( dest, udataCur );
5200  }
5201}
5202
5203// Fix IE bugs, see support tests
5204function fixInput( src, dest ) {
5205  var nodeName = dest.nodeName.toLowerCase();
5206
5207  // Fails to persist the checked state of a cloned checkbox or radio button.
5208  if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5209    dest.checked = src.checked;
5210
5211  // Fails to return the selected option to the default selected state when cloning options
5212  } else if ( nodeName === "input" || nodeName === "textarea" ) {
5213    dest.defaultValue = src.defaultValue;
5214  }
5215}
5216
5217function domManip( collection, args, callback, ignored ) {
5218
5219  // Flatten any nested arrays
5220  args = concat.apply( [], args );
5221
5222  var fragment, first, scripts, hasScripts, node, doc,
5223    i = 0,
5224    l = collection.length,
5225    iNoClone = l - 1,
5226    value = args[ 0 ],
5227    isFunction = jQuery.isFunction( value );
5228
5229  // We can't cloneNode fragments that contain checked, in WebKit
5230  if ( isFunction ||
5231      ( l > 1 && typeof value === "string" &&
5232        !support.checkClone && rchecked.test( value ) ) ) {
5233    return collection.each( function( index ) {
5234      var self = collection.eq( index );
5235      if ( isFunction ) {
5236        args[ 0 ] = value.call( this, index, self.html() );
5237      }
5238      domManip( self, args, callback, ignored );
5239    } );
5240  }
5241
5242  if ( l ) {
5243    fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5244    first = fragment.firstChild;
5245
5246    if ( fragment.childNodes.length === 1 ) {
5247      fragment = first;
5248    }
5249
5250    // Require either new content or an interest in ignored elements to invoke the callback
5251    if ( first || ignored ) {
5252      scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5253      hasScripts = scripts.length;
5254
5255      // Use the original fragment for the last item
5256      // instead of the first because it can end up
5257      // being emptied incorrectly in certain situations (#8070).
5258      for ( ; i < l; i++ ) {
5259        node = fragment;
5260
5261        if ( i !== iNoClone ) {
5262          node = jQuery.clone( node, true, true );
5263
5264          // Keep references to cloned scripts for later restoration
5265          if ( hasScripts ) {
5266
5267            // Support: Android<4.1, PhantomJS<2
5268            // push.apply(_, arraylike) throws on ancient WebKit
5269            jQuery.merge( scripts, getAll( node, "script" ) );
5270          }
5271        }
5272
5273        callback.call( collection[ i ], node, i );
5274      }
5275
5276      if ( hasScripts ) {
5277        doc = scripts[ scripts.length - 1 ].ownerDocument;
5278
5279        // Reenable scripts
5280        jQuery.map( scripts, restoreScript );
5281
5282        // Evaluate executable scripts on first document insertion
5283        for ( i = 0; i < hasScripts; i++ ) {
5284          node = scripts[ i ];
5285          if ( rscriptType.test( node.type || "" ) &&
5286            !dataPriv.access( node, "globalEval" ) &&
5287            jQuery.contains( doc, node ) ) {
5288
5289            if ( node.src ) {
5290
5291              // Optional AJAX dependency, but won't run scripts if not present
5292              if ( jQuery._evalUrl ) {
5293                jQuery._evalUrl( node.src );
5294              }
5295            } else {
5296              jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5297            }
5298          }
5299        }
5300      }
5301    }
5302  }
5303
5304  return collection;
5305}
5306
5307function remove( elem, selector, keepData ) {
5308  var node,
5309    nodes = selector ? jQuery.filter( selector, elem ) : elem,
5310    i = 0;
5311
5312  for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5313    if ( !keepData && node.nodeType === 1 ) {
5314      jQuery.cleanData( getAll( node ) );
5315    }
5316
5317    if ( node.parentNode ) {
5318      if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5319        setGlobalEval( getAll( node, "script" ) );
5320      }
5321      node.parentNode.removeChild( node );
5322    }
5323  }
5324
5325  return elem;
5326}
5327
5328jQuery.extend( {
5329  htmlPrefilter: function( html ) {
5330    return html.replace( rxhtmlTag, "<$1></$2>" );
5331  },
5332
5333  clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5334    var i, l, srcElements, destElements,
5335      clone = elem.cloneNode( true ),
5336      inPage = jQuery.contains( elem.ownerDocument, elem );
5337
5338    // Fix IE cloning issues
5339    if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5340        !jQuery.isXMLDoc( elem ) ) {
5341
5342      // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5343      destElements = getAll( clone );
5344      srcElements = getAll( elem );
5345
5346      for ( i = 0, l = srcElements.length; i < l; i++ ) {
5347        fixInput( srcElements[ i ], destElements[ i ] );
5348      }
5349    }
5350
5351    // Copy the events from the original to the clone
5352    if ( dataAndEvents ) {
5353      if ( deepDataAndEvents ) {
5354        srcElements = srcElements || getAll( elem );
5355        destElements = destElements || getAll( clone );
5356
5357        for ( i = 0, l = srcElements.length; i < l; i++ ) {
5358          cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5359        }
5360      } else {
5361        cloneCopyEvent( elem, clone );
5362      }
5363    }
5364
5365    // Preserve script evaluation history
5366    destElements = getAll( clone, "script" );
5367    if ( destElements.length > 0 ) {
5368      setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5369    }
5370
5371    // Return the cloned set
5372    return clone;
5373  },
5374
5375  cleanData: function( elems ) {
5376    var data, elem, type,
5377      special = jQuery.event.special,
5378      i = 0;
5379
5380    for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5381      if ( acceptData( elem ) ) {
5382        if ( ( data = elem[ dataPriv.expando ] ) ) {
5383          if ( data.events ) {
5384            for ( type in data.events ) {
5385              if ( special[ type ] ) {
5386                jQuery.event.remove( elem, type );
5387
5388              // This is a shortcut to avoid jQuery.event.remove's overhead
5389              } else {
5390                jQuery.removeEvent( elem, type, data.handle );
5391              }
5392            }
5393          }
5394
vendor: 4,214 bytes, lines 5395-5555
5395          // Support: Chrome <= 35-45+
5396          // Assign undefined instead of using delete, see Data#remove
5397          elem[ dataPriv.expando ] = undefined;
5398        }
5399        if ( elem[ dataUser.expando ] ) {
5400
5401          // Support: Chrome <= 35-45+
5402          // Assign undefined instead of using delete, see Data#remove
5403          elem[ dataUser.expando ] = undefined;
5404        }
5405      }
5406    }
5407  }
5408} );
5409
5410jQuery.fn.extend( {
5411
5412  // Keep domManip exposed until 3.0 (gh-2225)
5413  domManip: domManip,
5414
5415  detach: function( selector ) {
5416    return remove( this, selector, true );
5417  },
5418
5419  remove: function( selector ) {
5420    return remove( this, selector );
5421  },
5422
5423  text: function( value ) {
5424    return access( this, function( value ) {
5425      return value === undefined ?
5426        jQuery.text( this ) :
5427        this.empty().each( function() {
5428          if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5429            this.textContent = value;
5430          }
5431        } );
5432    }, null, value, arguments.length );
5433  },
5434
5435  append: function() {
5436    return domManip( this, arguments, function( elem ) {
5437      if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5438        var target = manipulationTarget( this, elem );
5439        target.appendChild( elem );
5440      }
5441    } );
5442  },
5443
5444  prepend: function() {
5445    return domManip( this, arguments, function( elem ) {
5446      if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5447        var target = manipulationTarget( this, elem );
5448        target.insertBefore( elem, target.firstChild );
5449      }
5450    } );
5451  },
5452
5453  before: function() {
5454    return domManip( this, arguments, function( elem ) {
5455      if ( this.parentNode ) {
5456        this.parentNode.insertBefore( elem, this );
5457      }
5458    } );
5459  },
5460
5461  after: function() {
5462    return domManip( this, arguments, function( elem ) {
5463      if ( this.parentNode ) {
5464        this.parentNode.insertBefore( elem, this.nextSibling );
5465      }
5466    } );
5467  },
5468
5469  empty: function() {
5470    var elem,
5471      i = 0;
5472
5473    for ( ; ( elem = this[ i ] ) != null; i++ ) {
5474      if ( elem.nodeType === 1 ) {
5475
5476        // Prevent memory leaks
5477        jQuery.cleanData( getAll( elem, false ) );
5478
5479        // Remove any remaining nodes
5480        elem.textContent = "";
5481      }
5482    }
5483
5484    return this;
5485  },
5486
5487  clone: function( dataAndEvents, deepDataAndEvents ) {
5488    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5489    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5490
5491    return this.map( function() {
5492      return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5493    } );
5494  },
5495
5496  html: function( value ) {
5497    return access( this, function( value ) {
5498      var elem = this[ 0 ] || {},
5499        i = 0,
5500        l = this.length;
5501
5502      if ( value === undefined && elem.nodeType === 1 ) {
5503        return elem.innerHTML;
5504      }
5505
5506      // See if we can take a shortcut and just use innerHTML
5507      if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5508        !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5509
5510        value = jQuery.htmlPrefilter( value );
5511
5512        try {
5513          for ( ; i < l; i++ ) {
5514            elem = this[ i ] || {};
5515
5516            // Remove element nodes and prevent memory leaks
5517            if ( elem.nodeType === 1 ) {
5518              jQuery.cleanData( getAll( elem, false ) );
5519              elem.innerHTML = value;
5520            }
5521          }
5522
5523          elem = 0;
5524
5525        // If using innerHTML throws an exception, use the fallback method
5526        } catch ( e ) {}
5527      }
5528
5529      if ( elem ) {
5530        this.empty().append( value );
5531      }
5532    }, null, value, arguments.length );
5533  },
5534
5535  replaceWith: function() {
5536    var ignored = [];
5537
5538    // Make the changes, replacing each non-ignored context element with the new content
5539    return domManip( this, arguments, function( elem ) {
5540      var parent = this.parentNode;
5541
5542      if ( jQuery.inArray( this, ignored ) < 0 ) {
5543        jQuery.cleanData( getAll( this ) );
5544        if ( parent ) {
5545          parent.replaceChild( elem, this );
5546        }
5547      }
5548
5549    // Force callback invocation
5550    }, ignored );
5551  }
5552} );
5553
5554jQuery.each( {
5555  appendTo: "append",
vendor: 9,983 bytes, lines 5556-5899
5556  prependTo: "prepend",
5557  insertBefore: "before",
5558  insertAfter: "after",
5559  replaceAll: "replaceWith"
5560}, function( name, original ) {
5561  jQuery.fn[ name ] = function( selector ) {
5562    var elems,
5563      ret = [],
5564      insert = jQuery( selector ),
5565      last = insert.length - 1,
5566      i = 0;
5567
5568    for ( ; i <= last; i++ ) {
5569      elems = i === last ? this : this.clone( true );
5570      jQuery( insert[ i ] )[ original ]( elems );
5571
5572      // Support: QtWebKit
5573      // .get() because push.apply(_, arraylike) throws
5574      push.apply( ret, elems.get() );
5575    }
5576
5577    return this.pushStack( ret );
5578  };
5579} );
5580
5581
5582var iframe,
5583  elemdisplay = {
5584
5585    // Support: Firefox
5586    // We have to pre-define these values for FF (#10227)
5587    HTML: "block",
5588    BODY: "block"
5589  };
5590
5591/**
5592 * Retrieve the actual display of a element
5593 * @param {String} name nodeName of the element
5594 * @param {Object} doc Document object
5595 */
5596
5597// Called only from within defaultDisplay
5598function actualDisplay( name, doc ) {
5599  var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5600
5601    display = jQuery.css( elem[ 0 ], "display" );
5602
5603  // We don't have any data stored on the element,
5604  // so use "detach" method as fast way to get rid of the element
5605  elem.detach();
5606
5607  return display;
5608}
5609
5610/**
5611 * Try to determine the default display value of an element
5612 * @param {String} nodeName
5613 */
5614function defaultDisplay( nodeName ) {
5615  var doc = document,
5616    display = elemdisplay[ nodeName ];
5617
5618  if ( !display ) {
5619    display = actualDisplay( nodeName, doc );
5620
5621    // If the simple way fails, read from inside an iframe
5622    if ( display === "none" || !display ) {
5623
5624      // Use the already-created iframe if possible
5625      iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
5626        .appendTo( doc.documentElement );
5627
5628      // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5629      doc = iframe[ 0 ].contentDocument;
5630
5631      // Support: IE
5632      doc.write();
5633      doc.close();
5634
5635      display = actualDisplay( nodeName, doc );
5636      iframe.detach();
5637    }
5638
5639    // Store the correct default display
5640    elemdisplay[ nodeName ] = display;
5641  }
5642
5643  return display;
5644}
5645var rmargin = ( /^margin/ );
5646
5647var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5648
5649var getStyles = function( elem ) {
5650
5651    // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5652    // IE throws on elements created in popups
5653    // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5654    var view = elem.ownerDocument.defaultView;
5655
5656    if ( !view || !view.opener ) {
5657      view = window;
5658    }
5659
5660    return view.getComputedStyle( elem );
5661  };
5662
5663var swap = function( elem, options, callback, args ) {
5664  var ret, name,
5665    old = {};
5666
5667  // Remember the old values, and insert the new ones
5668  for ( name in options ) {
5669    old[ name ] = elem.style[ name ];
5670    elem.style[ name ] = options[ name ];
5671  }
5672
5673  ret = callback.apply( elem, args || [] );
5674
5675  // Revert the old values
5676  for ( name in options ) {
5677    elem.style[ name ] = old[ name ];
5678  }
5679
5680  return ret;
5681};
5682
5683
5684var documentElement = document.documentElement;
5685
5686
5687
5688( function() {
5689  var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
5690    container = document.createElement( "div" ),
5691    div = document.createElement( "div" );
5692
5693  // Finish early in limited (non-browser) environments
5694  if ( !div.style ) {
5695    return;
5696  }
5697
5698  // Support: IE9-11+
5699  // Style of cloned element affects source element cloned (#8908)
5700  div.style.backgroundClip = "content-box";
5701  div.cloneNode( true ).style.backgroundClip = "";
5702  support.clearCloneStyle = div.style.backgroundClip === "content-box";
5703
5704  container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
5705    "padding:0;margin-top:1px;position:absolute";
5706  container.appendChild( div );
5707
5708  // Executing both pixelPosition & boxSizingReliable tests require only one layout
5709  // so they're executed at the same time to save the second computation.
5710  function computeStyleTests() {
5711    div.style.cssText =
5712
5713      // Support: Firefox<29, Android 2.3
5714      // Vendor-prefix box-sizing
5715      "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
5716      "position:relative;display:block;" +
5717      "margin:auto;border:1px;padding:1px;" +
5718      "top:1%;width:50%";
5719    div.innerHTML = "";
5720    documentElement.appendChild( container );
5721
5722    var divStyle = window.getComputedStyle( div );
5723    pixelPositionVal = divStyle.top !== "1%";
5724    reliableMarginLeftVal = divStyle.marginLeft === "2px";
5725    boxSizingReliableVal = divStyle.width === "4px";
5726
5727    // Support: Android 4.0 - 4.3 only
5728    // Some styles come back with percentage values, even though they shouldn't
5729    div.style.marginRight = "50%";
5730    pixelMarginRightVal = divStyle.marginRight === "4px";
5731
5732    documentElement.removeChild( container );
5733  }
5734
5735  jQuery.extend( support, {
5736    pixelPosition: function() {
5737
5738      // This test is executed only once but we still do memoizing
5739      // since we can use the boxSizingReliable pre-computing.
5740      // No need to check if the test was already performed, though.
5741      computeStyleTests();
5742      return pixelPositionVal;
5743    },
5744    boxSizingReliable: function() {
5745      if ( boxSizingReliableVal == null ) {
5746        computeStyleTests();
5747      }
5748      return boxSizingReliableVal;
5749    },
5750    pixelMarginRight: function() {
5751
5752      // Support: Android 4.0-4.3
5753      // We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
5754      // since that compresses better and they're computed together anyway.
5755      if ( boxSizingReliableVal == null ) {
5756        computeStyleTests();
5757      }
5758      return pixelMarginRightVal;
5759    },
5760    reliableMarginLeft: function() {
5761
5762      // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
5763      if ( boxSizingReliableVal == null ) {
5764        computeStyleTests();
5765      }
5766      return reliableMarginLeftVal;
5767    },
5768    reliableMarginRight: function() {
5769
5770      // Support: Android 2.3
5771      // Check if div with explicit width and no margin-right incorrectly
5772      // gets computed margin-right based on width of container. (#3333)
5773      // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5774      // This support function is only executed once so no memoizing is needed.
5775      var ret,
5776        marginDiv = div.appendChild( document.createElement( "div" ) );
5777
5778      // Reset CSS: box-sizing; display; margin; border; padding
5779      marginDiv.style.cssText = div.style.cssText =
5780
5781        // Support: Android 2.3
5782        // Vendor-prefix box-sizing
5783        "-webkit-box-sizing:content-box;box-sizing:content-box;" +
5784        "display:block;margin:0;border:0;padding:0";
5785      marginDiv.style.marginRight = marginDiv.style.width = "0";
5786      div.style.width = "1px";
5787      documentElement.appendChild( container );
5788
5789      ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
5790
5791      documentElement.removeChild( container );
5792      div.removeChild( marginDiv );
5793
5794      return ret;
5795    }
5796  } );
5797} )();
5798
5799
5800function curCSS( elem, name, computed ) {
5801  var width, minWidth, maxWidth, ret,
5802    style = elem.style;
5803
5804  computed = computed || getStyles( elem );
5805  ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
5806
5807  // Support: Opera 12.1x only
5808  // Fall back to style even without computed
5809  // computed is undefined for elems on document fragments
5810  if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
5811    ret = jQuery.style( elem, name );
5812  }
5813
5814  // Support: IE9
5815  // getPropertyValue is only needed for .css('filter') (#12537)
5816  if ( computed ) {
5817
5818    // A tribute to the "awesome hack by Dean Edwards"
5819    // Android Browser returns percentage for some values,
5820    // but width seems to be reliably pixels.
5821    // This is against the CSSOM draft spec:
5822    // http://dev.w3.org/csswg/cssom/#resolved-values
5823    if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5824
5825      // Remember the original values
5826      width = style.width;
5827      minWidth = style.minWidth;
5828      maxWidth = style.maxWidth;
5829
5830      // Put in the new values to get a computed value out
5831      style.minWidth = style.maxWidth = style.width = ret;
5832      ret = computed.width;
5833
5834      // Revert the changed values
5835      style.width = width;
5836      style.minWidth = minWidth;
5837      style.maxWidth = maxWidth;
5838    }
5839  }
5840
5841  return ret !== undefined ?
5842
5843    // Support: IE9-11+
5844    // IE returns zIndex value as an integer.
5845    ret + "" :
5846    ret;
5847}
5848
5849
5850function addGetHookIf( conditionFn, hookFn ) {
5851
5852  // Define the hook, we'll check on the first run if it's really needed.
5853  return {
5854    get: function() {
5855      if ( conditionFn() ) {
5856
5857        // Hook not needed (or it's not possible to use it due
5858        // to missing dependency), remove it.
5859        delete this.get;
5860        return;
5861      }
5862
5863      // Hook needed; redefine it so that the support test is not executed again.
5864      return ( this.get = hookFn ).apply( this, arguments );
5865    }
5866  };
5867}
5868
5869
5870var
5871
5872  // Swappable if display is none or starts with table
5873  // except "table", "table-cell", or "table-caption"
5874  // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5875  rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5876
5877  cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5878  cssNormalTransform = {
5879    letterSpacing: "0",
5880    fontWeight: "400"
5881  },
5882
5883  cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
5884  emptyStyle = document.createElement( "div" ).style;
5885
5886// Return a css property mapped to a potentially vendor prefixed property
5887function vendorPropName( name ) {
5888
5889  // Shortcut for names that are not vendor prefixed
5890  if ( name in emptyStyle ) {
5891    return name;
5892  }
5893
5894  // Check for vendor prefixed names
5895  var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
5896    i = cssPrefixes.length;
5897
5898  while ( i-- ) {
5899    name = cssPrefixes[ i ] + capName;
vendor: 4,323 bytes, lines 5900-6045
5900    if ( name in emptyStyle ) {
5901      return name;
5902    }
5903  }
5904}
5905
5906function setPositiveNumber( elem, value, subtract ) {
5907
5908  // Any relative (+/-) values have already been
5909  // normalized at this point
5910  var matches = rcssNum.exec( value );
5911  return matches ?
5912
5913    // Guard against undefined "subtract", e.g., when used as in cssHooks
5914    Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
5915    value;
5916}
5917
5918function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5919  var i = extra === ( isBorderBox ? "border" : "content" ) ?
5920
5921    // If we already have the right measurement, avoid augmentation
5922    4 :
5923
5924    // Otherwise initialize for horizontal or vertical properties
5925    name === "width" ? 1 : 0,
5926
5927    val = 0;
5928
5929  for ( ; i < 4; i += 2 ) {
5930
5931    // Both box models exclude margin, so add it if we want it
5932    if ( extra === "margin" ) {
5933      val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5934    }
5935
5936    if ( isBorderBox ) {
5937
5938      // border-box includes padding, so remove it if we want content
5939      if ( extra === "content" ) {
5940        val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5941      }
5942
5943      // At this point, extra isn't border nor margin, so remove border
5944      if ( extra !== "margin" ) {
5945        val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5946      }
5947    } else {
5948
5949      // At this point, extra isn't content, so add padding
5950      val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5951
5952      // At this point, extra isn't content nor padding, so add border
5953      if ( extra !== "padding" ) {
5954        val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5955      }
5956    }
5957  }
5958
5959  return val;
5960}
5961
5962function getWidthOrHeight( elem, name, extra ) {
5963
5964  // Start with offset property, which is equivalent to the border-box value
5965  var valueIsBorderBox = true,
5966    val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5967    styles = getStyles( elem ),
5968    isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5969
5970  // Some non-html elements return undefined for offsetWidth, so check for null/undefined
5971  // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5972  // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5973  if ( val <= 0 || val == null ) {
5974
5975    // Fall back to computed then uncomputed css if necessary
5976    val = curCSS( elem, name, styles );
5977    if ( val < 0 || val == null ) {
5978      val = elem.style[ name ];
5979    }
5980
5981    // Computed unit is not pixels. Stop here and return.
5982    if ( rnumnonpx.test( val ) ) {
5983      return val;
5984    }
5985
5986    // Check for style in case a browser which returns unreliable values
5987    // for getComputedStyle silently falls back to the reliable elem.style
5988    valueIsBorderBox = isBorderBox &&
5989      ( support.boxSizingReliable() || val === elem.style[ name ] );
5990
5991    // Normalize "", auto, and prepare for extra
5992    val = parseFloat( val ) || 0;
5993  }
5994
5995  // Use the active box-sizing model to add/subtract irrelevant styles
5996  return ( val +
5997    augmentWidthOrHeight(
5998      elem,
5999      name,
6000      extra || ( isBorderBox ? "border" : "content" ),
6001      valueIsBorderBox,
6002      styles
6003    )
6004  ) + "px";
6005}
6006
6007function showHide( elements, show ) {
6008  var display, elem, hidden,
6009    values = [],
6010    index = 0,
6011    length = elements.length;
6012
6013  for ( ; index < length; index++ ) {
6014    elem = elements[ index ];
6015    if ( !elem.style ) {
6016      continue;
6017    }
6018
6019    values[ index ] = dataPriv.get( elem, "olddisplay" );
6020    display = elem.style.display;
6021    if ( show ) {
6022
6023      // Reset the inline display of this element to learn if it is
6024      // being hidden by cascaded rules or not
6025      if ( !values[ index ] && display === "none" ) {
6026        elem.style.display = "";
6027      }
6028
6029      // Set elements which have been overridden with display: none
6030      // in a stylesheet to whatever the default browser style is
6031      // for such an element
6032      if ( elem.style.display === "" && isHidden( elem ) ) {
6033        values[ index ] = dataPriv.access(
6034          elem,
6035          "olddisplay",
6036          defaultDisplay( elem.nodeName )
6037        );
6038      }
6039    } else {
6040      hidden = isHidden( elem );
6041
6042      if ( display !== "none" || !hidden ) {
6043        dataPriv.set(
6044          elem,
6045          "olddisplay",
vendor: 13,874 bytes, lines 6046-6550
6046          hidden ? display : jQuery.css( elem, "display" )
6047        );
6048      }
6049    }
6050  }
6051
6052  // Set the display of most of the elements in a second loop
6053  // to avoid the constant reflow
6054  for ( index = 0; index < length; index++ ) {
6055    elem = elements[ index ];
6056    if ( !elem.style ) {
6057      continue;
6058    }
6059    if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6060      elem.style.display = show ? values[ index ] || "" : "none";
6061    }
6062  }
6063
6064  return elements;
6065}
6066
6067jQuery.extend( {
6068
6069  // Add in style property hooks for overriding the default
6070  // behavior of getting and setting a style property
6071  cssHooks: {
6072    opacity: {
6073      get: function( elem, computed ) {
6074        if ( computed ) {
6075
6076          // We should always get a number back from opacity
6077          var ret = curCSS( elem, "opacity" );
6078          return ret === "" ? "1" : ret;
6079        }
6080      }
6081    }
6082  },
6083
6084  // Don't automatically add "px" to these possibly-unitless properties
6085  cssNumber: {
6086    "animationIterationCount": true,
6087    "columnCount": true,
6088    "fillOpacity": true,
6089    "flexGrow": true,
6090    "flexShrink": true,
6091    "fontWeight": true,
6092    "lineHeight": true,
6093    "opacity": true,
6094    "order": true,
6095    "orphans": true,
6096    "widows": true,
6097    "zIndex": true,
6098    "zoom": true
6099  },
6100
6101  // Add in properties whose names you wish to fix before
6102  // setting or getting the value
6103  cssProps: {
6104    "float": "cssFloat"
6105  },
6106
6107  // Get and set the style property on a DOM Node
6108  style: function( elem, name, value, extra ) {
6109
6110    // Don't set styles on text and comment nodes
6111    if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6112      return;
6113    }
6114
6115    // Make sure that we're working with the right name
6116    var ret, type, hooks,
6117      origName = jQuery.camelCase( name ),
6118      style = elem.style;
6119
6120    name = jQuery.cssProps[ origName ] ||
6121      ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6122
6123    // Gets hook for the prefixed version, then unprefixed version
6124    hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6125
6126    // Check if we're setting a value
6127    if ( value !== undefined ) {
6128      type = typeof value;
6129
6130      // Convert "+=" or "-=" to relative numbers (#7345)
6131      if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6132        value = adjustCSS( elem, name, ret );
6133
6134        // Fixes bug #9237
6135        type = "number";
6136      }
6137
6138      // Make sure that null and NaN values aren't set (#7116)
6139      if ( value == null || value !== value ) {
6140        return;
6141      }
6142
6143      // If a number was passed in, add the unit (except for certain CSS properties)
6144      if ( type === "number" ) {
6145        value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6146      }
6147
6148      // Support: IE9-11+
6149      // background-* props affect original clone's values
6150      if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6151        style[ name ] = "inherit";
6152      }
6153
6154      // If a hook was provided, use that value, otherwise just set the specified value
6155      if ( !hooks || !( "set" in hooks ) ||
6156        ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6157
6158        style[ name ] = value;
6159      }
6160
6161    } else {
6162
6163      // If a hook was provided get the non-computed value from there
6164      if ( hooks && "get" in hooks &&
6165        ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6166
6167        return ret;
6168      }
6169
6170      // Otherwise just get the value from the style object
6171      return style[ name ];
6172    }
6173  },
6174
6175  css: function( elem, name, extra, styles ) {
6176    var val, num, hooks,
6177      origName = jQuery.camelCase( name );
6178
6179    // Make sure that we're working with the right name
6180    name = jQuery.cssProps[ origName ] ||
6181      ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6182
6183    // Try prefixed name followed by the unprefixed name
6184    hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6185
6186    // If a hook was provided get the computed value from there
6187    if ( hooks && "get" in hooks ) {
6188      val = hooks.get( elem, true, extra );
6189    }
6190
6191    // Otherwise, if a way to get the computed value exists, use that
6192    if ( val === undefined ) {
6193      val = curCSS( elem, name, styles );
6194    }
6195
6196    // Convert "normal" to computed value
6197    if ( val === "normal" && name in cssNormalTransform ) {
6198      val = cssNormalTransform[ name ];
6199    }
6200
6201    // Make numeric if forced or a qualifier was provided and val looks numeric
6202    if ( extra === "" || extra ) {
6203      num = parseFloat( val );
6204      return extra === true || isFinite( num ) ? num || 0 : val;
6205    }
6206    return val;
6207  }
6208} );
6209
6210jQuery.each( [ "height", "width" ], function( i, name ) {
6211  jQuery.cssHooks[ name ] = {
6212    get: function( elem, computed, extra ) {
6213      if ( computed ) {
6214
6215        // Certain elements can have dimension info if we invisibly show them
6216        // but it must have a current display style that would benefit
6217        return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6218          elem.offsetWidth === 0 ?
6219            swap( elem, cssShow, function() {
6220              return getWidthOrHeight( elem, name, extra );
6221            } ) :
6222            getWidthOrHeight( elem, name, extra );
6223      }
6224    },
6225
6226    set: function( elem, value, extra ) {
6227      var matches,
6228        styles = extra && getStyles( elem ),
6229        subtract = extra && augmentWidthOrHeight(
6230          elem,
6231          name,
6232          extra,
6233          jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6234          styles
6235        );
6236
6237      // Convert to pixels if value adjustment is needed
6238      if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6239        ( matches[ 3 ] || "px" ) !== "px" ) {
6240
6241        elem.style[ name ] = value;
6242        value = jQuery.css( elem, name );
6243      }
6244
6245      return setPositiveNumber( elem, value, subtract );
6246    }
6247  };
6248} );
6249
6250jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6251  function( elem, computed ) {
6252    if ( computed ) {
6253      return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6254        elem.getBoundingClientRect().left -
6255          swap( elem, { marginLeft: 0 }, function() {
6256            return elem.getBoundingClientRect().left;
6257          } )
6258        ) + "px";
6259    }
6260  }
6261);
6262
6263// Support: Android 2.3
6264jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6265  function( elem, computed ) {
6266    if ( computed ) {
6267      return swap( elem, { "display": "inline-block" },
6268        curCSS, [ elem, "marginRight" ] );
6269    }
6270  }
6271);
6272
6273// These hooks are used by animate to expand properties
6274jQuery.each( {
6275  margin: "",
6276  padding: "",
6277  border: "Width"
6278}, function( prefix, suffix ) {
6279  jQuery.cssHooks[ prefix + suffix ] = {
6280    expand: function( value ) {
6281      var i = 0,
6282        expanded = {},
6283
6284        // Assumes a single number if not a string
6285        parts = typeof value === "string" ? value.split( " " ) : [ value ];
6286
6287      for ( ; i < 4; i++ ) {
6288        expanded[ prefix + cssExpand[ i ] + suffix ] =
6289          parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6290      }
6291
6292      return expanded;
6293    }
6294  };
6295
6296  if ( !rmargin.test( prefix ) ) {
6297    jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6298  }
6299} );
6300
6301jQuery.fn.extend( {
6302  css: function( name, value ) {
6303    return access( this, function( elem, name, value ) {
6304      var styles, len,
6305        map = {},
6306        i = 0;
6307
6308      if ( jQuery.isArray( name ) ) {
6309        styles = getStyles( elem );
6310        len = name.length;
6311
6312        for ( ; i < len; i++ ) {
6313          map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6314        }
6315
6316        return map;
6317      }
6318
6319      return value !== undefined ?
6320        jQuery.style( elem, name, value ) :
6321        jQuery.css( elem, name );
6322    }, name, value, arguments.length > 1 );
6323  },
6324  show: function() {
6325    return showHide( this, true );
6326  },
6327  hide: function() {
6328    return showHide( this );
6329  },
6330  toggle: function( state ) {
6331    if ( typeof state === "boolean" ) {
6332      return state ? this.show() : this.hide();
6333    }
6334
6335    return this.each( function() {
6336      if ( isHidden( this ) ) {
6337        jQuery( this ).show();
6338      } else {
6339        jQuery( this ).hide();
6340      }
6341    } );
6342  }
6343} );
6344
6345
6346function Tween( elem, options, prop, end, easing ) {
6347  return new Tween.prototype.init( elem, options, prop, end, easing );
6348}
6349jQuery.Tween = Tween;
6350
6351Tween.prototype = {
6352  constructor: Tween,
6353  init: function( elem, options, prop, end, easing, unit ) {
6354    this.elem = elem;
6355    this.prop = prop;
6356    this.easing = easing || jQuery.easing._default;
6357    this.options = options;
6358    this.start = this.now = this.cur();
6359    this.end = end;
6360    this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6361  },
6362  cur: function() {
6363    var hooks = Tween.propHooks[ this.prop ];
6364
6365    return hooks && hooks.get ?
6366      hooks.get( this ) :
6367      Tween.propHooks._default.get( this );
6368  },
6369  run: function( percent ) {
6370    var eased,
6371      hooks = Tween.propHooks[ this.prop ];
6372
6373    if ( this.options.duration ) {
6374      this.pos = eased = jQuery.easing[ this.easing ](
6375        percent, this.options.duration * percent, 0, 1, this.options.duration
6376      );
6377    } else {
6378      this.pos = eased = percent;
6379    }
6380    this.now = ( this.end - this.start ) * eased + this.start;
6381
6382    if ( this.options.step ) {
6383      this.options.step.call( this.elem, this.now, this );
6384    }
6385
6386    if ( hooks && hooks.set ) {
6387      hooks.set( this );
6388    } else {
6389      Tween.propHooks._default.set( this );
6390    }
6391    return this;
6392  }
6393};
6394
6395Tween.prototype.init.prototype = Tween.prototype;
6396
6397Tween.propHooks = {
6398  _default: {
6399    get: function( tween ) {
6400      var result;
6401
6402      // Use a property on the element directly when it is not a DOM element,
6403      // or when there is no matching style property that exists.
6404      if ( tween.elem.nodeType !== 1 ||
6405        tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6406        return tween.elem[ tween.prop ];
6407      }
6408
6409      // Passing an empty string as a 3rd parameter to .css will automatically
6410      // attempt a parseFloat and fallback to a string if the parse fails.
6411      // Simple values such as "10px" are parsed to Float;
6412      // complex values such as "rotate(1rad)" are returned as-is.
6413      result = jQuery.css( tween.elem, tween.prop, "" );
6414
6415      // Empty strings, null, undefined and "auto" are converted to 0.
6416      return !result || result === "auto" ? 0 : result;
6417    },
6418    set: function( tween ) {
6419
6420      // Use step hook for back compat.
6421      // Use cssHook if its there.
6422      // Use .style if available and use plain properties where available.
6423      if ( jQuery.fx.step[ tween.prop ] ) {
6424        jQuery.fx.step[ tween.prop ]( tween );
6425      } else if ( tween.elem.nodeType === 1 &&
6426        ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6427          jQuery.cssHooks[ tween.prop ] ) ) {
6428        jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6429      } else {
6430        tween.elem[ tween.prop ] = tween.now;
6431      }
6432    }
6433  }
6434};
6435
6436// Support: IE9
6437// Panic based approach to setting things on disconnected nodes
6438Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6439  set: function( tween ) {
6440    if ( tween.elem.nodeType && tween.elem.parentNode ) {
6441      tween.elem[ tween.prop ] = tween.now;
6442    }
6443  }
6444};
6445
6446jQuery.easing = {
6447  linear: function( p ) {
6448    return p;
6449  },
6450  swing: function( p ) {
6451    return 0.5 - Math.cos( p * Math.PI ) / 2;
6452  },
6453  _default: "swing"
6454};
6455
6456jQuery.fx = Tween.prototype.init;
6457
6458// Back Compat <1.8 extension point
6459jQuery.fx.step = {};
6460
6461
6462
6463
6464var
6465  fxNow, timerId,
6466  rfxtypes = /^(?:toggle|show|hide)$/,
6467  rrun = /queueHooks$/;
6468
6469// Animations created synchronously will run synchronously
6470function createFxNow() {
6471  window.setTimeout( function() {
6472    fxNow = undefined;
6473  } );
6474  return ( fxNow = jQuery.now() );
6475}
6476
6477// Generate parameters to create a standard animation
6478function genFx( type, includeWidth ) {
6479  var which,
6480    i = 0,
6481    attrs = { height: type };
6482
6483  // If we include width, step value is 1 to do all cssExpand values,
6484  // otherwise step value is 2 to skip over Left and Right
6485  includeWidth = includeWidth ? 1 : 0;
6486  for ( ; i < 4 ; i += 2 - includeWidth ) {
6487    which = cssExpand[ i ];
6488    attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6489  }
6490
6491  if ( includeWidth ) {
6492    attrs.opacity = attrs.width = type;
6493  }
6494
6495  return attrs;
6496}
6497
6498function createTween( value, prop, animation ) {
6499  var tween,
6500    collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6501    index = 0,
6502    length = collection.length;
6503  for ( ; index < length; index++ ) {
6504    if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6505
6506      // We're done with this property
6507      return tween;
6508    }
6509  }
6510}
6511
6512function defaultPrefilter( elem, props, opts ) {
6513  /* jshint validthis: true */
6514  var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6515    anim = this,
6516    orig = {},
6517    style = elem.style,
6518    hidden = elem.nodeType && isHidden( elem ),
6519    dataShow = dataPriv.get( elem, "fxshow" );
6520
6521  // Handle queue: false promises
6522  if ( !opts.queue ) {
6523    hooks = jQuery._queueHooks( elem, "fx" );
6524    if ( hooks.unqueued == null ) {
6525      hooks.unqueued = 0;
6526      oldfire = hooks.empty.fire;
6527      hooks.empty.fire = function() {
6528        if ( !hooks.unqueued ) {
6529          oldfire();
6530        }
6531      };
6532    }
6533    hooks.unqueued++;
6534
6535    anim.always( function() {
6536
6537      // Ensure the complete handler is called before this completes
6538      anim.always( function() {
6539        hooks.unqueued--;
6540        if ( !jQuery.queue( elem, "fx" ).length ) {
6541          hooks.empty.fire();
6542        }
6543      } );
6544    } );
6545  }
6546
6547  // Height/width overflow pass
6548  if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6549
6550    // Make sure that nothing sneaks out
vendor: 4,265 bytes, lines 6551-6697
6551    // Record all 3 overflow attributes because IE9-10 do not
6552    // change the overflow attribute when overflowX and
6553    // overflowY are set to the same value
6554    opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6555
6556    // Set display property to inline-block for height/width
6557    // animations on inline elements that are having width/height animated
6558    display = jQuery.css( elem, "display" );
6559
6560    // Test default display if display is currently "none"
6561    checkDisplay = display === "none" ?
6562      dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6563
6564    if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6565      style.display = "inline-block";
6566    }
6567  }
6568
6569  if ( opts.overflow ) {
6570    style.overflow = "hidden";
6571    anim.always( function() {
6572      style.overflow = opts.overflow[ 0 ];
6573      style.overflowX = opts.overflow[ 1 ];
6574      style.overflowY = opts.overflow[ 2 ];
6575    } );
6576  }
6577
6578  // show/hide pass
6579  for ( prop in props ) {
6580    value = props[ prop ];
6581    if ( rfxtypes.exec( value ) ) {
6582      delete props[ prop ];
6583      toggle = toggle || value === "toggle";
6584      if ( value === ( hidden ? "hide" : "show" ) ) {
6585
6586        // If there is dataShow left over from a stopped hide or show
6587        // and we are going to proceed with show, we should pretend to be hidden
6588        if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6589          hidden = true;
6590        } else {
6591          continue;
6592        }
6593      }
6594      orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6595
6596    // Any non-fx value stops us from restoring the original display value
6597    } else {
6598      display = undefined;
6599    }
6600  }
6601
6602  if ( !jQuery.isEmptyObject( orig ) ) {
6603    if ( dataShow ) {
6604      if ( "hidden" in dataShow ) {
6605        hidden = dataShow.hidden;
6606      }
6607    } else {
6608      dataShow = dataPriv.access( elem, "fxshow", {} );
6609    }
6610
6611    // Store state if its toggle - enables .stop().toggle() to "reverse"
6612    if ( toggle ) {
6613      dataShow.hidden = !hidden;
6614    }
6615    if ( hidden ) {
6616      jQuery( elem ).show();
6617    } else {
6618      anim.done( function() {
6619        jQuery( elem ).hide();
6620      } );
6621    }
6622    anim.done( function() {
6623      var prop;
6624
6625      dataPriv.remove( elem, "fxshow" );
6626      for ( prop in orig ) {
6627        jQuery.style( elem, prop, orig[ prop ] );
6628      }
6629    } );
6630    for ( prop in orig ) {
6631      tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6632
6633      if ( !( prop in dataShow ) ) {
6634        dataShow[ prop ] = tween.start;
6635        if ( hidden ) {
6636          tween.end = tween.start;
6637          tween.start = prop === "width" || prop === "height" ? 1 : 0;
6638        }
6639      }
6640    }
6641
6642  // If this is a noop like .hide().hide(), restore an overwritten display value
6643  } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
6644    style.display = display;
6645  }
6646}
6647
6648function propFilter( props, specialEasing ) {
6649  var index, name, easing, value, hooks;
6650
6651  // camelCase, specialEasing and expand cssHook pass
6652  for ( index in props ) {
6653    name = jQuery.camelCase( index );
6654    easing = specialEasing[ name ];
6655    value = props[ index ];
6656    if ( jQuery.isArray( value ) ) {
6657      easing = value[ 1 ];
6658      value = props[ index ] = value[ 0 ];
6659    }
6660
6661    if ( index !== name ) {
6662      props[ name ] = value;
6663      delete props[ index ];
6664    }
6665
6666    hooks = jQuery.cssHooks[ name ];
6667    if ( hooks && "expand" in hooks ) {
6668      value = hooks.expand( value );
6669      delete props[ name ];
6670
6671      // Not quite $.extend, this won't overwrite existing keys.
6672      // Reusing 'index' because we have the correct "name"
6673      for ( index in value ) {
6674        if ( !( index in props ) ) {
6675          props[ index ] = value[ index ];
6676          specialEasing[ index ] = easing;
6677        }
6678      }
6679    } else {
6680      specialEasing[ name ] = easing;
6681    }
6682  }
6683}
6684
6685function Animation( elem, properties, options ) {
6686  var result,
6687    stopped,
6688    index = 0,
6689    length = Animation.prefilters.length,
6690    deferred = jQuery.Deferred().always( function() {
6691
6692      // Don't match elem in the :animated selector
6693      delete tick.elem;
6694    } ),
6695    tick = function() {
6696      if ( stopped ) {
6697        return false;
vendor: 19,594 bytes, lines 6698-7444
6698      }
6699      var currentTime = fxNow || createFxNow(),
6700        remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6701
6702        // Support: Android 2.3
6703        // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6704        temp = remaining / animation.duration || 0,
6705        percent = 1 - temp,
6706        index = 0,
6707        length = animation.tweens.length;
6708
6709      for ( ; index < length ; index++ ) {
6710        animation.tweens[ index ].run( percent );
6711      }
6712
6713      deferred.notifyWith( elem, [ animation, percent, remaining ] );
6714
6715      if ( percent < 1 && length ) {
6716        return remaining;
6717      } else {
6718        deferred.resolveWith( elem, [ animation ] );
6719        return false;
6720      }
6721    },
6722    animation = deferred.promise( {
6723      elem: elem,
6724      props: jQuery.extend( {}, properties ),
6725      opts: jQuery.extend( true, {
6726        specialEasing: {},
6727        easing: jQuery.easing._default
6728      }, options ),
6729      originalProperties: properties,
6730      originalOptions: options,
6731      startTime: fxNow || createFxNow(),
6732      duration: options.duration,
6733      tweens: [],
6734      createTween: function( prop, end ) {
6735        var tween = jQuery.Tween( elem, animation.opts, prop, end,
6736            animation.opts.specialEasing[ prop ] || animation.opts.easing );
6737        animation.tweens.push( tween );
6738        return tween;
6739      },
6740      stop: function( gotoEnd ) {
6741        var index = 0,
6742
6743          // If we are going to the end, we want to run all the tweens
6744          // otherwise we skip this part
6745          length = gotoEnd ? animation.tweens.length : 0;
6746        if ( stopped ) {
6747          return this;
6748        }
6749        stopped = true;
6750        for ( ; index < length ; index++ ) {
6751          animation.tweens[ index ].run( 1 );
6752        }
6753
6754        // Resolve when we played the last frame; otherwise, reject
6755        if ( gotoEnd ) {
6756          deferred.notifyWith( elem, [ animation, 1, 0 ] );
6757          deferred.resolveWith( elem, [ animation, gotoEnd ] );
6758        } else {
6759          deferred.rejectWith( elem, [ animation, gotoEnd ] );
6760        }
6761        return this;
6762      }
6763    } ),
6764    props = animation.props;
6765
6766  propFilter( props, animation.opts.specialEasing );
6767
6768  for ( ; index < length ; index++ ) {
6769    result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
6770    if ( result ) {
6771      if ( jQuery.isFunction( result.stop ) ) {
6772        jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
6773          jQuery.proxy( result.stop, result );
6774      }
6775      return result;
6776    }
6777  }
6778
6779  jQuery.map( props, createTween, animation );
6780
6781  if ( jQuery.isFunction( animation.opts.start ) ) {
6782    animation.opts.start.call( elem, animation );
6783  }
6784
6785  jQuery.fx.timer(
6786    jQuery.extend( tick, {
6787      elem: elem,
6788      anim: animation,
6789      queue: animation.opts.queue
6790    } )
6791  );
6792
6793  // attach callbacks from options
6794  return animation.progress( animation.opts.progress )
6795    .done( animation.opts.done, animation.opts.complete )
6796    .fail( animation.opts.fail )
6797    .always( animation.opts.always );
6798}
6799
6800jQuery.Animation = jQuery.extend( Animation, {
6801  tweeners: {
6802    "*": [ function( prop, value ) {
6803      var tween = this.createTween( prop, value );
6804      adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
6805      return tween;
6806    } ]
6807  },
6808
6809  tweener: function( props, callback ) {
6810    if ( jQuery.isFunction( props ) ) {
6811      callback = props;
6812      props = [ "*" ];
6813    } else {
6814      props = props.match( rnotwhite );
6815    }
6816
6817    var prop,
6818      index = 0,
6819      length = props.length;
6820
6821    for ( ; index < length ; index++ ) {
6822      prop = props[ index ];
6823      Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
6824      Animation.tweeners[ prop ].unshift( callback );
6825    }
6826  },
6827
6828  prefilters: [ defaultPrefilter ],
6829
6830  prefilter: function( callback, prepend ) {
6831    if ( prepend ) {
6832      Animation.prefilters.unshift( callback );
6833    } else {
6834      Animation.prefilters.push( callback );
6835    }
6836  }
6837} );
6838
6839jQuery.speed = function( speed, easing, fn ) {
6840  var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6841    complete: fn || !fn && easing ||
6842      jQuery.isFunction( speed ) && speed,
6843    duration: speed,
6844    easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6845  };
6846
6847  opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
6848    opt.duration : opt.duration in jQuery.fx.speeds ?
6849      jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6850
6851  // Normalize opt.queue - true/undefined/null -> "fx"
6852  if ( opt.queue == null || opt.queue === true ) {
6853    opt.queue = "fx";
6854  }
6855
6856  // Queueing
6857  opt.old = opt.complete;
6858
6859  opt.complete = function() {
6860    if ( jQuery.isFunction( opt.old ) ) {
6861      opt.old.call( this );
6862    }
6863
6864    if ( opt.queue ) {
6865      jQuery.dequeue( this, opt.queue );
6866    }
6867  };
6868
6869  return opt;
6870};
6871
6872jQuery.fn.extend( {
6873  fadeTo: function( speed, to, easing, callback ) {
6874
6875    // Show any hidden elements after setting opacity to 0
6876    return this.filter( isHidden ).css( "opacity", 0 ).show()
6877
6878      // Animate to the value specified
6879      .end().animate( { opacity: to }, speed, easing, callback );
6880  },
6881  animate: function( prop, speed, easing, callback ) {
6882    var empty = jQuery.isEmptyObject( prop ),
6883      optall = jQuery.speed( speed, easing, callback ),
6884      doAnimation = function() {
6885
6886        // Operate on a copy of prop so per-property easing won't be lost
6887        var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6888
6889        // Empty animations, or finishing resolves immediately
6890        if ( empty || dataPriv.get( this, "finish" ) ) {
6891          anim.stop( true );
6892        }
6893      };
6894      doAnimation.finish = doAnimation;
6895
6896    return empty || optall.queue === false ?
6897      this.each( doAnimation ) :
6898      this.queue( optall.queue, doAnimation );
6899  },
6900  stop: function( type, clearQueue, gotoEnd ) {
6901    var stopQueue = function( hooks ) {
6902      var stop = hooks.stop;
6903      delete hooks.stop;
6904      stop( gotoEnd );
6905    };
6906
6907    if ( typeof type !== "string" ) {
6908      gotoEnd = clearQueue;
6909      clearQueue = type;
6910      type = undefined;
6911    }
6912    if ( clearQueue && type !== false ) {
6913      this.queue( type || "fx", [] );
6914    }
6915
6916    return this.each( function() {
6917      var dequeue = true,
6918        index = type != null && type + "queueHooks",
6919        timers = jQuery.timers,
6920        data = dataPriv.get( this );
6921
6922      if ( index ) {
6923        if ( data[ index ] && data[ index ].stop ) {
6924          stopQueue( data[ index ] );
6925        }
6926      } else {
6927        for ( index in data ) {
6928          if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6929            stopQueue( data[ index ] );
6930          }
6931        }
6932      }
6933
6934      for ( index = timers.length; index--; ) {
6935        if ( timers[ index ].elem === this &&
6936          ( type == null || timers[ index ].queue === type ) ) {
6937
6938          timers[ index ].anim.stop( gotoEnd );
6939          dequeue = false;
6940          timers.splice( index, 1 );
6941        }
6942      }
6943
6944      // Start the next in the queue if the last step wasn't forced.
6945      // Timers currently will call their complete callbacks, which
6946      // will dequeue but only if they were gotoEnd.
6947      if ( dequeue || !gotoEnd ) {
6948        jQuery.dequeue( this, type );
6949      }
6950    } );
6951  },
6952  finish: function( type ) {
6953    if ( type !== false ) {
6954      type = type || "fx";
6955    }
6956    return this.each( function() {
6957      var index,
6958        data = dataPriv.get( this ),
6959        queue = data[ type + "queue" ],
6960        hooks = data[ type + "queueHooks" ],
6961        timers = jQuery.timers,
6962        length = queue ? queue.length : 0;
6963
6964      // Enable finishing flag on private data
6965      data.finish = true;
6966
6967      // Empty the queue first
6968      jQuery.queue( this, type, [] );
6969
6970      if ( hooks && hooks.stop ) {
6971        hooks.stop.call( this, true );
6972      }
6973
6974      // Look for any active animations, and finish them
6975      for ( index = timers.length; index--; ) {
6976        if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6977          timers[ index ].anim.stop( true );
6978          timers.splice( index, 1 );
6979        }
6980      }
6981
6982      // Look for any animations in the old queue and finish them
6983      for ( index = 0; index < length; index++ ) {
6984        if ( queue[ index ] && queue[ index ].finish ) {
6985          queue[ index ].finish.call( this );
6986        }
6987      }
6988
6989      // Turn off finishing flag
6990      delete data.finish;
6991    } );
6992  }
6993} );
6994
6995jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
6996  var cssFn = jQuery.fn[ name ];
6997  jQuery.fn[ name ] = function( speed, easing, callback ) {
6998    return speed == null || typeof speed === "boolean" ?
6999      cssFn.apply( this, arguments ) :
7000      this.animate( genFx( name, true ), speed, easing, callback );
7001  };
7002} );
7003
7004// Generate shortcuts for custom animations
7005jQuery.each( {
7006  slideDown: genFx( "show" ),
7007  slideUp: genFx( "hide" ),
7008  slideToggle: genFx( "toggle" ),
7009  fadeIn: { opacity: "show" },
7010  fadeOut: { opacity: "hide" },
7011  fadeToggle: { opacity: "toggle" }
7012}, function( name, props ) {
7013  jQuery.fn[ name ] = function( speed, easing, callback ) {
7014    return this.animate( props, speed, easing, callback );
7015  };
7016} );
7017
7018jQuery.timers = [];
7019jQuery.fx.tick = function() {
7020  var timer,
7021    i = 0,
7022    timers = jQuery.timers;
7023
7024  fxNow = jQuery.now();
7025
7026  for ( ; i < timers.length; i++ ) {
7027    timer = timers[ i ];
7028
7029    // Checks the timer has not already been removed
7030    if ( !timer() && timers[ i ] === timer ) {
7031      timers.splice( i--, 1 );
7032    }
7033  }
7034
7035  if ( !timers.length ) {
7036    jQuery.fx.stop();
7037  }
7038  fxNow = undefined;
7039};
7040
7041jQuery.fx.timer = function( timer ) {
7042  jQuery.timers.push( timer );
7043  if ( timer() ) {
7044    jQuery.fx.start();
7045  } else {
7046    jQuery.timers.pop();
7047  }
7048};
7049
7050jQuery.fx.interval = 13;
7051jQuery.fx.start = function() {
7052  if ( !timerId ) {
7053    timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
7054  }
7055};
7056
7057jQuery.fx.stop = function() {
7058  window.clearInterval( timerId );
7059
7060  timerId = null;
7061};
7062
7063jQuery.fx.speeds = {
7064  slow: 600,
7065  fast: 200,
7066
7067  // Default speed
7068  _default: 400
7069};
7070
7071
7072// Based off of the plugin by Clint Helfers, with permission.
7073// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7074jQuery.fn.delay = function( time, type ) {
7075  time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7076  type = type || "fx";
7077
7078  return this.queue( type, function( next, hooks ) {
7079    var timeout = window.setTimeout( next, time );
7080    hooks.stop = function() {
7081      window.clearTimeout( timeout );
7082    };
7083  } );
7084};
7085
7086
7087( function() {
7088  var input = document.createElement( "input" ),
7089    select = document.createElement( "select" ),
7090    opt = select.appendChild( document.createElement( "option" ) );
7091
7092  input.type = "checkbox";
7093
7094  // Support: iOS<=5.1, Android<=4.2+
7095  // Default value for a checkbox should be "on"
7096  support.checkOn = input.value !== "";
7097
7098  // Support: IE<=11+
7099  // Must access selectedIndex to make default options select
7100  support.optSelected = opt.selected;
7101
7102  // Support: Android<=2.3
7103  // Options inside disabled selects are incorrectly marked as disabled
7104  select.disabled = true;
7105  support.optDisabled = !opt.disabled;
7106
7107  // Support: IE<=11+
7108  // An input loses its value after becoming a radio
7109  input = document.createElement( "input" );
7110  input.value = "t";
7111  input.type = "radio";
7112  support.radioValue = input.value === "t";
7113} )();
7114
7115
7116var boolHook,
7117  attrHandle = jQuery.expr.attrHandle;
7118
7119jQuery.fn.extend( {
7120  attr: function( name, value ) {
7121    return access( this, jQuery.attr, name, value, arguments.length > 1 );
7122  },
7123
7124  removeAttr: function( name ) {
7125    return this.each( function() {
7126      jQuery.removeAttr( this, name );
7127    } );
7128  }
7129} );
7130
7131jQuery.extend( {
7132  attr: function( elem, name, value ) {
7133    var ret, hooks,
7134      nType = elem.nodeType;
7135
7136    // Don't get/set attributes on text, comment and attribute nodes
7137    if ( nType === 3 || nType === 8 || nType === 2 ) {
7138      return;
7139    }
7140
7141    // Fallback to prop when attributes are not supported
7142    if ( typeof elem.getAttribute === "undefined" ) {
7143      return jQuery.prop( elem, name, value );
7144    }
7145
7146    // All attributes are lowercase
7147    // Grab necessary hook if one is defined
7148    if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7149      name = name.toLowerCase();
7150      hooks = jQuery.attrHooks[ name ] ||
7151        ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7152    }
7153
7154    if ( value !== undefined ) {
7155      if ( value === null ) {
7156        jQuery.removeAttr( elem, name );
7157        return;
7158      }
7159
7160      if ( hooks && "set" in hooks &&
7161        ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7162        return ret;
7163      }
7164
7165      elem.setAttribute( name, value + "" );
7166      return value;
7167    }
7168
7169    if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7170      return ret;
7171    }
7172
7173    ret = jQuery.find.attr( elem, name );
7174
7175    // Non-existent attributes return null, we normalize to undefined
7176    return ret == null ? undefined : ret;
7177  },
7178
7179  attrHooks: {
7180    type: {
7181      set: function( elem, value ) {
7182        if ( !support.radioValue && value === "radio" &&
7183          jQuery.nodeName( elem, "input" ) ) {
7184          var val = elem.value;
7185          elem.setAttribute( "type", value );
7186          if ( val ) {
7187            elem.value = val;
7188          }
7189          return value;
7190        }
7191      }
7192    }
7193  },
7194
7195  removeAttr: function( elem, value ) {
7196    var name, propName,
7197      i = 0,
7198      attrNames = value && value.match( rnotwhite );
7199
7200    if ( attrNames && elem.nodeType === 1 ) {
7201      while ( ( name = attrNames[ i++ ] ) ) {
7202        propName = jQuery.propFix[ name ] || name;
7203
7204        // Boolean attributes get special treatment (#10870)
7205        if ( jQuery.expr.match.bool.test( name ) ) {
7206
7207          // Set corresponding property to false
7208          elem[ propName ] = false;
7209        }
7210
7211        elem.removeAttribute( name );
7212      }
7213    }
7214  }
7215} );
7216
7217// Hooks for boolean attributes
7218boolHook = {
7219  set: function( elem, value, name ) {
7220    if ( value === false ) {
7221
7222      // Remove boolean attributes when set to false
7223      jQuery.removeAttr( elem, name );
7224    } else {
7225      elem.setAttribute( name, name );
7226    }
7227    return name;
7228  }
7229};
7230jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7231  var getter = attrHandle[ name ] || jQuery.find.attr;
7232
7233  attrHandle[ name ] = function( elem, name, isXML ) {
7234    var ret, handle;
7235    if ( !isXML ) {
7236
7237      // Avoid an infinite loop by temporarily removing this function from the getter
7238      handle = attrHandle[ name ];
7239      attrHandle[ name ] = ret;
7240      ret = getter( elem, name, isXML ) != null ?
7241        name.toLowerCase() :
7242        null;
7243      attrHandle[ name ] = handle;
7244    }
7245    return ret;
7246  };
7247} );
7248
7249
7250
7251
7252var rfocusable = /^(?:input|select|textarea|button)$/i,
7253  rclickable = /^(?:a|area)$/i;
7254
7255jQuery.fn.extend( {
7256  prop: function( name, value ) {
7257    return access( this, jQuery.prop, name, value, arguments.length > 1 );
7258  },
7259
7260  removeProp: function( name ) {
7261    return this.each( function() {
7262      delete this[ jQuery.propFix[ name ] || name ];
7263    } );
7264  }
7265} );
7266
7267jQuery.extend( {
7268  prop: function( elem, name, value ) {
7269    var ret, hooks,
7270      nType = elem.nodeType;
7271
7272    // Don't get/set properties on text, comment and attribute nodes
7273    if ( nType === 3 || nType === 8 || nType === 2 ) {
7274      return;
7275    }
7276
7277    if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7278
7279      // Fix name and attach hooks
7280      name = jQuery.propFix[ name ] || name;
7281      hooks = jQuery.propHooks[ name ];
7282    }
7283
7284    if ( value !== undefined ) {
7285      if ( hooks && "set" in hooks &&
7286        ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7287        return ret;
7288      }
7289
7290      return ( elem[ name ] = value );
7291    }
7292
7293    if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7294      return ret;
7295    }
7296
7297    return elem[ name ];
7298  },
7299
7300  propHooks: {
7301    tabIndex: {
7302      get: function( elem ) {
7303
7304        // elem.tabIndex doesn't always return the
7305        // correct value when it hasn't been explicitly set
7306        // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7307        // Use proper attribute retrieval(#12072)
7308        var tabindex = jQuery.find.attr( elem, "tabindex" );
7309
7310        return tabindex ?
7311          parseInt( tabindex, 10 ) :
7312          rfocusable.test( elem.nodeName ) ||
7313            rclickable.test( elem.nodeName ) && elem.href ?
7314              0 :
7315              -1;
7316      }
7317    }
7318  },
7319
7320  propFix: {
7321    "for": "htmlFor",
7322    "class": "className"
7323  }
7324} );
7325
7326// Support: IE <=11 only
7327// Accessing the selectedIndex property
7328// forces the browser to respect setting selected
7329// on the option
7330// The getter ensures a default option is selected
7331// when in an optgroup
7332if ( !support.optSelected ) {
7333  jQuery.propHooks.selected = {
7334    get: function( elem ) {
7335      var parent = elem.parentNode;
7336      if ( parent && parent.parentNode ) {
7337        parent.parentNode.selectedIndex;
7338      }
7339      return null;
7340    },
7341    set: function( elem ) {
7342      var parent = elem.parentNode;
7343      if ( parent ) {
7344        parent.selectedIndex;
7345
7346        if ( parent.parentNode ) {
7347          parent.parentNode.selectedIndex;
7348        }
7349      }
7350    }
7351  };
7352}
7353
7354jQuery.each( [
7355  "tabIndex",
7356  "readOnly",
7357  "maxLength",
7358  "cellSpacing",
7359  "cellPadding",
7360  "rowSpan",
7361  "colSpan",
7362  "useMap",
7363  "frameBorder",
7364  "contentEditable"
7365], function() {
7366  jQuery.propFix[ this.toLowerCase() ] = this;
7367} );
7368
7369
7370
7371
7372var rclass = /[\t\r\n\f]/g;
7373
7374function getClass( elem ) {
7375  return elem.getAttribute && elem.getAttribute( "class" ) || "";
7376}
7377
7378jQuery.fn.extend( {
7379  addClass: function( value ) {
7380    var classes, elem, cur, curValue, clazz, j, finalValue,
7381      i = 0;
7382
7383    if ( jQuery.isFunction( value ) ) {
7384      return this.each( function( j ) {
7385        jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7386      } );
7387    }
7388
7389    if ( typeof value === "string" && value ) {
7390      classes = value.match( rnotwhite ) || [];
7391
7392      while ( ( elem = this[ i++ ] ) ) {
7393        curValue = getClass( elem );
7394        cur = elem.nodeType === 1 &&
7395          ( " " + curValue + " " ).replace( rclass, " " );
7396
7397        if ( cur ) {
7398          j = 0;
7399          while ( ( clazz = classes[ j++ ] ) ) {
7400            if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7401              cur += clazz + " ";
7402            }
7403          }
7404
7405          // Only assign if different to avoid unneeded rendering.
7406          finalValue = jQuery.trim( cur );
7407          if ( curValue !== finalValue ) {
7408            elem.setAttribute( "class", finalValue );
7409          }
7410        }
7411      }
7412    }
7413
7414    return this;
7415  },
7416
7417  removeClass: function( value ) {
7418    var classes, elem, cur, curValue, clazz, j, finalValue,
7419      i = 0;
7420
7421    if ( jQuery.isFunction( value ) ) {
7422      return this.each( function( j ) {
7423        jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7424      } );
7425    }
7426
7427    if ( !arguments.length ) {
7428      return this.attr( "class", "" );
7429    }
7430
7431    if ( typeof value === "string" && value ) {
7432      classes = value.match( rnotwhite ) || [];
7433
7434      while ( ( elem = this[ i++ ] ) ) {
7435        curValue = getClass( elem );
7436
7437        // This expression is here for better compressibility (see addClass)
7438        cur = elem.nodeType === 1 &&
7439          ( " " + curValue + " " ).replace( rclass, " " );
7440
7441        if ( cur ) {
7442          j = 0;
7443          while ( ( clazz = classes[ j++ ] ) ) {
7444
vendor: 4,149 bytes, lines 7445-7608
7445            // Remove *all* instances
7446            while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7447              cur = cur.replace( " " + clazz + " ", " " );
7448            }
7449          }
7450
7451          // Only assign if different to avoid unneeded rendering.
7452          finalValue = jQuery.trim( cur );
7453          if ( curValue !== finalValue ) {
7454            elem.setAttribute( "class", finalValue );
7455          }
7456        }
7457      }
7458    }
7459
7460    return this;
7461  },
7462
7463  toggleClass: function( value, stateVal ) {
7464    var type = typeof value;
7465
7466    if ( typeof stateVal === "boolean" && type === "string" ) {
7467      return stateVal ? this.addClass( value ) : this.removeClass( value );
7468    }
7469
7470    if ( jQuery.isFunction( value ) ) {
7471      return this.each( function( i ) {
7472        jQuery( this ).toggleClass(
7473          value.call( this, i, getClass( this ), stateVal ),
7474          stateVal
7475        );
7476      } );
7477    }
7478
7479    return this.each( function() {
7480      var className, i, self, classNames;
7481
7482      if ( type === "string" ) {
7483
7484        // Toggle individual class names
7485        i = 0;
7486        self = jQuery( this );
7487        classNames = value.match( rnotwhite ) || [];
7488
7489        while ( ( className = classNames[ i++ ] ) ) {
7490
7491          // Check each className given, space separated list
7492          if ( self.hasClass( className ) ) {
7493            self.removeClass( className );
7494          } else {
7495            self.addClass( className );
7496          }
7497        }
7498
7499      // Toggle whole class name
7500      } else if ( value === undefined || type === "boolean" ) {
7501        className = getClass( this );
7502        if ( className ) {
7503
7504          // Store className if set
7505          dataPriv.set( this, "__className__", className );
7506        }
7507
7508        // If the element has a class name or if we're passed `false`,
7509        // then remove the whole classname (if there was one, the above saved it).
7510        // Otherwise bring back whatever was previously saved (if anything),
7511        // falling back to the empty string if nothing was stored.
7512        if ( this.setAttribute ) {
7513          this.setAttribute( "class",
7514            className || value === false ?
7515            "" :
7516            dataPriv.get( this, "__className__" ) || ""
7517          );
7518        }
7519      }
7520    } );
7521  },
7522
7523  hasClass: function( selector ) {
7524    var className, elem,
7525      i = 0;
7526
7527    className = " " + selector + " ";
7528    while ( ( elem = this[ i++ ] ) ) {
7529      if ( elem.nodeType === 1 &&
7530        ( " " + getClass( elem ) + " " ).replace( rclass, " " )
7531          .indexOf( className ) > -1
7532      ) {
7533        return true;
7534      }
7535    }
7536
7537    return false;
7538  }
7539} );
7540
7541
7542
7543
7544var rreturn = /\r/g,
7545  rspaces = /[\x20\t\r\n\f]+/g;
7546
7547jQuery.fn.extend( {
7548  val: function( value ) {
7549    var hooks, ret, isFunction,
7550      elem = this[ 0 ];
7551
7552    if ( !arguments.length ) {
7553      if ( elem ) {
7554        hooks = jQuery.valHooks[ elem.type ] ||
7555          jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7556
7557        if ( hooks &&
7558          "get" in hooks &&
7559          ( ret = hooks.get( elem, "value" ) ) !== undefined
7560        ) {
7561          return ret;
7562        }
7563
7564        ret = elem.value;
7565
7566        return typeof ret === "string" ?
7567
7568          // Handle most common string cases
7569          ret.replace( rreturn, "" ) :
7570
7571          // Handle cases where value is null/undef or number
7572          ret == null ? "" : ret;
7573      }
7574
7575      return;
7576    }
7577
7578    isFunction = jQuery.isFunction( value );
7579
7580    return this.each( function( i ) {
7581      var val;
7582
7583      if ( this.nodeType !== 1 ) {
7584        return;
7585      }
7586
7587      if ( isFunction ) {
7588        val = value.call( this, i, jQuery( this ).val() );
7589      } else {
7590        val = value;
7591      }
7592
7593      // Treat null/undefined as ""; convert numbers to string
7594      if ( val == null ) {
7595        val = "";
7596
7597      } else if ( typeof val === "number" ) {
7598        val += "";
7599
7600      } else if ( jQuery.isArray( val ) ) {
7601        val = jQuery.map( val, function( value ) {
7602          return value == null ? "" : value + "";
7603        } );
7604      }
7605
7606      hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7607
7608      // If set returns undefined, fall back to normal setting
vendor: 4,403 bytes, lines 7609-7759
7609      if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
7610        this.value = val;
7611      }
7612    } );
7613  }
7614} );
7615
7616jQuery.extend( {
7617  valHooks: {
7618    option: {
7619      get: function( elem ) {
7620
7621        var val = jQuery.find.attr( elem, "value" );
7622        return val != null ?
7623          val :
7624
7625          // Support: IE10-11+
7626          // option.text throws exceptions (#14686, #14858)
7627          // Strip and collapse whitespace
7628          // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
7629          jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
7630      }
7631    },
7632    select: {
7633      get: function( elem ) {
7634        var value, option,
7635          options = elem.options,
7636          index = elem.selectedIndex,
7637          one = elem.type === "select-one" || index < 0,
7638          values = one ? null : [],
7639          max = one ? index + 1 : options.length,
7640          i = index < 0 ?
7641            max :
7642            one ? index : 0;
7643
7644        // Loop through all the selected options
7645        for ( ; i < max; i++ ) {
7646          option = options[ i ];
7647
7648          // IE8-9 doesn't update selected after form reset (#2551)
7649          if ( ( option.selected || i === index ) &&
7650
7651              // Don't return options that are disabled or in a disabled optgroup
7652              ( support.optDisabled ?
7653                !option.disabled : option.getAttribute( "disabled" ) === null ) &&
7654              ( !option.parentNode.disabled ||
7655                !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7656
7657            // Get the specific value for the option
7658            value = jQuery( option ).val();
7659
7660            // We don't need an array for one selects
7661            if ( one ) {
7662              return value;
7663            }
7664
7665            // Multi-Selects return an array
7666            values.push( value );
7667          }
7668        }
7669
7670        return values;
7671      },
7672
7673      set: function( elem, value ) {
7674        var optionSet, option,
7675          options = elem.options,
7676          values = jQuery.makeArray( value ),
7677          i = options.length;
7678
7679        while ( i-- ) {
7680          option = options[ i ];
7681          if ( option.selected =
7682            jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
7683          ) {
7684            optionSet = true;
7685          }
7686        }
7687
7688        // Force browsers to behave consistently when non-matching value is set
7689        if ( !optionSet ) {
7690          elem.selectedIndex = -1;
7691        }
7692        return values;
7693      }
7694    }
7695  }
7696} );
7697
7698// Radios and checkboxes getter/setter
7699jQuery.each( [ "radio", "checkbox" ], function() {
7700  jQuery.valHooks[ this ] = {
7701    set: function( elem, value ) {
7702      if ( jQuery.isArray( value ) ) {
7703        return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
7704      }
7705    }
7706  };
7707  if ( !support.checkOn ) {
7708    jQuery.valHooks[ this ].get = function( elem ) {
7709      return elem.getAttribute( "value" ) === null ? "on" : elem.value;
7710    };
7711  }
7712} );
7713
7714
7715
7716
7717// Return jQuery for attributes-only inclusion
7718
7719
7720var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
7721
7722jQuery.extend( jQuery.event, {
7723
7724  trigger: function( event, data, elem, onlyHandlers ) {
7725
7726    var i, cur, tmp, bubbleType, ontype, handle, special,
7727      eventPath = [ elem || document ],
7728      type = hasOwn.call( event, "type" ) ? event.type : event,
7729      namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
7730
7731    cur = tmp = elem = elem || document;
7732
7733    // Don't do events on text and comment nodes
7734    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
7735      return;
7736    }
7737
7738    // focus/blur morphs to focusin/out; ensure we're not firing them right now
7739    if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
7740      return;
7741    }
7742
7743    if ( type.indexOf( "." ) > -1 ) {
7744
7745      // Namespaced trigger; create a regexp to match event type in handle()
7746      namespaces = type.split( "." );
7747      type = namespaces.shift();
7748      namespaces.sort();
7749    }
7750    ontype = type.indexOf( ":" ) < 0 && "on" + type;
7751
7752    // Caller can pass in a jQuery.Event object, Object, or just an event type string
7753    event = event[ jQuery.expando ] ?
7754      event :
7755      new jQuery.Event( type, typeof event === "object" && event );
7756
7757    // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
7758    event.isTrigger = onlyHandlers ? 2 : 3;
7759    event.namespace = namespaces.join( "." );
vendor: 4,486 bytes, lines 7760-7918
7760    event.rnamespace = event.namespace ?
7761      new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
7762      null;
7763
7764    // Clean up the event in case it is being reused
7765    event.result = undefined;
7766    if ( !event.target ) {
7767      event.target = elem;
7768    }
7769
7770    // Clone any incoming data and prepend the event, creating the handler arg list
7771    data = data == null ?
7772      [ event ] :
7773      jQuery.makeArray( data, [ event ] );
7774
7775    // Allow special events to draw outside the lines
7776    special = jQuery.event.special[ type ] || {};
7777    if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
7778      return;
7779    }
7780
7781    // Determine event propagation path in advance, per W3C events spec (#9951)
7782    // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
7783    if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
7784
7785      bubbleType = special.delegateType || type;
7786      if ( !rfocusMorph.test( bubbleType + type ) ) {
7787        cur = cur.parentNode;
7788      }
7789      for ( ; cur; cur = cur.parentNode ) {
7790        eventPath.push( cur );
7791        tmp = cur;
7792      }
7793
7794      // Only add window if we got to document (e.g., not plain obj or detached DOM)
7795      if ( tmp === ( elem.ownerDocument || document ) ) {
7796        eventPath.push( tmp.defaultView || tmp.parentWindow || window );
7797      }
7798    }
7799
7800    // Fire handlers on the event path
7801    i = 0;
7802    while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
7803
7804      event.type = i > 1 ?
7805        bubbleType :
7806        special.bindType || type;
7807
7808      // jQuery handler
7809      handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
7810        dataPriv.get( cur, "handle" );
7811      if ( handle ) {
7812        handle.apply( cur, data );
7813      }
7814
7815      // Native handler
7816      handle = ontype && cur[ ontype ];
7817      if ( handle && handle.apply && acceptData( cur ) ) {
7818        event.result = handle.apply( cur, data );
7819        if ( event.result === false ) {
7820          event.preventDefault();
7821        }
7822      }
7823    }
7824    event.type = type;
7825
7826    // If nobody prevented the default action, do it now
7827    if ( !onlyHandlers && !event.isDefaultPrevented() ) {
7828
7829      if ( ( !special._default ||
7830        special._default.apply( eventPath.pop(), data ) === false ) &&
7831        acceptData( elem ) ) {
7832
7833        // Call a native DOM method on the target with the same name name as the event.
7834        // Don't do default actions on window, that's where global variables be (#6170)
7835        if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
7836
7837          // Don't re-trigger an onFOO event when we call its FOO() method
7838          tmp = elem[ ontype ];
7839
7840          if ( tmp ) {
7841            elem[ ontype ] = null;
7842          }
7843
7844          // Prevent re-triggering of the same event, since we already bubbled it above
7845          jQuery.event.triggered = type;
7846          elem[ type ]();
7847          jQuery.event.triggered = undefined;
7848
7849          if ( tmp ) {
7850            elem[ ontype ] = tmp;
7851          }
7852        }
7853      }
7854    }
7855
7856    return event.result;
7857  },
7858
7859  // Piggyback on a donor event to simulate a different one
7860  // Used only for `focus(in | out)` events
7861  simulate: function( type, elem, event ) {
7862    var e = jQuery.extend(
7863      new jQuery.Event(),
7864      event,
7865      {
7866        type: type,
7867        isSimulated: true
7868      }
7869    );
7870
7871    jQuery.event.trigger( e, null, elem );
7872  }
7873
7874} );
7875
7876jQuery.fn.extend( {
7877
7878  trigger: function( type, data ) {
7879    return this.each( function() {
7880      jQuery.event.trigger( type, data, this );
7881    } );
7882  },
7883  triggerHandler: function( type, data ) {
7884    var elem = this[ 0 ];
7885    if ( elem ) {
7886      return jQuery.event.trigger( type, data, elem, true );
7887    }
7888  }
7889} );
7890
7891
7892jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
7893  "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7894  "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
7895  function( i, name ) {
7896
7897  // Handle event binding
7898  jQuery.fn[ name ] = function( data, fn ) {
7899    return arguments.length > 0 ?
7900      this.on( name, null, data, fn ) :
7901      this.trigger( name );
7902  };
7903} );
7904
7905jQuery.fn.extend( {
7906  hover: function( fnOver, fnOut ) {
7907    return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7908  }
7909} );
7910
7911
7912
7913
7914support.focusin = "onfocusin" in window;
7915
7916
7917// Support: Firefox
7918// Firefox doesn't have focus(in | out) events
vendor: 4,867 bytes, lines 7919-8079
7919// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
7920//
7921// Support: Chrome, Safari
7922// focus(in | out) events fire after focus & blur events,
7923// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
7924// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
7925if ( !support.focusin ) {
7926  jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
7927
7928    // Attach a single capturing handler on the document while someone wants focusin/focusout
7929    var handler = function( event ) {
7930      jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
7931    };
7932
7933    jQuery.event.special[ fix ] = {
7934      setup: function() {
7935        var doc = this.ownerDocument || this,
7936          attaches = dataPriv.access( doc, fix );
7937
7938        if ( !attaches ) {
7939          doc.addEventListener( orig, handler, true );
7940        }
7941        dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
7942      },
7943      teardown: function() {
7944        var doc = this.ownerDocument || this,
7945          attaches = dataPriv.access( doc, fix ) - 1;
7946
7947        if ( !attaches ) {
7948          doc.removeEventListener( orig, handler, true );
7949          dataPriv.remove( doc, fix );
7950
7951        } else {
7952          dataPriv.access( doc, fix, attaches );
7953        }
7954      }
7955    };
7956  } );
7957}
7958var location = window.location;
7959
7960var nonce = jQuery.now();
7961
7962var rquery = ( /\?/ );
7963
7964
7965
7966// Support: Android 2.3
7967// Workaround failure to string-cast null input
7968jQuery.parseJSON = function( data ) {
7969  return JSON.parse( data + "" );
7970};
7971
7972
7973// Cross-browser xml parsing
7974jQuery.parseXML = function( data ) {
7975  var xml;
7976  if ( !data || typeof data !== "string" ) {
7977    return null;
7978  }
7979
7980  // Support: IE9
7981  try {
7982    xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
7983  } catch ( e ) {
7984    xml = undefined;
7985  }
7986
7987  if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7988    jQuery.error( "Invalid XML: " + data );
7989  }
7990  return xml;
7991};
7992
7993
7994var
7995  rhash = /#.*$/,
7996  rts = /([?&])_=[^&]*/,
7997  rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7998
7999  // #7653, #8125, #8152: local protocol detection
8000  rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8001  rnoContent = /^(?:GET|HEAD)$/,
8002  rprotocol = /^\/\//,
8003
8004  /* Prefilters
8005   * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8006   * 2) These are called:
8007   *    - BEFORE asking for a transport
8008   *    - AFTER param serialization (s.data is a string if s.processData is true)
8009   * 3) key is the dataType
8010   * 4) the catchall symbol "*" can be used
8011   * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8012   */
8013  prefilters = {},
8014
8015  /* Transports bindings
8016   * 1) key is the dataType
8017   * 2) the catchall symbol "*" can be used
8018   * 3) selection will start with transport dataType and THEN go to "*" if needed
8019   */
8020  transports = {},
8021
8022  // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8023  allTypes = "*/".concat( "*" ),
8024
8025  // Anchor tag for parsing the document origin
8026  originAnchor = document.createElement( "a" );
8027  originAnchor.href = location.href;
8028
8029// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8030function addToPrefiltersOrTransports( structure ) {
8031
8032  // dataTypeExpression is optional and defaults to "*"
8033  return function( dataTypeExpression, func ) {
8034
8035    if ( typeof dataTypeExpression !== "string" ) {
8036      func = dataTypeExpression;
8037      dataTypeExpression = "*";
8038    }
8039
8040    var dataType,
8041      i = 0,
8042      dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8043
8044    if ( jQuery.isFunction( func ) ) {
8045
8046      // For each dataType in the dataTypeExpression
8047      while ( ( dataType = dataTypes[ i++ ] ) ) {
8048
8049        // Prepend if requested
8050        if ( dataType[ 0 ] === "+" ) {
8051          dataType = dataType.slice( 1 ) || "*";
8052          ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8053
8054        // Otherwise append
8055        } else {
8056          ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8057        }
8058      }
8059    }
8060  };
8061}
8062
8063// Base inspection function for prefilters and transports
8064function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8065
8066  var inspected = {},
8067    seekingTransport = ( structure === transports );
8068
8069  function inspect( dataType ) {
8070    var selected;
8071    inspected[ dataType ] = true;
8072    jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8073      var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8074      if ( typeof dataTypeOrTransport === "string" &&
8075        !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8076
8077        options.dataTypes.unshift( dataTypeOrTransport );
8078        inspect( dataTypeOrTransport );
8079        return false;
vendor: 5,598 bytes, lines 8080-8290
8080      } else if ( seekingTransport ) {
8081        return !( selected = dataTypeOrTransport );
8082      }
8083    } );
8084    return selected;
8085  }
8086
8087  return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8088}
8089
8090// A special extend for ajax options
8091// that takes "flat" options (not to be deep extended)
8092// Fixes #9887
8093function ajaxExtend( target, src ) {
8094  var key, deep,
8095    flatOptions = jQuery.ajaxSettings.flatOptions || {};
8096
8097  for ( key in src ) {
8098    if ( src[ key ] !== undefined ) {
8099      ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8100    }
8101  }
8102  if ( deep ) {
8103    jQuery.extend( true, target, deep );
8104  }
8105
8106  return target;
8107}
8108
8109/* Handles responses to an ajax request:
8110 * - finds the right dataType (mediates between content-type and expected dataType)
8111 * - returns the corresponding response
8112 */
8113function ajaxHandleResponses( s, jqXHR, responses ) {
8114
8115  var ct, type, finalDataType, firstDataType,
8116    contents = s.contents,
8117    dataTypes = s.dataTypes;
8118
8119  // Remove auto dataType and get content-type in the process
8120  while ( dataTypes[ 0 ] === "*" ) {
8121    dataTypes.shift();
8122    if ( ct === undefined ) {
8123      ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8124    }
8125  }
8126
8127  // Check if we're dealing with a known content-type
8128  if ( ct ) {
8129    for ( type in contents ) {
8130      if ( contents[ type ] && contents[ type ].test( ct ) ) {
8131        dataTypes.unshift( type );
8132        break;
8133      }
8134    }
8135  }
8136
8137  // Check to see if we have a response for the expected dataType
8138  if ( dataTypes[ 0 ] in responses ) {
8139    finalDataType = dataTypes[ 0 ];
8140  } else {
8141
8142    // Try convertible dataTypes
8143    for ( type in responses ) {
8144      if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8145        finalDataType = type;
8146        break;
8147      }
8148      if ( !firstDataType ) {
8149        firstDataType = type;
8150      }
8151    }
8152
8153    // Or just use first one
8154    finalDataType = finalDataType || firstDataType;
8155  }
8156
8157  // If we found a dataType
8158  // We add the dataType to the list if needed
8159  // and return the corresponding response
8160  if ( finalDataType ) {
8161    if ( finalDataType !== dataTypes[ 0 ] ) {
8162      dataTypes.unshift( finalDataType );
8163    }
8164    return responses[ finalDataType ];
8165  }
8166}
8167
8168/* Chain conversions given the request and the original response
8169 * Also sets the responseXXX fields on the jqXHR instance
8170 */
8171function ajaxConvert( s, response, jqXHR, isSuccess ) {
8172  var conv2, current, conv, tmp, prev,
8173    converters = {},
8174
8175    // Work with a copy of dataTypes in case we need to modify it for conversion
8176    dataTypes = s.dataTypes.slice();
8177
8178  // Create converters map with lowercased keys
8179  if ( dataTypes[ 1 ] ) {
8180    for ( conv in s.converters ) {
8181      converters[ conv.toLowerCase() ] = s.converters[ conv ];
8182    }
8183  }
8184
8185  current = dataTypes.shift();
8186
8187  // Convert to each sequential dataType
8188  while ( current ) {
8189
8190    if ( s.responseFields[ current ] ) {
8191      jqXHR[ s.responseFields[ current ] ] = response;
8192    }
8193
8194    // Apply the dataFilter if provided
8195    if ( !prev && isSuccess && s.dataFilter ) {
8196      response = s.dataFilter( response, s.dataType );
8197    }
8198
8199    prev = current;
8200    current = dataTypes.shift();
8201
8202    if ( current ) {
8203
8204    // There's only work to do if current dataType is non-auto
8205      if ( current === "*" ) {
8206
8207        current = prev;
8208
8209      // Convert response if prev dataType is non-auto and differs from current
8210      } else if ( prev !== "*" && prev !== current ) {
8211
8212        // Seek a direct converter
8213        conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8214
8215        // If none found, seek a pair
8216        if ( !conv ) {
8217          for ( conv2 in converters ) {
8218
8219            // If conv2 outputs current
8220            tmp = conv2.split( " " );
8221            if ( tmp[ 1 ] === current ) {
8222
8223              // If prev can be converted to accepted input
8224              conv = converters[ prev + " " + tmp[ 0 ] ] ||
8225                converters[ "* " + tmp[ 0 ] ];
8226              if ( conv ) {
8227
8228                // Condense equivalence converters
8229                if ( conv === true ) {
8230                  conv = converters[ conv2 ];
8231
8232                // Otherwise, insert the intermediate dataType
8233                } else if ( converters[ conv2 ] !== true ) {
8234                  current = tmp[ 0 ];
8235                  dataTypes.unshift( tmp[ 1 ] );
8236                }
8237                break;
8238              }
8239            }
8240          }
8241        }
8242
8243        // Apply converter (if not an equivalence)
8244        if ( conv !== true ) {
8245
8246          // Unless errors are allowed to bubble, catch and return them
8247          if ( conv && s.throws ) {
8248            response = conv( response );
8249          } else {
8250            try {
8251              response = conv( response );
8252            } catch ( e ) {
8253              return {
8254                state: "parsererror",
8255                error: conv ? e : "No conversion from " + prev + " to " + current
8256              };
8257            }
8258          }
8259        }
8260      }
8261    }
8262  }
8263
8264  return { state: "success", data: response };
8265}
8266
8267jQuery.extend( {
8268
8269  // Counter for holding the number of active queries
8270  active: 0,
8271
8272  // Last-Modified header cache for next request
8273  lastModified: {},
8274  etag: {},
8275
8276  ajaxSettings: {
8277    url: location.href,
8278    type: "GET",
8279    isLocal: rlocalProtocol.test( location.protocol ),
8280    global: true,
8281    processData: true,
8282    async: true,
8283    contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8284    /*
8285    timeout: 0,
8286    data: null,
8287    dataType: null,
8288    username: null,
8289    password: null,
8290    cache: null,
vendor: 45,726 bytes, lines 8291-9883
8291    throws: false,
8292    traditional: false,
8293    headers: {},
8294    */
8295
8296    accepts: {
8297      "*": allTypes,
8298      text: "text/plain",
8299      html: "text/html",
8300      xml: "application/xml, text/xml",
8301      json: "application/json, text/javascript"
8302    },
8303
8304    contents: {
8305      xml: /\bxml\b/,
8306      html: /\bhtml/,
8307      json: /\bjson\b/
8308    },
8309
8310    responseFields: {
8311      xml: "responseXML",
8312      text: "responseText",
8313      json: "responseJSON"
8314    },
8315
8316    // Data converters
8317    // Keys separate source (or catchall "*") and destination types with a single space
8318    converters: {
8319
8320      // Convert anything to text
8321      "* text": String,
8322
8323      // Text to html (true = no transformation)
8324      "text html": true,
8325
8326      // Evaluate text as a json expression
8327      "text json": jQuery.parseJSON,
8328
8329      // Parse text as xml
8330      "text xml": jQuery.parseXML
8331    },
8332
8333    // For options that shouldn't be deep extended:
8334    // you can add your own custom options here if
8335    // and when you create one that shouldn't be
8336    // deep extended (see ajaxExtend)
8337    flatOptions: {
8338      url: true,
8339      context: true
8340    }
8341  },
8342
8343  // Creates a full fledged settings object into target
8344  // with both ajaxSettings and settings fields.
8345  // If target is omitted, writes into ajaxSettings.
8346  ajaxSetup: function( target, settings ) {
8347    return settings ?
8348
8349      // Building a settings object
8350      ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8351
8352      // Extending ajaxSettings
8353      ajaxExtend( jQuery.ajaxSettings, target );
8354  },
8355
8356  ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8357  ajaxTransport: addToPrefiltersOrTransports( transports ),
8358
8359  // Main method
8360  ajax: function( url, options ) {
8361
8362    // If url is an object, simulate pre-1.5 signature
8363    if ( typeof url === "object" ) {
8364      options = url;
8365      url = undefined;
8366    }
8367
8368    // Force options to be an object
8369    options = options || {};
8370
8371    var transport,
8372
8373      // URL without anti-cache param
8374      cacheURL,
8375
8376      // Response headers
8377      responseHeadersString,
8378      responseHeaders,
8379
8380      // timeout handle
8381      timeoutTimer,
8382
8383      // Url cleanup var
8384      urlAnchor,
8385
8386      // To know if global events are to be dispatched
8387      fireGlobals,
8388
8389      // Loop variable
8390      i,
8391
8392      // Create the final options object
8393      s = jQuery.ajaxSetup( {}, options ),
8394
8395      // Callbacks context
8396      callbackContext = s.context || s,
8397
8398      // Context for global events is callbackContext if it is a DOM node or jQuery collection
8399      globalEventContext = s.context &&
8400        ( callbackContext.nodeType || callbackContext.jquery ) ?
8401          jQuery( callbackContext ) :
8402          jQuery.event,
8403
8404      // Deferreds
8405      deferred = jQuery.Deferred(),
8406      completeDeferred = jQuery.Callbacks( "once memory" ),
8407
8408      // Status-dependent callbacks
8409      statusCode = s.statusCode || {},
8410
8411      // Headers (they are sent all at once)
8412      requestHeaders = {},
8413      requestHeadersNames = {},
8414
8415      // The jqXHR state
8416      state = 0,
8417
8418      // Default abort message
8419      strAbort = "canceled",
8420
8421      // Fake xhr
8422      jqXHR = {
8423        readyState: 0,
8424
8425        // Builds headers hashtable if needed
8426        getResponseHeader: function( key ) {
8427          var match;
8428          if ( state === 2 ) {
8429            if ( !responseHeaders ) {
8430              responseHeaders = {};
8431              while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8432                responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8433              }
8434            }
8435            match = responseHeaders[ key.toLowerCase() ];
8436          }
8437          return match == null ? null : match;
8438        },
8439
8440        // Raw string
8441        getAllResponseHeaders: function() {
8442          return state === 2 ? responseHeadersString : null;
8443        },
8444
8445        // Caches the header
8446        setRequestHeader: function( name, value ) {
8447          var lname = name.toLowerCase();
8448          if ( !state ) {
8449            name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
8450            requestHeaders[ name ] = value;
8451          }
8452          return this;
8453        },
8454
8455        // Overrides response content-type header
8456        overrideMimeType: function( type ) {
8457          if ( !state ) {
8458            s.mimeType = type;
8459          }
8460          return this;
8461        },
8462
8463        // Status-dependent callbacks
8464        statusCode: function( map ) {
8465          var code;
8466          if ( map ) {
8467            if ( state < 2 ) {
8468              for ( code in map ) {
8469
8470                // Lazy-add the new callback in a way that preserves old ones
8471                statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8472              }
8473            } else {
8474
8475              // Execute the appropriate callbacks
8476              jqXHR.always( map[ jqXHR.status ] );
8477            }
8478          }
8479          return this;
8480        },
8481
8482        // Cancel the request
8483        abort: function( statusText ) {
8484          var finalText = statusText || strAbort;
8485          if ( transport ) {
8486            transport.abort( finalText );
8487          }
8488          done( 0, finalText );
8489          return this;
8490        }
8491      };
8492
8493    // Attach deferreds
8494    deferred.promise( jqXHR ).complete = completeDeferred.add;
8495    jqXHR.success = jqXHR.done;
8496    jqXHR.error = jqXHR.fail;
8497
8498    // Remove hash character (#7531: and string promotion)
8499    // Add protocol if not provided (prefilters might expect it)
8500    // Handle falsy url in the settings object (#10093: consistency with old signature)
8501    // We also use the url parameter if available
8502    s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
8503      .replace( rprotocol, location.protocol + "//" );
8504
8505    // Alias method option to type as per ticket #12004
8506    s.type = options.method || options.type || s.method || s.type;
8507
8508    // Extract dataTypes list
8509    s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8510
8511    // A cross-domain request is in order when the origin doesn't match the current origin.
8512    if ( s.crossDomain == null ) {
8513      urlAnchor = document.createElement( "a" );
8514
8515      // Support: IE8-11+
8516      // IE throws exception if url is malformed, e.g. http://example.com:80x/
8517      try {
8518        urlAnchor.href = s.url;
8519
8520        // Support: IE8-11+
8521        // Anchor's host property isn't correctly set when s.url is relative
8522        urlAnchor.href = urlAnchor.href;
8523        s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
8524          urlAnchor.protocol + "//" + urlAnchor.host;
8525      } catch ( e ) {
8526
8527        // If there is an error parsing the URL, assume it is crossDomain,
8528        // it can be rejected by the transport if it is invalid
8529        s.crossDomain = true;
8530      }
8531    }
8532
8533    // Convert data if not already a string
8534    if ( s.data && s.processData && typeof s.data !== "string" ) {
8535      s.data = jQuery.param( s.data, s.traditional );
8536    }
8537
8538    // Apply prefilters
8539    inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8540
8541    // If request was aborted inside a prefilter, stop there
8542    if ( state === 2 ) {
8543      return jqXHR;
8544    }
8545
8546    // We can fire global events as of now if asked to
8547    // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8548    fireGlobals = jQuery.event && s.global;
8549
8550    // Watch for a new set of requests
8551    if ( fireGlobals && jQuery.active++ === 0 ) {
8552      jQuery.event.trigger( "ajaxStart" );
8553    }
8554
8555    // Uppercase the type
8556    s.type = s.type.toUpperCase();
8557
8558    // Determine if request has content
8559    s.hasContent = !rnoContent.test( s.type );
8560
8561    // Save the URL in case we're toying with the If-Modified-Since
8562    // and/or If-None-Match header later on
8563    cacheURL = s.url;
8564
8565    // More options handling for requests with no content
8566    if ( !s.hasContent ) {
8567
8568      // If data is available, append data to url
8569      if ( s.data ) {
8570        cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8571
8572        // #9682: remove data so that it's not used in an eventual retry
8573        delete s.data;
8574      }
8575
8576      // Add anti-cache in url if needed
8577      if ( s.cache === false ) {
8578        s.url = rts.test( cacheURL ) ?
8579
8580          // If there is already a '_' parameter, set its value
8581          cacheURL.replace( rts, "$1_=" + nonce++ ) :
8582
8583          // Otherwise add one to the end
8584          cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8585      }
8586    }
8587
8588    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8589    if ( s.ifModified ) {
8590      if ( jQuery.lastModified[ cacheURL ] ) {
8591        jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8592      }
8593      if ( jQuery.etag[ cacheURL ] ) {
8594        jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8595      }
8596    }
8597
8598    // Set the correct header, if data is being sent
8599    if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8600      jqXHR.setRequestHeader( "Content-Type", s.contentType );
8601    }
8602
8603    // Set the Accepts header for the server, depending on the dataType
8604    jqXHR.setRequestHeader(
8605      "Accept",
8606      s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
8607        s.accepts[ s.dataTypes[ 0 ] ] +
8608          ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8609        s.accepts[ "*" ]
8610    );
8611
8612    // Check for headers option
8613    for ( i in s.headers ) {
8614      jqXHR.setRequestHeader( i, s.headers[ i ] );
8615    }
8616
8617    // Allow custom headers/mimetypes and early abort
8618    if ( s.beforeSend &&
8619      ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8620
8621      // Abort if not done already and return
8622      return jqXHR.abort();
8623    }
8624
8625    // Aborting is no longer a cancellation
8626    strAbort = "abort";
8627
8628    // Install callbacks on deferreds
8629    for ( i in { success: 1, error: 1, complete: 1 } ) {
8630      jqXHR[ i ]( s[ i ] );
8631    }
8632
8633    // Get transport
8634    transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8635
8636    // If no transport, we auto-abort
8637    if ( !transport ) {
8638      done( -1, "No Transport" );
8639    } else {
8640      jqXHR.readyState = 1;
8641
8642      // Send global event
8643      if ( fireGlobals ) {
8644        globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8645      }
8646
8647      // If request was aborted inside ajaxSend, stop there
8648      if ( state === 2 ) {
8649        return jqXHR;
8650      }
8651
8652      // Timeout
8653      if ( s.async && s.timeout > 0 ) {
8654        timeoutTimer = window.setTimeout( function() {
8655          jqXHR.abort( "timeout" );
8656        }, s.timeout );
8657      }
8658
8659      try {
8660        state = 1;
8661        transport.send( requestHeaders, done );
8662      } catch ( e ) {
8663
8664        // Propagate exception as error if not done
8665        if ( state < 2 ) {
8666          done( -1, e );
8667
8668        // Simply rethrow otherwise
8669        } else {
8670          throw e;
8671        }
8672      }
8673    }
8674
8675    // Callback for when everything is done
8676    function done( status, nativeStatusText, responses, headers ) {
8677      var isSuccess, success, error, response, modified,
8678        statusText = nativeStatusText;
8679
8680      // Called once
8681      if ( state === 2 ) {
8682        return;
8683      }
8684
8685      // State is "done" now
8686      state = 2;
8687
8688      // Clear timeout if it exists
8689      if ( timeoutTimer ) {
8690        window.clearTimeout( timeoutTimer );
8691      }
8692
8693      // Dereference transport for early garbage collection
8694      // (no matter how long the jqXHR object will be used)
8695      transport = undefined;
8696
8697      // Cache response headers
8698      responseHeadersString = headers || "";
8699
8700      // Set readyState
8701      jqXHR.readyState = status > 0 ? 4 : 0;
8702
8703      // Determine if successful
8704      isSuccess = status >= 200 && status < 300 || status === 304;
8705
8706      // Get response data
8707      if ( responses ) {
8708        response = ajaxHandleResponses( s, jqXHR, responses );
8709      }
8710
8711      // Convert no matter what (that way responseXXX fields are always set)
8712      response = ajaxConvert( s, response, jqXHR, isSuccess );
8713
8714      // If successful, handle type chaining
8715      if ( isSuccess ) {
8716
8717        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8718        if ( s.ifModified ) {
8719          modified = jqXHR.getResponseHeader( "Last-Modified" );
8720          if ( modified ) {
8721            jQuery.lastModified[ cacheURL ] = modified;
8722          }
8723          modified = jqXHR.getResponseHeader( "etag" );
8724          if ( modified ) {
8725            jQuery.etag[ cacheURL ] = modified;
8726          }
8727        }
8728
8729        // if no content
8730        if ( status === 204 || s.type === "HEAD" ) {
8731          statusText = "nocontent";
8732
8733        // if not modified
8734        } else if ( status === 304 ) {
8735          statusText = "notmodified";
8736
8737        // If we have data, let's convert it
8738        } else {
8739          statusText = response.state;
8740          success = response.data;
8741          error = response.error;
8742          isSuccess = !error;
8743        }
8744      } else {
8745
8746        // Extract error from statusText and normalize for non-aborts
8747        error = statusText;
8748        if ( status || !statusText ) {
8749          statusText = "error";
8750          if ( status < 0 ) {
8751            status = 0;
8752          }
8753        }
8754      }
8755
8756      // Set data for the fake xhr object
8757      jqXHR.status = status;
8758      jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8759
8760      // Success/Error
8761      if ( isSuccess ) {
8762        deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8763      } else {
8764        deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8765      }
8766
8767      // Status-dependent callbacks
8768      jqXHR.statusCode( statusCode );
8769      statusCode = undefined;
8770
8771      if ( fireGlobals ) {
8772        globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8773          [ jqXHR, s, isSuccess ? success : error ] );
8774      }
8775
8776      // Complete
8777      completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8778
8779      if ( fireGlobals ) {
8780        globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8781
8782        // Handle the global AJAX counter
8783        if ( !( --jQuery.active ) ) {
8784          jQuery.event.trigger( "ajaxStop" );
8785        }
8786      }
8787    }
8788
8789    return jqXHR;
8790  },
8791
8792  getJSON: function( url, data, callback ) {
8793    return jQuery.get( url, data, callback, "json" );
8794  },
8795
8796  getScript: function( url, callback ) {
8797    return jQuery.get( url, undefined, callback, "script" );
8798  }
8799} );
8800
8801jQuery.each( [ "get", "post" ], function( i, method ) {
8802  jQuery[ method ] = function( url, data, callback, type ) {
8803
8804    // Shift arguments if data argument was omitted
8805    if ( jQuery.isFunction( data ) ) {
8806      type = type || callback;
8807      callback = data;
8808      data = undefined;
8809    }
8810
8811    // The url can be an options object (which then must have .url)
8812    return jQuery.ajax( jQuery.extend( {
8813      url: url,
8814      type: method,
8815      dataType: type,
8816      data: data,
8817      success: callback
8818    }, jQuery.isPlainObject( url ) && url ) );
8819  };
8820} );
8821
8822
8823jQuery._evalUrl = function( url ) {
8824  return jQuery.ajax( {
8825    url: url,
8826
8827    // Make this explicit, since user can override this through ajaxSetup (#11264)
8828    type: "GET",
8829    dataType: "script",
8830    async: false,
8831    global: false,
8832    "throws": true
8833  } );
8834};
8835
8836
8837jQuery.fn.extend( {
8838  wrapAll: function( html ) {
8839    var wrap;
8840
8841    if ( jQuery.isFunction( html ) ) {
8842      return this.each( function( i ) {
8843        jQuery( this ).wrapAll( html.call( this, i ) );
8844      } );
8845    }
8846
8847    if ( this[ 0 ] ) {
8848
8849      // The elements to wrap the target around
8850      wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8851
8852      if ( this[ 0 ].parentNode ) {
8853        wrap.insertBefore( this[ 0 ] );
8854      }
8855
8856      wrap.map( function() {
8857        var elem = this;
8858
8859        while ( elem.firstElementChild ) {
8860          elem = elem.firstElementChild;
8861        }
8862
8863        return elem;
8864      } ).append( this );
8865    }
8866
8867    return this;
8868  },
8869
8870  wrapInner: function( html ) {
8871    if ( jQuery.isFunction( html ) ) {
8872      return this.each( function( i ) {
8873        jQuery( this ).wrapInner( html.call( this, i ) );
8874      } );
8875    }
8876
8877    return this.each( function() {
8878      var self = jQuery( this ),
8879        contents = self.contents();
8880
8881      if ( contents.length ) {
8882        contents.wrapAll( html );
8883
8884      } else {
8885        self.append( html );
8886      }
8887    } );
8888  },
8889
8890  wrap: function( html ) {
8891    var isFunction = jQuery.isFunction( html );
8892
8893    return this.each( function( i ) {
8894      jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
8895    } );
8896  },
8897
8898  unwrap: function() {
8899    return this.parent().each( function() {
8900      if ( !jQuery.nodeName( this, "body" ) ) {
8901        jQuery( this ).replaceWith( this.childNodes );
8902      }
8903    } ).end();
8904  }
8905} );
8906
8907
8908jQuery.expr.filters.hidden = function( elem ) {
8909  return !jQuery.expr.filters.visible( elem );
8910};
8911jQuery.expr.filters.visible = function( elem ) {
8912
8913  // Support: Opera <= 12.12
8914  // Opera reports offsetWidths and offsetHeights less than zero on some elements
8915  // Use OR instead of AND as the element is not visible if either is true
8916  // See tickets #10406 and #13132
8917  return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
8918};
8919
8920
8921
8922
8923var r20 = /%20/g,
8924  rbracket = /\[\]$/,
8925  rCRLF = /\r?\n/g,
8926  rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8927  rsubmittable = /^(?:input|select|textarea|keygen)/i;
8928
8929function buildParams( prefix, obj, traditional, add ) {
8930  var name;
8931
8932  if ( jQuery.isArray( obj ) ) {
8933
8934    // Serialize array item.
8935    jQuery.each( obj, function( i, v ) {
8936      if ( traditional || rbracket.test( prefix ) ) {
8937
8938        // Treat each array item as a scalar.
8939        add( prefix, v );
8940
8941      } else {
8942
8943        // Item is non-scalar (array or object), encode its numeric index.
8944        buildParams(
8945          prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8946          v,
8947          traditional,
8948          add
8949        );
8950      }
8951    } );
8952
8953  } else if ( !traditional && jQuery.type( obj ) === "object" ) {
8954
8955    // Serialize object item.
8956    for ( name in obj ) {
8957      buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8958    }
8959
8960  } else {
8961
8962    // Serialize scalar item.
8963    add( prefix, obj );
8964  }
8965}
8966
8967// Serialize an array of form elements or a set of
8968// key/values into a query string
8969jQuery.param = function( a, traditional ) {
8970  var prefix,
8971    s = [],
8972    add = function( key, value ) {
8973
8974      // If value is a function, invoke it and return its value
8975      value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8976      s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8977    };
8978
8979  // Set traditional to true for jQuery <= 1.3.2 behavior.
8980  if ( traditional === undefined ) {
8981    traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8982  }
8983
8984  // If an array was passed in, assume that it is an array of form elements.
8985  if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8986
8987    // Serialize the form elements
8988    jQuery.each( a, function() {
8989      add( this.name, this.value );
8990    } );
8991
8992  } else {
8993
8994    // If traditional, encode the "old" way (the way 1.3.2 or older
8995    // did it), otherwise encode params recursively.
8996    for ( prefix in a ) {
8997      buildParams( prefix, a[ prefix ], traditional, add );
8998    }
8999  }
9000
9001  // Return the resulting serialization
9002  return s.join( "&" ).replace( r20, "+" );
9003};
9004
9005jQuery.fn.extend( {
9006  serialize: function() {
9007    return jQuery.param( this.serializeArray() );
9008  },
9009  serializeArray: function() {
9010    return this.map( function() {
9011
9012      // Can add propHook for "elements" to filter or add form elements
9013      var elements = jQuery.prop( this, "elements" );
9014      return elements ? jQuery.makeArray( elements ) : this;
9015    } )
9016    .filter( function() {
9017      var type = this.type;
9018
9019      // Use .is( ":disabled" ) so that fieldset[disabled] works
9020      return this.name && !jQuery( this ).is( ":disabled" ) &&
9021        rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9022        ( this.checked || !rcheckableType.test( type ) );
9023    } )
9024    .map( function( i, elem ) {
9025      var val = jQuery( this ).val();
9026
9027      return val == null ?
9028        null :
9029        jQuery.isArray( val ) ?
9030          jQuery.map( val, function( val ) {
9031            return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9032          } ) :
9033          { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9034    } ).get();
9035  }
9036} );
9037
9038
9039jQuery.ajaxSettings.xhr = function() {
9040  try {
9041    return new window.XMLHttpRequest();
9042  } catch ( e ) {}
9043};
9044
9045var xhrSuccessStatus = {
9046
9047    // File protocol always yields status code 0, assume 200
9048    0: 200,
9049
9050    // Support: IE9
9051    // #1450: sometimes IE returns 1223 when it should be 204
9052    1223: 204
9053  },
9054  xhrSupported = jQuery.ajaxSettings.xhr();
9055
9056support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9057support.ajax = xhrSupported = !!xhrSupported;
9058
9059jQuery.ajaxTransport( function( options ) {
9060  var callback, errorCallback;
9061
9062  // Cross domain only allowed if supported through XMLHttpRequest
9063  if ( support.cors || xhrSupported && !options.crossDomain ) {
9064    return {
9065      send: function( headers, complete ) {
9066        var i,
9067          xhr = options.xhr();
9068
9069        xhr.open(
9070          options.type,
9071          options.url,
9072          options.async,
9073          options.username,
9074          options.password
9075        );
9076
9077        // Apply custom fields if provided
9078        if ( options.xhrFields ) {
9079          for ( i in options.xhrFields ) {
9080            xhr[ i ] = options.xhrFields[ i ];
9081          }
9082        }
9083
9084        // Override mime type if needed
9085        if ( options.mimeType && xhr.overrideMimeType ) {
9086          xhr.overrideMimeType( options.mimeType );
9087        }
9088
9089        // X-Requested-With header
9090        // For cross-domain requests, seeing as conditions for a preflight are
9091        // akin to a jigsaw puzzle, we simply never set it to be sure.
9092        // (it can always be set on a per-request basis or even using ajaxSetup)
9093        // For same-domain requests, won't change header if already provided.
9094        if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9095          headers[ "X-Requested-With" ] = "XMLHttpRequest";
9096        }
9097
9098        // Set headers
9099        for ( i in headers ) {
9100          xhr.setRequestHeader( i, headers[ i ] );
9101        }
9102
9103        // Callback
9104        callback = function( type ) {
9105          return function() {
9106            if ( callback ) {
9107              callback = errorCallback = xhr.onload =
9108                xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9109
9110              if ( type === "abort" ) {
9111                xhr.abort();
9112              } else if ( type === "error" ) {
9113
9114                // Support: IE9
9115                // On a manual native abort, IE9 throws
9116                // errors on any property access that is not readyState
9117                if ( typeof xhr.status !== "number" ) {
9118                  complete( 0, "error" );
9119                } else {
9120                  complete(
9121
9122                    // File: protocol always yields status 0; see #8605, #14207
9123                    xhr.status,
9124                    xhr.statusText
9125                  );
9126                }
9127              } else {
9128                complete(
9129                  xhrSuccessStatus[ xhr.status ] || xhr.status,
9130                  xhr.statusText,
9131
9132                  // Support: IE9 only
9133                  // IE9 has no XHR2 but throws on binary (trac-11426)
9134                  // For XHR2 non-text, let the caller handle it (gh-2498)
9135                  ( xhr.responseType || "text" ) !== "text"  ||
9136                  typeof xhr.responseText !== "string" ?
9137                    { binary: xhr.response } :
9138                    { text: xhr.responseText },
9139                  xhr.getAllResponseHeaders()
9140                );
9141              }
9142            }
9143          };
9144        };
9145
9146        // Listen to events
9147        xhr.onload = callback();
9148        errorCallback = xhr.onerror = callback( "error" );
9149
9150        // Support: IE9
9151        // Use onreadystatechange to replace onabort
9152        // to handle uncaught aborts
9153        if ( xhr.onabort !== undefined ) {
9154          xhr.onabort = errorCallback;
9155        } else {
9156          xhr.onreadystatechange = function() {
9157
9158            // Check readyState before timeout as it changes
9159            if ( xhr.readyState === 4 ) {
9160
9161              // Allow onerror to be called first,
9162              // but that will not handle a native abort
9163              // Also, save errorCallback to a variable
9164              // as xhr.onerror cannot be accessed
9165              window.setTimeout( function() {
9166                if ( callback ) {
9167                  errorCallback();
9168                }
9169              } );
9170            }
9171          };
9172        }
9173
9174        // Create the abort callback
9175        callback = callback( "abort" );
9176
9177        try {
9178
9179          // Do send the request (this may raise an exception)
9180          xhr.send( options.hasContent && options.data || null );
9181        } catch ( e ) {
9182
9183          // #14683: Only rethrow if this hasn't been notified as an error yet
9184          if ( callback ) {
9185            throw e;
9186          }
9187        }
9188      },
9189
9190      abort: function() {
9191        if ( callback ) {
9192          callback();
9193        }
9194      }
9195    };
9196  }
9197} );
9198
9199
9200
9201
9202// Install script dataType
9203jQuery.ajaxSetup( {
9204  accepts: {
9205    script: "text/javascript, application/javascript, " +
9206      "application/ecmascript, application/x-ecmascript"
9207  },
9208  contents: {
9209    script: /\b(?:java|ecma)script\b/
9210  },
9211  converters: {
9212    "text script": function( text ) {
9213      jQuery.globalEval( text );
9214      return text;
9215    }
9216  }
9217} );
9218
9219// Handle cache's special case and crossDomain
9220jQuery.ajaxPrefilter( "script", function( s ) {
9221  if ( s.cache === undefined ) {
9222    s.cache = false;
9223  }
9224  if ( s.crossDomain ) {
9225    s.type = "GET";
9226  }
9227} );
9228
9229// Bind script tag hack transport
9230jQuery.ajaxTransport( "script", function( s ) {
9231
9232  // This transport only deals with cross domain requests
9233  if ( s.crossDomain ) {
9234    var script, callback;
9235    return {
9236      send: function( _, complete ) {
9237        script = jQuery( "<script>" ).prop( {
9238          charset: s.scriptCharset,
9239          src: s.url
9240        } ).on(
9241          "load error",
9242          callback = function( evt ) {
9243            script.remove();
9244            callback = null;
9245            if ( evt ) {
9246              complete( evt.type === "error" ? 404 : 200, evt.type );
9247            }
9248          }
9249        );
9250
9251        // Use native DOM manipulation to avoid our domManip AJAX trickery
9252        document.head.appendChild( script[ 0 ] );
9253      },
9254      abort: function() {
9255        if ( callback ) {
9256          callback();
9257        }
9258      }
9259    };
9260  }
9261} );
9262
9263
9264
9265
9266var oldCallbacks = [],
9267  rjsonp = /(=)\?(?=&|$)|\?\?/;
9268
9269// Default jsonp settings
9270jQuery.ajaxSetup( {
9271  jsonp: "callback",
9272  jsonpCallback: function() {
9273    var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9274    this[ callback ] = true;
9275    return callback;
9276  }
9277} );
9278
9279// Detect, normalize options and install callbacks for jsonp requests
9280jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9281
9282  var callbackName, overwritten, responseContainer,
9283    jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9284      "url" :
9285      typeof s.data === "string" &&
9286        ( s.contentType || "" )
9287          .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9288        rjsonp.test( s.data ) && "data"
9289    );
9290
9291  // Handle iff the expected data type is "jsonp" or we have a parameter to set
9292  if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9293
9294    // Get callback name, remembering preexisting value associated with it
9295    callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9296      s.jsonpCallback() :
9297      s.jsonpCallback;
9298
9299    // Insert callback into url or form data
9300    if ( jsonProp ) {
9301      s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9302    } else if ( s.jsonp !== false ) {
9303      s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9304    }
9305
9306    // Use data converter to retrieve json after script execution
9307    s.converters[ "script json" ] = function() {
9308      if ( !responseContainer ) {
9309        jQuery.error( callbackName + " was not called" );
9310      }
9311      return responseContainer[ 0 ];
9312    };
9313
9314    // Force json dataType
9315    s.dataTypes[ 0 ] = "json";
9316
9317    // Install callback
9318    overwritten = window[ callbackName ];
9319    window[ callbackName ] = function() {
9320      responseContainer = arguments;
9321    };
9322
9323    // Clean-up function (fires after converters)
9324    jqXHR.always( function() {
9325
9326      // If previous value didn't exist - remove it
9327      if ( overwritten === undefined ) {
9328        jQuery( window ).removeProp( callbackName );
9329
9330      // Otherwise restore preexisting value
9331      } else {
9332        window[ callbackName ] = overwritten;
9333      }
9334
9335      // Save back as free
9336      if ( s[ callbackName ] ) {
9337
9338        // Make sure that re-using the options doesn't screw things around
9339        s.jsonpCallback = originalSettings.jsonpCallback;
9340
9341        // Save the callback name for future use
9342        oldCallbacks.push( callbackName );
9343      }
9344
9345      // Call if it was a function and we have a response
9346      if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9347        overwritten( responseContainer[ 0 ] );
9348      }
9349
9350      responseContainer = overwritten = undefined;
9351    } );
9352
9353    // Delegate to script
9354    return "script";
9355  }
9356} );
9357
9358
9359
9360
9361// Argument "data" should be string of html
9362// context (optional): If specified, the fragment will be created in this context,
9363// defaults to document
9364// keepScripts (optional): If true, will include scripts passed in the html string
9365jQuery.parseHTML = function( data, context, keepScripts ) {
9366  if ( !data || typeof data !== "string" ) {
9367    return null;
9368  }
9369  if ( typeof context === "boolean" ) {
9370    keepScripts = context;
9371    context = false;
9372  }
9373  context = context || document;
9374
9375  var parsed = rsingleTag.exec( data ),
9376    scripts = !keepScripts && [];
9377
9378  // Single tag
9379  if ( parsed ) {
9380    return [ context.createElement( parsed[ 1 ] ) ];
9381  }
9382
9383  parsed = buildFragment( [ data ], context, scripts );
9384
9385  if ( scripts && scripts.length ) {
9386    jQuery( scripts ).remove();
9387  }
9388
9389  return jQuery.merge( [], parsed.childNodes );
9390};
9391
9392
9393// Keep a copy of the old load method
9394var _load = jQuery.fn.load;
9395
9396/**
9397 * Load a url into a page
9398 */
9399jQuery.fn.load = function( url, params, callback ) {
9400  if ( typeof url !== "string" && _load ) {
9401    return _load.apply( this, arguments );
9402  }
9403
9404  var selector, type, response,
9405    self = this,
9406    off = url.indexOf( " " );
9407
9408  if ( off > -1 ) {
9409    selector = jQuery.trim( url.slice( off ) );
9410    url = url.slice( 0, off );
9411  }
9412
9413  // If it's a function
9414  if ( jQuery.isFunction( params ) ) {
9415
9416    // We assume that it's the callback
9417    callback = params;
9418    params = undefined;
9419
9420  // Otherwise, build a param string
9421  } else if ( params && typeof params === "object" ) {
9422    type = "POST";
9423  }
9424
9425  // If we have elements to modify, make the request
9426  if ( self.length > 0 ) {
9427    jQuery.ajax( {
9428      url: url,
9429
9430      // If "type" variable is undefined, then "GET" method will be used.
9431      // Make value of this field explicit since
9432      // user can override it through ajaxSetup method
9433      type: type || "GET",
9434      dataType: "html",
9435      data: params
9436    } ).done( function( responseText ) {
9437
9438      // Save response for use in complete callback
9439      response = arguments;
9440
9441      self.html( selector ?
9442
9443        // If a selector was specified, locate the right elements in a dummy div
9444        // Exclude scripts to avoid IE 'Permission Denied' errors
9445        jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9446
9447        // Otherwise use the full result
9448        responseText );
9449
9450    // If the request succeeds, this function gets "data", "status", "jqXHR"
9451    // but they are ignored because response was set above.
9452    // If it fails, this function gets "jqXHR", "status", "error"
9453    } ).always( callback && function( jqXHR, status ) {
9454      self.each( function() {
9455        callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9456      } );
9457    } );
9458  }
9459
9460  return this;
9461};
9462
9463
9464
9465
9466// Attach a bunch of functions for handling common AJAX events
9467jQuery.each( [
9468  "ajaxStart",
9469  "ajaxStop",
9470  "ajaxComplete",
9471  "ajaxError",
9472  "ajaxSuccess",
9473  "ajaxSend"
9474], function( i, type ) {
9475  jQuery.fn[ type ] = function( fn ) {
9476    return this.on( type, fn );
9477  };
9478} );
9479
9480
9481
9482
9483jQuery.expr.filters.animated = function( elem ) {
9484  return jQuery.grep( jQuery.timers, function( fn ) {
9485    return elem === fn.elem;
9486  } ).length;
9487};
9488
9489
9490
9491
9492/**
9493 * Gets a window from an element
9494 */
9495function getWindow( elem ) {
9496  return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
9497}
9498
9499jQuery.offset = {
9500  setOffset: function( elem, options, i ) {
9501    var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9502      position = jQuery.css( elem, "position" ),
9503      curElem = jQuery( elem ),
9504      props = {};
9505
9506    // Set position first, in-case top/left are set even on static elem
9507    if ( position === "static" ) {
9508      elem.style.position = "relative";
9509    }
9510
9511    curOffset = curElem.offset();
9512    curCSSTop = jQuery.css( elem, "top" );
9513    curCSSLeft = jQuery.css( elem, "left" );
9514    calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9515      ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9516
9517    // Need to be able to calculate position if either
9518    // top or left is auto and position is either absolute or fixed
9519    if ( calculatePosition ) {
9520      curPosition = curElem.position();
9521      curTop = curPosition.top;
9522      curLeft = curPosition.left;
9523
9524    } else {
9525      curTop = parseFloat( curCSSTop ) || 0;
9526      curLeft = parseFloat( curCSSLeft ) || 0;
9527    }
9528
9529    if ( jQuery.isFunction( options ) ) {
9530
9531      // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9532      options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9533    }
9534
9535    if ( options.top != null ) {
9536      props.top = ( options.top - curOffset.top ) + curTop;
9537    }
9538    if ( options.left != null ) {
9539      props.left = ( options.left - curOffset.left ) + curLeft;
9540    }
9541
9542    if ( "using" in options ) {
9543      options.using.call( elem, props );
9544
9545    } else {
9546      curElem.css( props );
9547    }
9548  }
9549};
9550
9551jQuery.fn.extend( {
9552  offset: function( options ) {
9553    if ( arguments.length ) {
9554      return options === undefined ?
9555        this :
9556        this.each( function( i ) {
9557          jQuery.offset.setOffset( this, options, i );
9558        } );
9559    }
9560
9561    var docElem, win,
9562      elem = this[ 0 ],
9563      box = { top: 0, left: 0 },
9564      doc = elem && elem.ownerDocument;
9565
9566    if ( !doc ) {
9567      return;
9568    }
9569
9570    docElem = doc.documentElement;
9571
9572    // Make sure it's not a disconnected DOM node
9573    if ( !jQuery.contains( docElem, elem ) ) {
9574      return box;
9575    }
9576
9577    box = elem.getBoundingClientRect();
9578    win = getWindow( doc );
9579    return {
9580      top: box.top + win.pageYOffset - docElem.clientTop,
9581      left: box.left + win.pageXOffset - docElem.clientLeft
9582    };
9583  },
9584
9585  position: function() {
9586    if ( !this[ 0 ] ) {
9587      return;
9588    }
9589
9590    var offsetParent, offset,
9591      elem = this[ 0 ],
9592      parentOffset = { top: 0, left: 0 };
9593
9594    // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9595    // because it is its only offset parent
9596    if ( jQuery.css( elem, "position" ) === "fixed" ) {
9597
9598      // Assume getBoundingClientRect is there when computed position is fixed
9599      offset = elem.getBoundingClientRect();
9600
9601    } else {
9602
9603      // Get *real* offsetParent
9604      offsetParent = this.offsetParent();
9605
9606      // Get correct offsets
9607      offset = this.offset();
9608      if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9609        parentOffset = offsetParent.offset();
9610      }
9611
9612      // Add offsetParent borders
9613      parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9614      parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9615    }
9616
9617    // Subtract parent offsets and element margins
9618    return {
9619      top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9620      left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9621    };
9622  },
9623
9624  // This method will return documentElement in the following cases:
9625  // 1) For the element inside the iframe without offsetParent, this method will return
9626  //    documentElement of the parent window
9627  // 2) For the hidden or detached element
9628  // 3) For body or html element, i.e. in case of the html node - it will return itself
9629  //
9630  // but those exceptions were never presented as a real life use-cases
9631  // and might be considered as more preferable results.
9632  //
9633  // This logic, however, is not guaranteed and can change at any point in the future
9634  offsetParent: function() {
9635    return this.map( function() {
9636      var offsetParent = this.offsetParent;
9637
9638      while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
9639        offsetParent = offsetParent.offsetParent;
9640      }
9641
9642      return offsetParent || documentElement;
9643    } );
9644  }
9645} );
9646
9647// Create scrollLeft and scrollTop methods
9648jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9649  var top = "pageYOffset" === prop;
9650
9651  jQuery.fn[ method ] = function( val ) {
9652    return access( this, function( elem, method, val ) {
9653      var win = getWindow( elem );
9654
9655      if ( val === undefined ) {
9656        return win ? win[ prop ] : elem[ method ];
9657      }
9658
9659      if ( win ) {
9660        win.scrollTo(
9661          !top ? val : win.pageXOffset,
9662          top ? val : win.pageYOffset
9663        );
9664
9665      } else {
9666        elem[ method ] = val;
9667      }
9668    }, method, val, arguments.length );
9669  };
9670} );
9671
9672// Support: Safari<7-8+, Chrome<37-44+
9673// Add the top/left cssHooks using jQuery.fn.position
9674// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9675// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9676// getComputedStyle returns percent when specified for top/left/bottom/right;
9677// rather than make the css module depend on the offset module, just check for it here
9678jQuery.each( [ "top", "left" ], function( i, prop ) {
9679  jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9680    function( elem, computed ) {
9681      if ( computed ) {
9682        computed = curCSS( elem, prop );
9683
9684        // If curCSS returns percentage, fallback to offset
9685        return rnumnonpx.test( computed ) ?
9686          jQuery( elem ).position()[ prop ] + "px" :
9687          computed;
9688      }
9689    }
9690  );
9691} );
9692
9693
9694// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9695jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9696  jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
9697    function( defaultExtra, funcName ) {
9698
9699    // Margin is only for outerHeight, outerWidth
9700    jQuery.fn[ funcName ] = function( margin, value ) {
9701      var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9702        extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9703
9704      return access( this, function( elem, type, value ) {
9705        var doc;
9706
9707        if ( jQuery.isWindow( elem ) ) {
9708
9709          // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9710          // isn't a whole lot we can do. See pull request at this URL for discussion:
9711          // https://github.com/jquery/jquery/pull/764
9712          return elem.document.documentElement[ "client" + name ];
9713        }
9714
9715        // Get document width or height
9716        if ( elem.nodeType === 9 ) {
9717          doc = elem.documentElement;
9718
9719          // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9720          // whichever is greatest
9721          return Math.max(
9722            elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9723            elem.body[ "offset" + name ], doc[ "offset" + name ],
9724            doc[ "client" + name ]
9725          );
9726        }
9727
9728        return value === undefined ?
9729
9730          // Get width or height on the element, requesting but not forcing parseFloat
9731          jQuery.css( elem, type, extra ) :
9732
9733          // Set width or height on the element
9734          jQuery.style( elem, type, value, extra );
9735      }, type, chainable ? margin : undefined, chainable, null );
9736    };
9737  } );
9738} );
9739
9740
9741jQuery.fn.extend( {
9742
9743  bind: function( types, data, fn ) {
9744    return this.on( types, null, data, fn );
9745  },
9746  unbind: function( types, fn ) {
9747    return this.off( types, null, fn );
9748  },
9749
9750  delegate: function( selector, types, data, fn ) {
9751    return this.on( types, selector, data, fn );
9752  },
9753  undelegate: function( selector, types, fn ) {
9754
9755    // ( namespace ) or ( selector, types [, fn] )
9756    return arguments.length === 1 ?
9757      this.off( selector, "**" ) :
9758      this.off( types, selector || "**", fn );
9759  },
9760  size: function() {
9761    return this.length;
9762  }
9763} );
9764
9765jQuery.fn.andSelf = jQuery.fn.addBack;
9766
9767
9768
9769
9770// Register as a named AMD module, since jQuery can be concatenated with other
9771// files that may use define, but not via a proper concatenation script that
9772// understands anonymous AMD modules. A named AMD is safest and most robust
9773// way to register. Lowercase jquery is used because AMD module names are
9774// derived from file names, and jQuery is normally delivered in a lowercase
9775// file name. Do this after creating the global so that if an AMD module wants
9776// to call noConflict to hide this version of jQuery, it will work.
9777
9778// Note that for maximum portability, libraries that are not jQuery should
9779// declare themselves as anonymous modules, and avoid setting a global if an
9780// AMD loader is present. jQuery is a special case. For more information, see
9781// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9782
9783if ( typeof define === "function" && define.amd ) {
9784  define( "jquery", [], function() {
9785    return jQuery;
9786  } );
9787}
9788
9789
9790
9791var
9792
9793  // Map over jQuery in case of overwrite
9794  _jQuery = window.jQuery,
9795
9796  // Map over the $ in case of overwrite
9797  _$ = window.$;
9798
9799jQuery.noConflict = function( deep ) {
9800  if ( window.$ === jQuery ) {
9801    window.$ = _$;
9802  }
9803
9804  if ( deep && window.jQuery === jQuery ) {
9805    window.jQuery = _jQuery;
9806  }
9807
9808  return jQuery;
9809};
9810
9811// Expose jQuery and $ identifiers, even in AMD
9812// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9813// and CommonJS for browser emulators (#13566)
9814if ( !noGlobal ) {
9815  window.jQuery = window.$ = jQuery;
9816}
9817
9818return jQuery;
9819}));
9820(function($, undefined) {
9821
9822/**
9823 * Unobtrusive scripting adapter for jQuery
9824 * https://github.com/rails/jquery-ujs
9825 *
9826 * Requires jQuery 1.8.0 or later.
9827 *
9828 * Released under the MIT license
9829 *
9830 */
9831
9832  // Cut down on the number of issues from people inadvertently including jquery_ujs twice
9833  // by detecting and raising an error when it happens.
9834  'use strict';
9835
9836  if ( $.rails !== undefined ) {
9837    $.error('jquery-ujs has already been loaded!');
9838  }
9839
9840  // Shorthand to make it a little easier to call public rails functions from within rails.js
9841  var rails;
9842  var $document = $(document);
9843
9844  $.rails = rails = {
9845    // Link elements bound by jquery-ujs
9846    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
9847
9848    // Button elements bound by jquery-ujs
9849    buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)',
9850
9851    // Select elements bound by jquery-ujs
9852    inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
9853
9854    // Form elements bound by jquery-ujs
9855    formSubmitSelector: 'form:not([data-turbo=true])',
9856
9857    // Form input elements bound by jquery-ujs
9858    formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
9859
9860    // Form input elements disabled during form submission
9861    disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
9862
9863    // Form input elements re-enabled after form submission
9864    enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
9865
9866    // Form required input elements
9867    requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])',
9868
9869    // Form file input elements
9870    fileInputSelector: 'input[name][type=file]:not([disabled])',
9871
9872    // Link onClick disable selector with possible reenable after remote submission
9873    linkDisableSelector: 'a[data-disable-with], a[data-disable]',
9874
9875    // Button onClick disable selector with possible reenable after remote submission
9876    buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',
9877
9878    // Up-to-date Cross-Site Request Forgery token
9879    csrfToken: function() {
9880     return $('meta[name=csrf-token]').attr('content');
9881    },
9882
9883    // URL param that must contain the CSRF token
9884    csrfParam: function() {
9885     return $('meta[name=csrf-param]').attr('content');
9886    },
9887
9888    // Make sure that every Ajax request sends the CSRF token
9889    CSRFProtection: function(xhr) {
9890      var token = rails.csrfToken();
9891      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
9892    },
9893
9894    // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones)
9895    refreshCSRFTokens: function(){
9896      $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken());
9897    },
9898
9899    // Triggers an event on an element and returns false if the event result is false
9900    fire: function(obj, name, data) {
9901      var event = $.Event(name);
9902      obj.trigger(event, data);
9903      return event.result !== false;
9904    },
9905
9906    // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
9907    confirm: function(message) {
9908      return confirm(message);
9909    },
9910
9911    // Default ajax function, may be overridden with custom function in $.rails.ajax
9912    ajax: function(options) {
9913      return $.ajax(options);
9914    },
9915
9916    // Default way to get an element's href. May be overridden at $.rails.href.
9917    href: function(element) {
9918      return element[0].href;
9919    },
9920
9921    // Checks "data-remote" if true to handle the request through a XHR request.
9922    isRemote: function(element) {
9923      return element.data('remote') !== undefined && element.data('remote') !== false;
9924    },
9925
9926    // Submits "remote" forms and links with ajax
9927    handleRemote: function(element) {
9928      var method, url, data, withCredentials, dataType, options;
9929
9930      if (rails.fire(element, 'ajax:before')) {
9931        withCredentials = element.data('with-credentials') || null;
9932        dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
9933
9934        if (element.is('form')) {
9935          method = element.data('ujs:submit-button-formmethod') || element.attr('method');
9936          url = element.data('ujs:submit-button-formaction') || element.attr('action');
9937          data = $(element[0]).serializeArray();
9938          // memoized value from clicked submit button
9939          var button = element.data('ujs:submit-button');
9940          if (button) {
9941            data.push(button);
9942            element.data('ujs:submit-button', null);
9943          }
9944          element.data('ujs:submit-button-formmethod', null);
9945          element.data('ujs:submit-button-formaction', null);
9946        } else if (element.is(rails.inputChangeSelector)) {
9947          method = element.data('method');
9948          url = element.data('url');
9949          data = element.serialize();
9950          if (element.data('params')) data = data + '&' + element.data('params');
9951        } else if (element.is(rails.buttonClickSelector)) {
9952          method = element.data('method') || 'get';
9953          url = element.data('url');
9954          data = element.serialize();
9955          if (element.data('params')) data = data + '&' + element.data('params');
9956        } else {
9957          method = element.data('method');
9958          url = rails.href(element);
9959          data = element.data('params') || null;
9960        }
9961
9962        options = {
9963          type: method || 'GET', data: data, dataType: dataType,
9964          // stopping the "ajax:beforeSend" event will cancel the ajax request
9965          beforeSend: function(xhr, settings) {
9966            if (settings.dataType === undefined) {
9967              xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
9968            }
9969            if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
9970              element.trigger('ajax:send', xhr);
9971            } else {
9972              return false;
9973            }
9974          },
9975          success: function(data, status, xhr) {
9976            element.trigger('ajax:success', [data, status, xhr]);
9977          },
9978          complete: function(xhr, status) {
9979            element.trigger('ajax:complete', [xhr, status]);
9980          },
9981          error: function(xhr, status, error) {
9982            element.trigger('ajax:error', [xhr, status, error]);
9983          },
9984          crossDomain: rails.isCrossDomain(url)
9985        };
9986
9987        // There is no withCredentials for IE6-8 when
9988        // "Enable native XMLHTTP support" is disabled
9989        if (withCredentials) {
9990          options.xhrFields = {
9991            withCredentials: withCredentials
9992          };
9993        }
9994
9995        // Only pass url to `ajax` options if not blank
9996        if (url) { options.url = url; }
9997
9998        return rails.ajax(options);
9999      } else {
10000        return false;
10001      }
10002    },
10003
10004    // Determines if the request is a cross domain request.
10005    isCrossDomain: function(url) {
10006      var originAnchor = document.createElement('a');
10007      originAnchor.href = location.href;
10008      var urlAnchor = document.createElement('a');
10009
10010      try {
10011        urlAnchor.href = url;
10012        // This is a workaround to a IE bug.
10013        urlAnchor.href = urlAnchor.href;
10014
10015        // If URL protocol is false or is a string containing a single colon
10016        // *and* host are false, assume it is not a cross-domain request
10017        // (should only be the case for IE7 and IE compatibility mode).
10018        // Otherwise, evaluate protocol and host of the URL against the origin
10019        // protocol and host.
10020        return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) ||
10021          (originAnchor.protocol + '//' + originAnchor.host ===
10022            urlAnchor.protocol + '//' + urlAnchor.host));
10023      } catch (e) {
10024        // If there is an error parsing the URL, assume it is crossDomain.
10025        return true;
10026      }
10027    },
10028
10029    // Handles "data-method" on links such as:
10030    // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
10031    handleMethod: function(link) {
10032      var href = rails.href(link),
10033        method = link.data('method'),
10034        target = link.attr('target'),
10035        csrfToken = rails.csrfToken(),
10036        csrfParam = rails.csrfParam(),
10037        form = $('<form method="post" action="' + href + '"></form>'),
10038        metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
10039
10040      if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {
10041        metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
10042      }
10043
10044      if (target) { form.attr('target', target); }
10045
10046      form.hide().append(metadataInput).appendTo('body');
10047      form.submit();
10048    },
10049
10050    // Helper function that returns form elements that match the specified CSS selector
10051    // If form is actually a "form" element this will return associated elements outside the from that have
10052    // the html form attribute set
10053    formElements: function(form, selector) {
10054      return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector);
10055    },
10056
10057    /* Disables form elements:
10058      - Caches element value in 'ujs:enable-with' data store
10059      - Replaces element text with value of 'data-disable-with' attribute
10060      - Sets disabled property to true
10061    */
10062    disableFormElements: function(form) {
10063      rails.formElements(form, rails.disableSelector).each(function() {
10064        rails.disableFormElement($(this));
10065      });
10066    },
10067
10068    disableFormElement: function(element) {
10069      var method, replacement;
10070
10071      method = element.is('button') ? 'html' : 'val';
10072      replacement = element.data('disable-with');
10073
10074      if (replacement !== undefined) {
10075        element.data('ujs:enable-with', element[method]());
10076        element[method](replacement);
10077      }
10078
10079      element.prop('disabled', true);
10080      element.data('ujs:disabled', true);
10081    },
10082
10083    /* Re-enables disabled form elements:
10084      - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
10085      - Sets disabled property to false
10086    */
10087    enableFormElements: function(form) {
10088      rails.formElements(form, rails.enableSelector).each(function() {
10089        rails.enableFormElement($(this));
10090      });
10091    },
10092
10093    enableFormElement: function(element) {
10094      var method = element.is('button') ? 'html' : 'val';
10095      if (element.data('ujs:enable-with') !== undefined) {
10096        element[method](element.data('ujs:enable-with'));
10097        element.removeData('ujs:enable-with'); // clean up cache
10098      }
10099      element.prop('disabled', false);
10100      element.removeData('ujs:disabled');
10101    },
10102
10103   /* For 'data-confirm' attribute:
10104      - Fires `confirm` event
10105      - Shows the confirmation dialog
10106      - Fires the `confirm:complete` event
10107
10108      Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
10109      Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
10110      Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
10111      return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
10112   */
10113    allowAction: function(element) {
10114      var message = element.data('confirm'),
10115          answer = false, callback;
10116      if (!message) { return true; }
10117
10118      if (rails.fire(element, 'confirm')) {
10119        try {
10120          answer = rails.confirm(message);
10121        } catch (e) {
10122          (console.error || console.log).call(console, e.stack || e);
10123        }
10124        callback = rails.fire(element, 'confirm:complete', [answer]);
10125      }
10126      return answer && callback;
10127    },
10128
10129    // Helper function which checks for blank inputs in a form that match the specified CSS selector
10130    blankInputs: function(form, specifiedSelector, nonBlank) {
10131      var foundInputs = $(),
10132        input,
10133        valueToCheck,
10134        radiosForNameWithNoneSelected,
10135        radioName,
10136        selector = specifiedSelector || 'input,textarea',
10137        requiredInputs = form.find(selector),
10138        checkedRadioButtonNames = {};
10139
10140      requiredInputs.each(function() {
10141        input = $(this);
10142        if (input.is('input[type=radio]')) {
10143
10144          // Don't count unchecked required radio as blank if other radio with same name is checked,
10145          // regardless of whether same-name radio input has required attribute or not. The spec
10146          // states https://www.w3.org/TR/html5/forms.html#the-required-attribute
10147          radioName = input.attr('name');
10148
10149          // Skip if we've already seen the radio with this name.
10150          if (!checkedRadioButtonNames[radioName]) {
10151
10152            // If none checked
10153            if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) {
10154              radiosForNameWithNoneSelected = form.find(
10155                'input[type=radio][name="' + radioName + '"]');
10156              foundInputs = foundInputs.add(radiosForNameWithNoneSelected);
10157            }
10158
10159            // We only need to check each name once.
10160            checkedRadioButtonNames[radioName] = radioName;
10161          }
10162        } else {
10163          valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val();
10164          if (valueToCheck === nonBlank) {
10165            foundInputs = foundInputs.add(input);
10166          }
10167        }
10168      });
10169      return foundInputs.length ? foundInputs : false;
10170    },
10171
10172    // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
10173    nonBlankInputs: function(form, specifiedSelector) {
10174      return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
10175    },
10176
10177    // Helper function, needed to provide consistent behavior in IE
10178    stopEverything: function(e) {
10179      $(e.target).trigger('ujs:everythingStopped');
10180      e.stopImmediatePropagation();
10181      return false;
10182    },
10183
10184    //  Replace element's html with the 'data-disable-with' after storing original html
10185    //  and prevent clicking on it
10186    disableElement: function(element) {
10187      var replacement = element.data('disable-with');
10188
10189      if (replacement !== undefined) {
10190        element.data('ujs:enable-with', element.html()); // store enabled state
10191        element.html(replacement);
10192      }
10193
10194      element.bind('click.railsDisable', function(e) { // prevent further clicking
10195        return rails.stopEverything(e);
10196      });
10197      element.data('ujs:disabled', true);
10198    },
10199
10200    // Restore element to its original state which was disabled by 'disableElement' above
10201    enableElement: function(element) {
10202      if (element.data('ujs:enable-with') !== undefined) {
10203        element.html(element.data('ujs:enable-with')); // set to old enabled state
10204        element.removeData('ujs:enable-with'); // clean up cache
10205      }
10206      element.unbind('click.railsDisable'); // enable element
10207      element.removeData('ujs:disabled');
10208    }
10209  };
10210
10211  if (rails.fire($document, 'rails:attachBindings')) {
10212
10213    $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
10214
10215    // This event works the same as the load event, except that it fires every
10216    // time the page is loaded.
10217    //
10218    // See https://github.com/rails/jquery-ujs/issues/357
10219    // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
10220    $(window).on('pageshow.rails', function () {
10221      $($.rails.enableSelector).each(function () {
10222        var element = $(this);
10223
10224        if (element.data('ujs:disabled')) {
10225          $.rails.enableFormElement(element);
10226        }
10227      });
10228
10229      $($.rails.linkDisableSelector).each(function () {
10230        var element = $(this);
10231
10232        if (element.data('ujs:disabled')) {
10233          $.rails.enableElement(element);
10234        }
10235      });
10236    });
10237
10238    $document.on('ajax:complete', rails.linkDisableSelector, function() {
10239        rails.enableElement($(this));
10240    });
10241
10242    $document.on('ajax:complete', rails.buttonDisableSelector, function() {
10243        rails.enableFormElement($(this));
10244    });
10245
10246    $document.on('click.rails', rails.linkClickSelector, function(e) {
10247      var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
10248      if (!rails.allowAction(link)) return rails.stopEverything(e);
10249
10250      if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);
10251
10252      if (rails.isRemote(link)) {
10253        if (metaClick && (!method || method === 'GET') && !data) { return true; }
10254
10255        var handleRemote = rails.handleRemote(link);
10256        // Response from rails.handleRemote() will either be false or a deferred object promise.
10257        if (handleRemote === false) {
10258          rails.enableElement(link);
10259        } else {
10260          handleRemote.fail( function() { rails.enableElement(link); } );
10261        }
10262        return false;
10263
10264      } else if (method) {
10265        rails.handleMethod(link);
10266        return false;
10267      }
10268    });
10269
10270    $document.on('click.rails', rails.buttonClickSelector, function(e) {
10271      var button = $(this);
10272
10273      if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e);
10274
10275      if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button);
10276
10277      var handleRemote = rails.handleRemote(button);
10278      // Response from rails.handleRemote() will either be false or a deferred object promise.
10279      if (handleRemote === false) {
10280        rails.enableFormElement(button);
10281      } else {
10282        handleRemote.fail( function() { rails.enableFormElement(button); } );
10283      }
10284      return false;
10285    });
10286
10287    $document.on('change.rails', rails.inputChangeSelector, function(e) {
10288      var link = $(this);
10289      if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e);
10290
10291      rails.handleRemote(link);
10292      return false;
10293    });
10294
10295    $document.on('submit.rails', rails.formSubmitSelector, function(e) {
10296      var form = $(this),
10297        remote = rails.isRemote(form),
10298        blankRequiredInputs,
10299        nonBlankFileInputs;
10300
10301      if (!rails.allowAction(form)) return rails.stopEverything(e);
10302
10303      // Skip other logic when required values are missing or file upload is present
10304      if (form.attr('novalidate') === undefined) {
10305        if (form.data('ujs:formnovalidate-button') === undefined) {
10306          blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false);
10307          if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
10308            return rails.stopEverything(e);
10309          }
10310        } else {
10311          // Clear the formnovalidate in case the next button click is not on a formnovalidate button
10312          // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain
10313          form.data('ujs:formnovalidate-button', undefined);
10314        }
10315      }
10316
10317      if (remote) {
10318        nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
10319        if (nonBlankFileInputs) {
10320          // Slight timeout so that the submit button gets properly serialized
10321          // (make it easy for event handler to serialize form without disabled values)
10322          setTimeout(function(){ rails.disableFormElements(form); }, 13);
10323          var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
10324
10325          // Re-enable form elements if event bindings return false (canceling normal form submission)
10326          if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
10327
10328          return aborted;
10329        }
10330
10331        rails.handleRemote(form);
10332        return false;
10333
10334      } else {
10335        // Slight timeout so that the submit button gets properly serialized
10336        setTimeout(function(){ rails.disableFormElements(form); }, 13);
10337      }
10338    });
10339
10340    $document.on('click.rails', rails.formInputClickSelector, function(event) {
10341      var button = $(this);
10342
10343      if (!rails.allowAction(button)) return rails.stopEverything(event);
10344
10345      // Register the pressed submit button
10346      var name = button.attr('name'),
10347        data = name ? {name:name, value:button.val()} : null;
10348
10349      var form = button.closest('form');
10350      if (form.length === 0) {
10351        form = $('#' + button.attr('form'));
10352      }
10353      form.data('ujs:submit-button', data);
10354
10355      // Save attributes from button
10356      form.data('ujs:formnovalidate-button', button.attr('formnovalidate'));
10357      form.data('ujs:submit-button-formaction', button.attr('formaction'));
10358      form.data('ujs:submit-button-formmethod', button.attr('formmethod'));
10359    });
10360
10361    $document.on('ajax:send.rails', rails.formSubmitSelector, function(event) {
10362      if (this === event.target) rails.disableFormElements($(this));
10363    });
10364
10365    $document.on('ajax:complete.rails', rails.formSubmitSelector, function(event) {
10366      if (this === event.target) rails.enableFormElements($(this));
10367    });
10368
10369    $(function(){
10370      rails.refreshCSRFTokens();
10371    });
10372  }
10373
10374})( jQuery );
10375/**
10376 * @license
10377 * lodash 4.9.0 <https://lodash.com/>
10378 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
10379 * Released under MIT license <https://lodash.com/license>
10380 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
10381 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
10382 */
10383;(function() {
10384
10385  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
10386  var undefined;
10387
10388  /** Used as the semantic version number. */
10389  var VERSION = '4.9.0';
10390
10391  /** Used as the size to enable large array optimizations. */
10392  var LARGE_ARRAY_SIZE = 200;
10393
10394  /** Used as the `TypeError` message for "Functions" methods. */
vendor: 4,526 bytes, lines 10395-10525
10395  var FUNC_ERROR_TEXT = 'Expected a function';
10396
10397  /** Used to stand-in for `undefined` hash values. */
10398  var HASH_UNDEFINED = '__lodash_hash_undefined__';
10399
10400  /** Used as the internal argument placeholder. */
10401  var PLACEHOLDER = '__lodash_placeholder__';
10402
10403  /** Used to compose bitmasks for wrapper metadata. */
10404  var BIND_FLAG = 1,
10405      BIND_KEY_FLAG = 2,
10406      CURRY_BOUND_FLAG = 4,
10407      CURRY_FLAG = 8,
10408      CURRY_RIGHT_FLAG = 16,
10409      PARTIAL_FLAG = 32,
10410      PARTIAL_RIGHT_FLAG = 64,
10411      ARY_FLAG = 128,
10412      REARG_FLAG = 256,
10413      FLIP_FLAG = 512;
10414
10415  /** Used to compose bitmasks for comparison styles. */
10416  var UNORDERED_COMPARE_FLAG = 1,
10417      PARTIAL_COMPARE_FLAG = 2;
10418
10419  /** Used as default options for `_.truncate`. */
10420  var DEFAULT_TRUNC_LENGTH = 30,
10421      DEFAULT_TRUNC_OMISSION = '...';
10422
10423  /** Used to detect hot functions by number of calls within a span of milliseconds. */
10424  var HOT_COUNT = 150,
10425      HOT_SPAN = 16;
10426
10427  /** Used to indicate the type of lazy iteratees. */
10428  var LAZY_FILTER_FLAG = 1,
10429      LAZY_MAP_FLAG = 2,
10430      LAZY_WHILE_FLAG = 3;
10431
10432  /** Used as references for various `Number` constants. */
10433  var INFINITY = 1 / 0,
10434      MAX_SAFE_INTEGER = 9007199254740991,
10435      MAX_INTEGER = 1.7976931348623157e+308,
10436      NAN = 0 / 0;
10437
10438  /** Used as references for the maximum length and index of an array. */
10439  var MAX_ARRAY_LENGTH = 4294967295,
10440      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
10441      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
10442
10443  /** `Object#toString` result references. */
10444  var argsTag = '[object Arguments]',
10445      arrayTag = '[object Array]',
10446      boolTag = '[object Boolean]',
10447      dateTag = '[object Date]',
10448      errorTag = '[object Error]',
10449      funcTag = '[object Function]',
10450      genTag = '[object GeneratorFunction]',
10451      mapTag = '[object Map]',
10452      numberTag = '[object Number]',
10453      objectTag = '[object Object]',
10454      promiseTag = '[object Promise]',
10455      regexpTag = '[object RegExp]',
10456      setTag = '[object Set]',
10457      stringTag = '[object String]',
10458      symbolTag = '[object Symbol]',
10459      weakMapTag = '[object WeakMap]',
10460      weakSetTag = '[object WeakSet]';
10461
10462  var arrayBufferTag = '[object ArrayBuffer]',
10463      dataViewTag = '[object DataView]',
10464      float32Tag = '[object Float32Array]',
10465      float64Tag = '[object Float64Array]',
10466      int8Tag = '[object Int8Array]',
10467      int16Tag = '[object Int16Array]',
10468      int32Tag = '[object Int32Array]',
10469      uint8Tag = '[object Uint8Array]',
10470      uint8ClampedTag = '[object Uint8ClampedArray]',
10471      uint16Tag = '[object Uint16Array]',
10472      uint32Tag = '[object Uint32Array]';
10473
10474  /** Used to match empty string literals in compiled template source. */
10475  var reEmptyStringLeading = /\b__p \+= '';/g,
10476      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
10477      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
10478
10479  /** Used to match HTML entities and HTML characters. */
10480  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
10481      reUnescapedHtml = /[&<>"'`]/g,
10482      reHasEscapedHtml = RegExp(reEscapedHtml.source),
10483      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
10484
10485  /** Used to match template delimiters. */
10486  var reEscape = /<%-([\s\S]+?)%>/g,
10487      reEvaluate = /<%([\s\S]+?)%>/g,
10488      reInterpolate = /<%=([\s\S]+?)%>/g;
10489
10490  /** Used to match property names within property paths. */
10491  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
10492      reIsPlainProp = /^\w*$/,
10493      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
10494
10495  /**
10496   * Used to match `RegExp`
10497   * [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns).
10498   */
10499  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
10500      reHasRegExpChar = RegExp(reRegExpChar.source);
10501
10502  /** Used to match leading and trailing whitespace. */
10503  var reTrim = /^\s+|\s+$/g,
10504      reTrimStart = /^\s+/,
10505      reTrimEnd = /\s+$/;
10506
10507  /** Used to match backslashes in property paths. */
10508  var reEscapeChar = /\\(\\)?/g;
10509
10510  /**
10511   * Used to match
10512   * [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components).
10513   */
10514  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
10515
10516  /** Used to match `RegExp` flags from their coerced string values. */
10517  var reFlags = /\w*$/;
10518
10519  /** Used to detect hexadecimal string values. */
10520  var reHasHexPrefix = /^0x/i;
10521
10522  /** Used to detect bad signed hexadecimal string values. */
10523  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
10524
10525  /** Used to detect binary string values. */
vendor: 5,287 bytes, lines 10526-10634
10526  var reIsBinary = /^0b[01]+$/i;
10527
10528  /** Used to detect host constructors (Safari). */
10529  var reIsHostCtor = /^\[object .+?Constructor\]$/;
10530
10531  /** Used to detect octal string values. */
10532  var reIsOctal = /^0o[0-7]+$/i;
10533
10534  /** Used to detect unsigned integer values. */
10535  var reIsUint = /^(?:0|[1-9]\d*)$/;
10536
10537  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
10538  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
10539
10540  /** Used to ensure capturing order of template delimiters. */
10541  var reNoMatch = /($^)/;
10542
10543  /** Used to match unescaped characters in compiled string literals. */
10544  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
10545
10546  /** Used to compose unicode character classes. */
10547  var rsAstralRange = '\\ud800-\\udfff',
10548      rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
10549      rsComboSymbolsRange = '\\u20d0-\\u20f0',
10550      rsDingbatRange = '\\u2700-\\u27bf',
10551      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
10552      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
10553      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
10554      rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
10555      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
10556      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
10557      rsVarRange = '\\ufe0e\\ufe0f',
10558      rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
10559
10560  /** Used to compose unicode capture groups. */
10561  var rsAstral = '[' + rsAstralRange + ']',
10562      rsBreak = '[' + rsBreakRange + ']',
10563      rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
10564      rsDigits = '\\d+',
10565      rsDingbat = '[' + rsDingbatRange + ']',
10566      rsLower = '[' + rsLowerRange + ']',
10567      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
10568      rsFitz = '\\ud83c[\\udffb-\\udfff]',
10569      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
10570      rsNonAstral = '[^' + rsAstralRange + ']',
10571      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
10572      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
10573      rsUpper = '[' + rsUpperRange + ']',
10574      rsZWJ = '\\u200d';
10575
10576  /** Used to compose unicode regexes. */
10577  var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
10578      rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
10579      reOptMod = rsModifier + '?',
10580      rsOptVar = '[' + rsVarRange + ']?',
10581      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
10582      rsSeq = rsOptVar + reOptMod + rsOptJoin,
10583      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
10584      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
10585
10586  /**
10587   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
10588   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
10589   */
10590  var reComboMark = RegExp(rsCombo, 'g');
10591
10592  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
10593  var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
10594
10595  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
10596  var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
10597
10598  /** Used to match non-compound words composed of alphanumeric characters. */
10599  var reBasicWord = /[a-zA-Z0-9]+/g;
10600
10601  /** Used to match complex or compound words. */
10602  var reComplexWord = RegExp([
10603    rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
10604    rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
10605    rsUpper + '?' + rsLowerMisc + '+',
10606    rsUpper + '+',
10607    rsDigits,
10608    rsEmoji
10609  ].join('|'), 'g');
10610
10611  /** Used to detect strings that need a more robust regexp to match words. */
10612  var reHasComplexWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
10613
10614  /** Used to assign default `context` object properties. */
10615  var contextProps = [
10616    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
10617    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
10618    'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError',
10619    'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
10620    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
10621  ];
10622
10623  /** Used to make template sourceURLs easier to identify. */
10624  var templateCounter = -1;
10625
10626  /** Used to identify `toStringTag` values of typed arrays. */
10627  var typedArrayTags = {};
10628  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
10629  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
10630  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
10631  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
10632  typedArrayTags[uint32Tag] = true;
10633  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
10634  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
10635  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
10636  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
10637  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
10638  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
10639  typedArrayTags[setTag] = typedArrayTags[stringTag] =
10640  typedArrayTags[weakMapTag] = false;
10641
10642  /** Used to identify `toStringTag` values supported by `_.clone`. */
10643  var cloneableTags = {};
10644  cloneableTags[argsTag] = cloneableTags[arrayTag] =
10645  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
10646  cloneableTags[boolTag] = cloneableTags[dateTag] =
10647  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
10648  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
10649  cloneableTags[int32Tag] = cloneableTags[mapTag] =
10650  cloneableTags[numberTag] = cloneableTags[objectTag] =
10651  cloneableTags[regexpTag] = cloneableTags[setTag] =
10652  cloneableTags[stringTag] = cloneableTags[symbolTag] =
10653  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
10654  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
10655  cloneableTags[errorTag] = cloneableTags[funcTag] =
10656  cloneableTags[weakMapTag] = false;
10657
10658  /** Used to map latin-1 supplementary letters to basic latin letters. */
10659  var deburredLetters = {
10660    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
10661    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
10662    '\xc7': 'C',  '\xe7': 'c',
10663    '\xd0': 'D',  '\xf0': 'd',
10664    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
10665    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
10666    '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
10667    '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
10668    '\xd1': 'N',  '\xf1': 'n',
10669    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
10670    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
10671    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
10672    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
10673    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
10674    '\xc6': 'Ae', '\xe6': 'ae',
10675    '\xde': 'Th', '\xfe': 'th',
10676    '\xdf': 'ss'
10677  };
10678
10679  /** Used to map characters to HTML entities. */
10680  var htmlEscapes = {
10681    '&': '&amp;',
10682    '<': '&lt;',
10683    '>': '&gt;',
10684    '"': '&quot;',
10685    "'": '&#39;',
10686    '`': '&#96;'
10687  };
10688
10689  /** Used to map HTML entities to characters. */
10690  var htmlUnescapes = {
10691    '&amp;': '&',
10692    '&lt;': '<',
10693    '&gt;': '>',
10694    '&quot;': '"',
10695    '&#39;': "'",
10696    '&#96;': '`'
10697  };
10698
10699  /** Used to determine if values are of the language type `Object`. */
10700  var objectTypes = {
10701    'function': true,
10702    'object': true
10703  };
10704
10705  /** Used to escape characters for inclusion in compiled string literals. */
10706  var stringEscapes = {
10707    '\\': '\\',
10708    "'": "'",
10709    '\n': 'n',
10710    '\r': 'r',
10711    '\u2028': 'u2028',
10712    '\u2029': 'u2029'
10713  };
10714
10715  /** Built-in method references without a dependency on `root`. */
10716  var freeParseFloat = parseFloat,
10717      freeParseInt = parseInt;
10718
10719  /** Detect free variable `exports`. */
10720  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
10721    ? exports
10722    : undefined;
10723
10724  /** Detect free variable `module`. */
10725  var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
10726    ? module
10727    : undefined;
10728
10729  /** Detect the popular CommonJS extension `module.exports`. */
10730  var moduleExports = (freeModule && freeModule.exports === freeExports)
10731    ? freeExports
10732    : undefined;
10733
10734  /** Detect free variable `global` from Node.js. */
10735  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
10736
10737  /** Detect free variable `self`. */
10738  var freeSelf = checkGlobal(objectTypes[typeof self] && self);
10739
10740  /** Detect free variable `window`. */
10741  var freeWindow = checkGlobal(objectTypes[typeof window] && window);
10742
10743  /** Detect `this` as the global object. */
10744  var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
10745
10746  /**
10747   * Used as a reference to the global object.
10748   *
10749   * The `this` value is used if it's the global object to avoid Greasemonkey's
10750   * restricted `window` object, otherwise the `window` object is used.
10751   */
10752  var root = freeGlobal ||
10753    ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
10754      freeSelf || thisGlobal || Function('return this')();
10755
10756  /*--------------------------------------------------------------------------*/
10757
10758  /**
10759   * Adds the key-value `pair` to `map`.
10760   *
10761   * @private
10762   * @param {Object} map The map to modify.
10763   * @param {Array} pair The key-value pair to add.
10764   * @returns {Object} Returns `map`.
10765   */
10766  function addMapEntry(map, pair) {
10767    // Don't return `Map#set` because it doesn't return the map instance in IE 11.
vendor: 4,289 bytes, lines 10768-10921
10768    map.set(pair[0], pair[1]);
10769    return map;
10770  }
10771
10772  /**
10773   * Adds `value` to `set`.
10774   *
10775   * @private
10776   * @param {Object} set The set to modify.
10777   * @param {*} value The value to add.
10778   * @returns {Object} Returns `set`.
10779   */
10780  function addSetEntry(set, value) {
10781    set.add(value);
10782    return set;
10783  }
10784
10785  /**
10786   * A faster alternative to `Function#apply`, this function invokes `func`
10787   * with the `this` binding of `thisArg` and the arguments of `args`.
10788   *
10789   * @private
10790   * @param {Function} func The function to invoke.
10791   * @param {*} thisArg The `this` binding of `func`.
10792   * @param {Array} args The arguments to invoke `func` with.
10793   * @returns {*} Returns the result of `func`.
10794   */
10795  function apply(func, thisArg, args) {
10796    var length = args.length;
10797    switch (length) {
10798      case 0: return func.call(thisArg);
10799      case 1: return func.call(thisArg, args[0]);
10800      case 2: return func.call(thisArg, args[0], args[1]);
10801      case 3: return func.call(thisArg, args[0], args[1], args[2]);
10802    }
10803    return func.apply(thisArg, args);
10804  }
10805
10806  /**
10807   * A specialized version of `baseAggregator` for arrays.
10808   *
10809   * @private
10810   * @param {Array} array The array to iterate over.
10811   * @param {Function} setter The function to set `accumulator` values.
10812   * @param {Function} iteratee The iteratee to transform keys.
10813   * @param {Object} accumulator The initial aggregated object.
10814   * @returns {Function} Returns `accumulator`.
10815   */
10816  function arrayAggregator(array, setter, iteratee, accumulator) {
10817    var index = -1,
10818        length = array.length;
10819
10820    while (++index < length) {
10821      var value = array[index];
10822      setter(accumulator, value, iteratee(value), array);
10823    }
10824    return accumulator;
10825  }
10826
10827  /**
10828   * Creates a new array concatenating `array` with `other`.
10829   *
10830   * @private
10831   * @param {Array} array The first array to concatenate.
10832   * @param {Array} other The second array to concatenate.
10833   * @returns {Array} Returns the new concatenated array.
10834   */
10835  function arrayConcat(array, other) {
10836    var index = -1,
10837        length = array.length,
10838        othIndex = -1,
10839        othLength = other.length,
10840        result = Array(length + othLength);
10841
10842    while (++index < length) {
10843      result[index] = array[index];
10844    }
10845    while (++othIndex < othLength) {
10846      result[index++] = other[othIndex];
10847    }
10848    return result;
10849  }
10850
10851  /**
10852   * A specialized version of `_.forEach` for arrays without support for
10853   * iteratee shorthands.
10854   *
10855   * @private
10856   * @param {Array} array The array to iterate over.
10857   * @param {Function} iteratee The function invoked per iteration.
10858   * @returns {Array} Returns `array`.
10859   */
10860  function arrayEach(array, iteratee) {
10861    var index = -1,
10862        length = array.length;
10863
10864    while (++index < length) {
10865      if (iteratee(array[index], index, array) === false) {
10866        break;
10867      }
10868    }
10869    return array;
10870  }
10871
10872  /**
10873   * A specialized version of `_.forEachRight` for arrays without support for
10874   * iteratee shorthands.
10875   *
10876   * @private
10877   * @param {Array} array The array to iterate over.
10878   * @param {Function} iteratee The function invoked per iteration.
10879   * @returns {Array} Returns `array`.
10880   */
10881  function arrayEachRight(array, iteratee) {
10882    var length = array.length;
10883
10884    while (length--) {
10885      if (iteratee(array[length], length, array) === false) {
10886        break;
10887      }
10888    }
10889    return array;
10890  }
10891
10892  /**
10893   * A specialized version of `_.every` for arrays without support for
10894   * iteratee shorthands.
10895   *
10896   * @private
10897   * @param {Array} array The array to iterate over.
10898   * @param {Function} predicate The function invoked per iteration.
10899   * @returns {boolean} Returns `true` if all elements pass the predicate check,
10900   *  else `false`.
10901   */
10902  function arrayEvery(array, predicate) {
10903    var index = -1,
10904        length = array.length;
10905
10906    while (++index < length) {
10907      if (!predicate(array[index], index, array)) {
10908        return false;
10909      }
10910    }
10911    return true;
10912  }
10913
10914  /**
10915   * A specialized version of `_.filter` for arrays without support for
10916   * iteratee shorthands.
10917   *
10918   * @private
10919   * @param {Array} array The array to iterate over.
10920   * @param {Function} predicate The function invoked per iteration.
10921   * @returns {Array} Returns the new filtered array.
vendor: 10,752 bytes, lines 10922-11281
10922   */
10923  function arrayFilter(array, predicate) {
10924    var index = -1,
10925        length = array.length,
10926        resIndex = 0,
10927        result = [];
10928
10929    while (++index < length) {
10930      var value = array[index];
10931      if (predicate(value, index, array)) {
10932        result[resIndex++] = value;
10933      }
10934    }
10935    return result;
10936  }
10937
10938  /**
10939   * A specialized version of `_.includes` for arrays without support for
10940   * specifying an index to search from.
10941   *
10942   * @private
10943   * @param {Array} array The array to search.
10944   * @param {*} target The value to search for.
10945   * @returns {boolean} Returns `true` if `target` is found, else `false`.
10946   */
10947  function arrayIncludes(array, value) {
10948    return !!array.length && baseIndexOf(array, value, 0) > -1;
10949  }
10950
10951  /**
10952   * This function is like `arrayIncludes` except that it accepts a comparator.
10953   *
10954   * @private
10955   * @param {Array} array The array to search.
10956   * @param {*} target The value to search for.
10957   * @param {Function} comparator The comparator invoked per element.
10958   * @returns {boolean} Returns `true` if `target` is found, else `false`.
10959   */
10960  function arrayIncludesWith(array, value, comparator) {
10961    var index = -1,
10962        length = array.length;
10963
10964    while (++index < length) {
10965      if (comparator(value, array[index])) {
10966        return true;
10967      }
10968    }
10969    return false;
10970  }
10971
10972  /**
10973   * A specialized version of `_.map` for arrays without support for iteratee
10974   * shorthands.
10975   *
10976   * @private
10977   * @param {Array} array The array to iterate over.
10978   * @param {Function} iteratee The function invoked per iteration.
10979   * @returns {Array} Returns the new mapped array.
10980   */
10981  function arrayMap(array, iteratee) {
10982    var index = -1,
10983        length = array.length,
10984        result = Array(length);
10985
10986    while (++index < length) {
10987      result[index] = iteratee(array[index], index, array);
10988    }
10989    return result;
10990  }
10991
10992  /**
10993   * Appends the elements of `values` to `array`.
10994   *
10995   * @private
10996   * @param {Array} array The array to modify.
10997   * @param {Array} values The values to append.
10998   * @returns {Array} Returns `array`.
10999   */
11000  function arrayPush(array, values) {
11001    var index = -1,
11002        length = values.length,
11003        offset = array.length;
11004
11005    while (++index < length) {
11006      array[offset + index] = values[index];
11007    }
11008    return array;
11009  }
11010
11011  /**
11012   * A specialized version of `_.reduce` for arrays without support for
11013   * iteratee shorthands.
11014   *
11015   * @private
11016   * @param {Array} array The array to iterate over.
11017   * @param {Function} iteratee The function invoked per iteration.
11018   * @param {*} [accumulator] The initial value.
11019   * @param {boolean} [initAccum] Specify using the first element of `array` as
11020   *  the initial value.
11021   * @returns {*} Returns the accumulated value.
11022   */
11023  function arrayReduce(array, iteratee, accumulator, initAccum) {
11024    var index = -1,
11025        length = array.length;
11026
11027    if (initAccum && length) {
11028      accumulator = array[++index];
11029    }
11030    while (++index < length) {
11031      accumulator = iteratee(accumulator, array[index], index, array);
11032    }
11033    return accumulator;
11034  }
11035
11036  /**
11037   * A specialized version of `_.reduceRight` for arrays without support for
11038   * iteratee shorthands.
11039   *
11040   * @private
11041   * @param {Array} array The array to iterate over.
11042   * @param {Function} iteratee The function invoked per iteration.
11043   * @param {*} [accumulator] The initial value.
11044   * @param {boolean} [initAccum] Specify using the last element of `array` as
11045   *  the initial value.
11046   * @returns {*} Returns the accumulated value.
11047   */
11048  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
11049    var length = array.length;
11050    if (initAccum && length) {
11051      accumulator = array[--length];
11052    }
11053    while (length--) {
11054      accumulator = iteratee(accumulator, array[length], length, array);
11055    }
11056    return accumulator;
11057  }
11058
11059  /**
11060   * A specialized version of `_.some` for arrays without support for iteratee
11061   * shorthands.
11062   *
11063   * @private
11064   * @param {Array} array The array to iterate over.
11065   * @param {Function} predicate The function invoked per iteration.
11066   * @returns {boolean} Returns `true` if any element passes the predicate check,
11067   *  else `false`.
11068   */
11069  function arraySome(array, predicate) {
11070    var index = -1,
11071        length = array.length;
11072
11073    while (++index < length) {
11074      if (predicate(array[index], index, array)) {
11075        return true;
11076      }
11077    }
11078    return false;
11079  }
11080
11081  /**
11082   * The base implementation of methods like `_.max` and `_.min` which accepts a
11083   * `comparator` to determine the extremum value.
11084   *
11085   * @private
11086   * @param {Array} array The array to iterate over.
11087   * @param {Function} iteratee The iteratee invoked per iteration.
11088   * @param {Function} comparator The comparator used to compare values.
11089   * @returns {*} Returns the extremum value.
11090   */
11091  function baseExtremum(array, iteratee, comparator) {
11092    var index = -1,
11093        length = array.length;
11094
11095    while (++index < length) {
11096      var value = array[index],
11097          current = iteratee(value);
11098
11099      if (current != null && (computed === undefined
11100            ? current === current
11101            : comparator(current, computed)
11102          )) {
11103        var computed = current,
11104            result = value;
11105      }
11106    }
11107    return result;
11108  }
11109
11110  /**
11111   * The base implementation of methods like `_.find` and `_.findKey`, without
11112   * support for iteratee shorthands, which iterates over `collection` using
11113   * `eachFunc`.
11114   *
11115   * @private
11116   * @param {Array|Object} collection The collection to search.
11117   * @param {Function} predicate The function invoked per iteration.
11118   * @param {Function} eachFunc The function to iterate over `collection`.
11119   * @param {boolean} [retKey] Specify returning the key of the found element
11120   *  instead of the element itself.
11121   * @returns {*} Returns the found element or its key, else `undefined`.
11122   */
11123  function baseFind(collection, predicate, eachFunc, retKey) {
11124    var result;
11125    eachFunc(collection, function(value, key, collection) {
11126      if (predicate(value, key, collection)) {
11127        result = retKey ? key : value;
11128        return false;
11129      }
11130    });
11131    return result;
11132  }
11133
11134  /**
11135   * The base implementation of `_.findIndex` and `_.findLastIndex` without
11136   * support for iteratee shorthands.
11137   *
11138   * @private
11139   * @param {Array} array The array to search.
11140   * @param {Function} predicate The function invoked per iteration.
11141   * @param {boolean} [fromRight] Specify iterating from right to left.
11142   * @returns {number} Returns the index of the matched value, else `-1`.
11143   */
11144  function baseFindIndex(array, predicate, fromRight) {
11145    var length = array.length,
11146        index = fromRight ? length : -1;
11147
11148    while ((fromRight ? index-- : ++index < length)) {
11149      if (predicate(array[index], index, array)) {
11150        return index;
11151      }
11152    }
11153    return -1;
11154  }
11155
11156  /**
11157   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
11158   *
11159   * @private
11160   * @param {Array} array The array to search.
11161   * @param {*} value The value to search for.
11162   * @param {number} fromIndex The index to search from.
11163   * @returns {number} Returns the index of the matched value, else `-1`.
11164   */
11165  function baseIndexOf(array, value, fromIndex) {
11166    if (value !== value) {
11167      return indexOfNaN(array, fromIndex);
11168    }
11169    var index = fromIndex - 1,
11170        length = array.length;
11171
11172    while (++index < length) {
11173      if (array[index] === value) {
11174        return index;
11175      }
11176    }
11177    return -1;
11178  }
11179
11180  /**
11181   * This function is like `baseIndexOf` except that it accepts a comparator.
11182   *
11183   * @private
11184   * @param {Array} array The array to search.
11185   * @param {*} value The value to search for.
11186   * @param {number} fromIndex The index to search from.
11187   * @param {Function} comparator The comparator invoked per element.
11188   * @returns {number} Returns the index of the matched value, else `-1`.
11189   */
11190  function baseIndexOfWith(array, value, fromIndex, comparator) {
11191    var index = fromIndex - 1,
11192        length = array.length;
11193
11194    while (++index < length) {
11195      if (comparator(array[index], value)) {
11196        return index;
11197      }
11198    }
11199    return -1;
11200  }
11201
11202  /**
11203   * The base implementation of `_.mean` and `_.meanBy` without support for
11204   * iteratee shorthands.
11205   *
11206   * @private
11207   * @param {Array} array The array to iterate over.
11208   * @param {Function} iteratee The function invoked per iteration.
11209   * @returns {number} Returns the mean.
11210   */
11211  function baseMean(array, iteratee) {
11212    var length = array ? array.length : 0;
11213    return length ? (baseSum(array, iteratee) / length) : NAN;
11214  }
11215
11216  /**
11217   * The base implementation of `_.reduce` and `_.reduceRight`, without support
11218   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
11219   *
11220   * @private
11221   * @param {Array|Object} collection The collection to iterate over.
11222   * @param {Function} iteratee The function invoked per iteration.
11223   * @param {*} accumulator The initial value.
11224   * @param {boolean} initAccum Specify using the first or last element of
11225   *  `collection` as the initial value.
11226   * @param {Function} eachFunc The function to iterate over `collection`.
11227   * @returns {*} Returns the accumulated value.
11228   */
11229  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
11230    eachFunc(collection, function(value, index, collection) {
11231      accumulator = initAccum
11232        ? (initAccum = false, value)
11233        : iteratee(accumulator, value, index, collection);
11234    });
11235    return accumulator;
11236  }
11237
11238  /**
11239   * The base implementation of `_.sortBy` which uses `comparer` to define the
11240   * sort order of `array` and replaces criteria objects with their corresponding
11241   * values.
11242   *
11243   * @private
11244   * @param {Array} array The array to sort.
11245   * @param {Function} comparer The function to define sort order.
11246   * @returns {Array} Returns `array`.
11247   */
11248  function baseSortBy(array, comparer) {
11249    var length = array.length;
11250
11251    array.sort(comparer);
11252    while (length--) {
11253      array[length] = array[length].value;
11254    }
11255    return array;
11256  }
11257
11258  /**
11259   * The base implementation of `_.sum` and `_.sumBy` without support for
11260   * iteratee shorthands.
11261   *
11262   * @private
11263   * @param {Array} array The array to iterate over.
11264   * @param {Function} iteratee The function invoked per iteration.
11265   * @returns {number} Returns the sum.
11266   */
11267  function baseSum(array, iteratee) {
11268    var result,
11269        index = -1,
11270        length = array.length;
11271
11272    while (++index < length) {
11273      var current = iteratee(array[index]);
11274      if (current !== undefined) {
11275        result = result === undefined ? current : (result + current);
11276      }
11277    }
11278    return result;
11279  }
11280
11281  /**
11282   * The base implementation of `_.times` without support for iteratee shorthands
11283   * or max array length checks.
11284   *
11285   * @private
11286   * @param {number} n The number of times to invoke `iteratee`.
11287   * @param {Function} iteratee The function invoked per iteration.
11288   * @returns {Array} Returns the array of results.
11289   */
11290  function baseTimes(n, iteratee) {
11291    var index = -1,
11292        result = Array(n);
11293
11294    while (++index < n) {
11295      result[index] = iteratee(index);
11296    }
11297    return result;
11298  }
11299
11300  /**
11301   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
11302   * of key-value pairs for `object` corresponding to the property names of `props`.
11303   *
11304   * @private
11305   * @param {Object} object The object to query.
11306   * @param {Array} props The property names to get values for.
11307   * @returns {Object} Returns the new array of key-value pairs.
11308   */
11309  function baseToPairs(object, props) {
11310    return arrayMap(props, function(key) {
11311      return [key, object[key]];
11312    });
11313  }
11314
11315  /**
11316   * The base implementation of `_.unary` without support for storing wrapper metadata.
11317   *
11318   * @private
11319   * @param {Function} func The function to cap arguments for.
11320   * @returns {Function} Returns the new function.
11321   */
11322  function baseUnary(func) {
11323    return function(value) {
11324      return func(value);
11325    };
11326  }
11327
11328  /**
11329   * The base implementation of `_.values` and `_.valuesIn` which creates an
11330   * array of `object` property values corresponding to the property names
11331   * of `props`.
11332   *
11333   * @private
11334   * @param {Object} object The object to query.
11335   * @param {Array} props The property names to get values for.
11336   * @returns {Object} Returns the array of property values.
11337   */
11338  function baseValues(object, props) {
11339    return arrayMap(props, function(key) {
11340      return object[key];
11341    });
11342  }
11343
11344  /**
11345   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
11346   * that is not found in the character symbols.
11347   *
11348   * @private
11349   * @param {Array} strSymbols The string symbols to inspect.
11350   * @param {Array} chrSymbols The character symbols to find.
11351   * @returns {number} Returns the index of the first unmatched string symbol.
11352   */
11353  function charsStartIndex(strSymbols, chrSymbols) {
11354    var index = -1,
11355        length = strSymbols.length;
11356
11357    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
11358    return index;
11359  }
11360
11361  /**
11362   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
11363   * that is not found in the character symbols.
11364   *
11365   * @private
11366   * @param {Array} strSymbols The string symbols to inspect.
11367   * @param {Array} chrSymbols The character symbols to find.
11368   * @returns {number} Returns the index of the last unmatched string symbol.
11369   */
11370  function charsEndIndex(strSymbols, chrSymbols) {
11371    var index = strSymbols.length;
11372
11373    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
11374    return index;
11375  }
11376
11377  /**
11378   * Checks if `value` is a global object.
11379   *
11380   * @private
11381   * @param {*} value The value to check.
11382   * @returns {null|Object} Returns `value` if it's a global object, else `null`.
11383   */
11384  function checkGlobal(value) {
11385    return (value && value.Object === Object) ? value : null;
11386  }
11387
11388  /**
11389   * Compares values to sort them in ascending order.
11390   *
11391   * @private
11392   * @param {*} value The value to compare.
11393   * @param {*} other The other value to compare.
11394   * @returns {number} Returns the sort order indicator for `value`.
11395   */
11396  function compareAscending(value, other) {
11397    if (value !== other) {
11398      var valIsNull = value === null,
11399          valIsUndef = value === undefined,
11400          valIsReflexive = value === value;
11401
11402      var othIsNull = other === null,
11403          othIsUndef = other === undefined,
11404          othIsReflexive = other === other;
11405
11406      if ((value > other && !othIsNull) || !valIsReflexive ||
11407          (valIsNull && !othIsUndef && othIsReflexive) ||
11408          (valIsUndef && othIsReflexive)) {
11409        return 1;
11410      }
11411      if ((value < other && !valIsNull) || !othIsReflexive ||
11412          (othIsNull && !valIsUndef && valIsReflexive) ||
11413          (othIsUndef && valIsReflexive)) {
11414        return -1;
11415      }
11416    }
11417    return 0;
11418  }
11419
11420  /**
11421   * Used by `_.orderBy` to compare multiple properties of a value to another
11422   * and stable sort them.
11423   *
11424   * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
11425   * specify an order of "desc" for descending or "asc" for ascending sort order
11426   * of corresponding values.
11427   *
11428   * @private
11429   * @param {Object} object The object to compare.
11430   * @param {Object} other The other object to compare.
11431   * @param {boolean[]|string[]} orders The order to sort by for each property.
11432   * @returns {number} Returns the sort order indicator for `object`.
11433   */
11434  function compareMultiple(object, other, orders) {
11435    var index = -1,
11436        objCriteria = object.criteria,
11437        othCriteria = other.criteria,
11438        length = objCriteria.length,
11439        ordersLength = orders.length;
11440
11441    while (++index < length) {
11442      var result = compareAscending(objCriteria[index], othCriteria[index]);
11443      if (result) {
11444        if (index >= ordersLength) {
11445          return result;
11446        }
11447        var order = orders[index];
11448        return result * (order == 'desc' ? -1 : 1);
11449      }
11450    }
11451    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
11452    // that causes it, under certain circumstances, to provide the same value for
11453    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
11454    // for more details.
11455    //
11456    // This also ensures a stable sort in V8 and other engines.
11457    // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
11458    return object.index - other.index;
11459  }
11460
11461  /**
11462   * Gets the number of `placeholder` occurrences in `array`.
11463   *
11464   * @private
11465   * @param {Array} array The array to inspect.
11466   * @param {*} placeholder The placeholder to search for.
11467   * @returns {number} Returns the placeholder count.
11468   */
11469  function countHolders(array, placeholder) {
11470    var length = array.length,
11471        result = 0;
11472
11473    while (length--) {
11474      if (array[length] === placeholder) {
11475        result++;
11476      }
11477    }
11478    return result;
11479  }
11480
11481  /**
11482   * Creates a function that performs a mathematical operation on two values.
11483   *
11484   * @private
11485   * @param {Function} operator The function to perform the operation.
11486   * @returns {Function} Returns the new mathematical operation function.
11487   */
11488  function createMathOperation(operator) {
11489    return function(value, other) {
11490      var result;
11491      if (value === undefined && other === undefined) {
11492        return 0;
11493      }
11494      if (value !== undefined) {
11495        result = value;
11496      }
11497      if (other !== undefined) {
11498        result = result === undefined ? other : operator(result, other);
11499      }
11500      return result;
11501    };
11502  }
11503
11504  /**
11505   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
11506   *
11507   * @private
11508   * @param {string} letter The matched letter to deburr.
11509   * @returns {string} Returns the deburred letter.
11510   */
11511  function deburrLetter(letter) {
11512    return deburredLetters[letter];
11513  }
11514
11515  /**
11516   * Used by `_.escape` to convert characters to HTML entities.
11517   *
11518   * @private
11519   * @param {string} chr The matched character to escape.
11520   * @returns {string} Returns the escaped character.
11521   */
11522  function escapeHtmlChar(chr) {
11523    return htmlEscapes[chr];
11524  }
11525
11526  /**
11527   * Used by `_.template` to escape characters for inclusion in compiled string literals.
11528   *
11529   * @private
11530   * @param {string} chr The matched character to escape.
11531   * @returns {string} Returns the escaped character.
11532   */
11533  function escapeStringChar(chr) {
11534    return '\\' + stringEscapes[chr];
11535  }
11536
11537  /**
11538   * Gets the index at which the first occurrence of `NaN` is found in `array`.
11539   *
11540   * @private
11541   * @param {Array} array The array to search.
11542   * @param {number} fromIndex The index to search from.
11543   * @param {boolean} [fromRight] Specify iterating from right to left.
11544   * @returns {number} Returns the index of the matched `NaN`, else `-1`.
11545   */
11546  function indexOfNaN(array, fromIndex, fromRight) {
11547    var length = array.length,
11548        index = fromIndex + (fromRight ? 0 : -1);
11549
11550    while ((fromRight ? index-- : ++index < length)) {
11551      var other = array[index];
11552      if (other !== other) {
11553        return index;
11554      }
11555    }
11556    return -1;
11557  }
11558
11559  /**
11560   * Checks if `value` is a host object in IE < 9.
11561   *
11562   * @private
11563   * @param {*} value The value to check.
11564   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
11565   */
11566  function isHostObject(value) {
11567    // Many host objects are `Object` objects that can coerce to strings
11568    // despite having improperly defined `toString` methods.
11569    var result = false;
11570    if (value != null && typeof value.toString != 'function') {
11571      try {
11572        result = !!(value + '');
11573      } catch (e) {}
11574    }
11575    return result;
11576  }
11577
11578  /**
11579   * Checks if `value` is a valid array-like index.
11580   *
11581   * @private
11582   * @param {*} value The value to check.
11583   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
11584   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
11585   */
11586  function isIndex(value, length) {
11587    value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
11588    length = length == null ? MAX_SAFE_INTEGER : length;
11589    return value > -1 && value % 1 == 0 && value < length;
11590  }
11591
11592  /**
11593   * Converts `iterator` to an array.
11594   *
11595   * @private
11596   * @param {Object} iterator The iterator to convert.
11597   * @returns {Array} Returns the converted array.
11598   */
11599  function iteratorToArray(iterator) {
11600    var data,
11601        result = [];
11602
11603    while (!(data = iterator.next()).done) {
11604      result.push(data.value);
11605    }
11606    return result;
11607  }
11608
11609  /**
11610   * Converts `map` to an array.
11611   *
11612   * @private
11613   * @param {Object} map The map to convert.
11614   * @returns {Array} Returns the converted array.
11615   */
11616  function mapToArray(map) {
11617    var index = -1,
11618        result = Array(map.size);
11619
11620    map.forEach(function(value, key) {
11621      result[++index] = [key, value];
11622    });
11623    return result;
11624  }
11625
11626  /**
11627   * Replaces all `placeholder` elements in `array` with an internal placeholder
11628   * and returns an array of their indexes.
11629   *
11630   * @private
11631   * @param {Array} array The array to modify.
11632   * @param {*} placeholder The placeholder to replace.
11633   * @returns {Array} Returns the new array of placeholder indexes.
11634   */
11635  function replaceHolders(array, placeholder) {
11636    var index = -1,
11637        length = array.length,
11638        resIndex = 0,
11639        result = [];
11640
11641    while (++index < length) {
11642      var value = array[index];
11643      if (value === placeholder || value === PLACEHOLDER) {
11644        array[index] = PLACEHOLDER;
11645        result[resIndex++] = index;
11646      }
11647    }
11648    return result;
11649  }
11650
11651  /**
11652   * Converts `set` to an array.
11653   *
11654   * @private
11655   * @param {Object} set The set to convert.
11656   * @returns {Array} Returns the converted array.
11657   */
11658  function setToArray(set) {
11659    var index = -1,
11660        result = Array(set.size);
11661
11662    set.forEach(function(value) {
11663      result[++index] = value;
11664    });
11665    return result;
11666  }
11667
11668  /**
11669   * Gets the number of symbols in `string`.
11670   *
11671   * @private
11672   * @param {string} string The string to inspect.
11673   * @returns {number} Returns the string size.
11674   */
11675  function stringSize(string) {
11676    if (!(string && reHasComplexSymbol.test(string))) {
11677      return string.length;
11678    }
11679    var result = reComplexSymbol.lastIndex = 0;
11680    while (reComplexSymbol.test(string)) {
11681      result++;
11682    }
11683    return result;
11684  }
11685
11686  /**
11687   * Converts `string` to an array.
11688   *
11689   * @private
11690   * @param {string} string The string to convert.
11691   * @returns {Array} Returns the converted array.
11692   */
11693  function stringToArray(string) {
11694    return string.match(reComplexSymbol);
11695  }
11696
11697  /**
11698   * Used by `_.unescape` to convert HTML entities to characters.
11699   *
11700   * @private
11701   * @param {string} chr The matched character to unescape.
11702   * @returns {string} Returns the unescaped character.
11703   */
11704  function unescapeHtmlChar(chr) {
11705    return htmlUnescapes[chr];
11706  }
11707
11708  /*--------------------------------------------------------------------------*/
11709
11710  /**
11711   * Create a new pristine `lodash` function using the `context` object.
11712   *
11713   * @static
11714   * @memberOf _
11715   * @since 1.1.0
11716   * @category Util
11717   * @param {Object} [context=root] The context object.
11718   * @returns {Function} Returns a new `lodash` function.
11719   * @example
11720   *
11721   * _.mixin({ 'foo': _.constant('foo') });
11722   *
11723   * var lodash = _.runInContext();
11724   * lodash.mixin({ 'bar': lodash.constant('bar') });
11725   *
11726   * _.isFunction(_.foo);
11727   * // => true
11728   * _.isFunction(_.bar);
11729   * // => false
11730   *
11731   * lodash.isFunction(lodash.foo);
11732   * // => false
11733   * lodash.isFunction(lodash.bar);
11734   * // => true
11735   *
11736   * // Use `context` to mock `Date#getTime` use in `_.now`.
11737   * var mock = _.runInContext({
11738   *   'Date': function() {
11739   *     return { 'getTime': getTimeMock };
11740   *   }
11741   * });
11742   *
11743   * // Create a suped-up `defer` in Node.js.
11744   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
11745   */
11746  function runInContext(context) {
11747    context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
11748
11749    /** Built-in constructor references. */
11750    var Date = context.Date,
11751        Error = context.Error,
11752        Math = context.Math,
11753        RegExp = context.RegExp,
11754        TypeError = context.TypeError;
11755
11756    /** Used for built-in method references. */
11757    var arrayProto = context.Array.prototype,
11758        objectProto = context.Object.prototype;
11759
11760    /** Used to resolve the decompiled source of functions. */
11761    var funcToString = context.Function.prototype.toString;
11762
11763    /** Used to check objects for own properties. */
11764    var hasOwnProperty = objectProto.hasOwnProperty;
11765
11766    /** Used to generate unique IDs. */
11767    var idCounter = 0;
11768
11769    /** Used to infer the `Object` constructor. */
11770    var objectCtorString = funcToString.call(Object);
11771
11772    /**
11773     * Used to resolve the
11774     * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
11775     * of values.
11776     */
11777    var objectToString = objectProto.toString;
11778
11779    /** Used to restore the original `_` reference in `_.noConflict`. */
11780    var oldDash = root._;
11781
11782    /** Used to detect if a method is native. */
11783    var reIsNative = RegExp('^' +
11784      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
11785      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
11786    );
11787
11788    /** Built-in value references. */
11789    var Buffer = moduleExports ? context.Buffer : undefined,
11790        Reflect = context.Reflect,
11791        Symbol = context.Symbol,
11792        Uint8Array = context.Uint8Array,
11793        clearTimeout = context.clearTimeout,
11794        enumerate = Reflect ? Reflect.enumerate : undefined,
11795        getOwnPropertySymbols = Object.getOwnPropertySymbols,
11796        iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
11797        objectCreate = Object.create,
11798        propertyIsEnumerable = objectProto.propertyIsEnumerable,
11799        setTimeout = context.setTimeout,
11800        splice = arrayProto.splice;
11801
11802    /* Built-in method references for those with the same name as other `lodash` methods. */
11803    var nativeCeil = Math.ceil,
11804        nativeFloor = Math.floor,
11805        nativeGetPrototype = Object.getPrototypeOf,
11806        nativeIsFinite = context.isFinite,
11807        nativeJoin = arrayProto.join,
11808        nativeKeys = Object.keys,
11809        nativeMax = Math.max,
11810        nativeMin = Math.min,
11811        nativeParseInt = context.parseInt,
11812        nativeRandom = Math.random,
11813        nativeReverse = arrayProto.reverse;
11814
11815    /* Built-in method references that are verified to be native. */
11816    var DataView = getNative(context, 'DataView'),
11817        Map = getNative(context, 'Map'),
11818        Promise = getNative(context, 'Promise'),
11819        Set = getNative(context, 'Set'),
11820        WeakMap = getNative(context, 'WeakMap'),
11821        nativeCreate = getNative(Object, 'create');
11822
11823    /** Used to store function metadata. */
11824    var metaMap = WeakMap && new WeakMap;
11825
11826    /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
11827    var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
11828
11829    /** Used to lookup unminified function names. */
11830    var realNames = {};
11831
11832    /** Used to detect maps, sets, and weakmaps. */
11833    var dataViewCtorString = toSource(DataView),
11834        mapCtorString = toSource(Map),
11835        promiseCtorString = toSource(Promise),
11836        setCtorString = toSource(Set),
11837        weakMapCtorString = toSource(WeakMap);
11838
11839    /** Used to convert symbols to primitives and strings. */
11840    var symbolProto = Symbol ? Symbol.prototype : undefined,
11841        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
11842        symbolToString = symbolProto ? symbolProto.toString : undefined;
11843
11844    /*------------------------------------------------------------------------*/
11845
11846    /**
11847     * Creates a `lodash` object which wraps `value` to enable implicit method
11848     * chain sequences. Methods that operate on and return arrays, collections,
11849     * and functions can be chained together. Methods that retrieve a single value
11850     * or may return a primitive value will automatically end the chain sequence
11851     * and return the unwrapped value. Otherwise, the value must be unwrapped
11852     * with `_#value`.
11853     *
11854     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
11855     * enabled using `_.chain`.
11856     *
11857     * The execution of chained methods is lazy, that is, it's deferred until
11858     * `_#value` is implicitly or explicitly called.
11859     *
11860     * Lazy evaluation allows several methods to support shortcut fusion.
11861     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
11862     * the creation of intermediate arrays and can greatly reduce the number of
11863     * iteratee executions. Sections of a chain sequence qualify for shortcut
11864     * fusion if the section is applied to an array of at least `200` elements
11865     * and any iteratees accept only one argument. The heuristic for whether a
11866     * section qualifies for shortcut fusion is subject to change.
11867     *
11868     * Chaining is supported in custom builds as long as the `_#value` method is
11869     * directly or indirectly included in the build.
11870     *
11871     * In addition to lodash methods, wrappers have `Array` and `String` methods.
11872     *
11873     * The wrapper `Array` methods are:
11874     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
11875     *
11876     * The wrapper `String` methods are:
11877     * `replace` and `split`
11878     *
11879     * The wrapper methods that support shortcut fusion are:
11880     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
11881     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
11882     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
11883     *
11884     * The chainable wrapper methods are:
11885     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
11886     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
11887     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
11888     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
11889     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
11890     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
11891     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
11892     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
11893     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
11894     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
11895     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
11896     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
11897     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
11898     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
11899     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
11900     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
11901     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
11902     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
11903     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
11904     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
11905     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
11906     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
11907     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
11908     * `zipObject`, `zipObjectDeep`, and `zipWith`
11909     *
11910     * The wrapper methods that are **not** chainable by default are:
11911     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
11912     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `divide`, `each`,
11913     * `eachRight`, `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`,
11914     * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`,
11915     * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
11916     * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`,
11917     * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`,
11918     * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`,
11919     * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
11920     * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`,
11921     * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
11922     * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
11923     * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`,
11924     * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`,
11925     * `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`,
11926     * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
11927     * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
11928     * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
11929     * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
11930     * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`,
11931     * `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`,
11932     * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`,
11933     * `uniqueId`, `upperCase`, `upperFirst`, `value`, and `words`
11934     *
11935     * @name _
11936     * @constructor
11937     * @category Seq
11938     * @param {*} value The value to wrap in a `lodash` instance.
11939     * @returns {Object} Returns the new `lodash` wrapper instance.
11940     * @example
11941     *
11942     * function square(n) {
11943     *   return n * n;
11944     * }
11945     *
11946     * var wrapped = _([1, 2, 3]);
11947     *
11948     * // Returns an unwrapped value.
11949     * wrapped.reduce(_.add);
11950     * // => 6
11951     *
11952     * // Returns a wrapped value.
11953     * var squares = wrapped.map(square);
11954     *
11955     * _.isArray(squares);
11956     * // => false
11957     *
11958     * _.isArray(squares.value());
11959     * // => true
11960     */
11961    function lodash(value) {
11962      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
11963        if (value instanceof LodashWrapper) {
11964          return value;
11965        }
11966        if (hasOwnProperty.call(value, '__wrapped__')) {
11967          return wrapperClone(value);
11968        }
11969      }
11970      return new LodashWrapper(value);
11971    }
11972
11973    /**
11974     * The function whose prototype chain sequence wrappers inherit from.
11975     *
11976     * @private
11977     */
11978    function baseLodash() {
11979      // No operation performed.
11980    }
11981
11982    /**
11983     * The base constructor for creating `lodash` wrapper objects.
11984     *
11985     * @private
11986     * @param {*} value The value to wrap.
11987     * @param {boolean} [chainAll] Enable explicit method chain sequences.
11988     */
11989    function LodashWrapper(value, chainAll) {
11990      this.__wrapped__ = value;
11991      this.__actions__ = [];
11992      this.__chain__ = !!chainAll;
11993      this.__index__ = 0;
11994      this.__values__ = undefined;
11995    }
11996
11997    /**
11998     * By default, the template delimiters used by lodash are like those in
11999     * embedded Ruby (ERB). Change the following template settings to use
12000     * alternative delimiters.
12001     *
12002     * @static
12003     * @memberOf _
12004     * @type {Object}
12005     */
12006    lodash.templateSettings = {
12007
12008      /**
12009       * Used to detect `data` property values to be HTML-escaped.
12010       *
12011       * @memberOf _.templateSettings
12012       * @type {RegExp}
12013       */
12014      'escape': reEscape,
12015
12016      /**
12017       * Used to detect code to be evaluated.
12018       *
12019       * @memberOf _.templateSettings
12020       * @type {RegExp}
12021       */
12022      'evaluate': reEvaluate,
12023
12024      /**
12025       * Used to detect `data` property values to inject.
12026       *
12027       * @memberOf _.templateSettings
12028       * @type {RegExp}
12029       */
12030      'interpolate': reInterpolate,
12031
12032      /**
12033       * Used to reference the data object in the template text.
12034       *
12035       * @memberOf _.templateSettings
12036       * @type {string}
12037       */
12038      'variable': '',
12039
12040      /**
12041       * Used to import variables into the compiled template.
12042       *
12043       * @memberOf _.templateSettings
12044       * @type {Object}
12045       */
12046      'imports': {
12047
12048        /**
12049         * A reference to the `lodash` function.
12050         *
12051         * @memberOf _.templateSettings.imports
12052         * @type {Function}
12053         */
12054        '_': lodash
12055      }
12056    };
12057
12058    // Ensure wrappers are instances of `baseLodash`.
vendor: 6,771 bytes, lines 12059-12296
12059    lodash.prototype = baseLodash.prototype;
12060    lodash.prototype.constructor = lodash;
12061
12062    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
12063    LodashWrapper.prototype.constructor = LodashWrapper;
12064
12065    /*------------------------------------------------------------------------*/
12066
12067    /**
12068     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
12069     *
12070     * @private
12071     * @constructor
12072     * @param {*} value The value to wrap.
12073     */
12074    function LazyWrapper(value) {
12075      this.__wrapped__ = value;
12076      this.__actions__ = [];
12077      this.__dir__ = 1;
12078      this.__filtered__ = false;
12079      this.__iteratees__ = [];
12080      this.__takeCount__ = MAX_ARRAY_LENGTH;
12081      this.__views__ = [];
12082    }
12083
12084    /**
12085     * Creates a clone of the lazy wrapper object.
12086     *
12087     * @private
12088     * @name clone
12089     * @memberOf LazyWrapper
12090     * @returns {Object} Returns the cloned `LazyWrapper` object.
12091     */
12092    function lazyClone() {
12093      var result = new LazyWrapper(this.__wrapped__);
12094      result.__actions__ = copyArray(this.__actions__);
12095      result.__dir__ = this.__dir__;
12096      result.__filtered__ = this.__filtered__;
12097      result.__iteratees__ = copyArray(this.__iteratees__);
12098      result.__takeCount__ = this.__takeCount__;
12099      result.__views__ = copyArray(this.__views__);
12100      return result;
12101    }
12102
12103    /**
12104     * Reverses the direction of lazy iteration.
12105     *
12106     * @private
12107     * @name reverse
12108     * @memberOf LazyWrapper
12109     * @returns {Object} Returns the new reversed `LazyWrapper` object.
12110     */
12111    function lazyReverse() {
12112      if (this.__filtered__) {
12113        var result = new LazyWrapper(this);
12114        result.__dir__ = -1;
12115        result.__filtered__ = true;
12116      } else {
12117        result = this.clone();
12118        result.__dir__ *= -1;
12119      }
12120      return result;
12121    }
12122
12123    /**
12124     * Extracts the unwrapped value from its lazy wrapper.
12125     *
12126     * @private
12127     * @name value
12128     * @memberOf LazyWrapper
12129     * @returns {*} Returns the unwrapped value.
12130     */
12131    function lazyValue() {
12132      var array = this.__wrapped__.value(),
12133          dir = this.__dir__,
12134          isArr = isArray(array),
12135          isRight = dir < 0,
12136          arrLength = isArr ? array.length : 0,
12137          view = getView(0, arrLength, this.__views__),
12138          start = view.start,
12139          end = view.end,
12140          length = end - start,
12141          index = isRight ? end : (start - 1),
12142          iteratees = this.__iteratees__,
12143          iterLength = iteratees.length,
12144          resIndex = 0,
12145          takeCount = nativeMin(length, this.__takeCount__);
12146
12147      if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
12148          (arrLength == length && takeCount == length)) {
12149        return baseWrapperValue(array, this.__actions__);
12150      }
12151      var result = [];
12152
12153      outer:
12154      while (length-- && resIndex < takeCount) {
12155        index += dir;
12156
12157        var iterIndex = -1,
12158            value = array[index];
12159
12160        while (++iterIndex < iterLength) {
12161          var data = iteratees[iterIndex],
12162              iteratee = data.iteratee,
12163              type = data.type,
12164              computed = iteratee(value);
12165
12166          if (type == LAZY_MAP_FLAG) {
12167            value = computed;
12168          } else if (!computed) {
12169            if (type == LAZY_FILTER_FLAG) {
12170              continue outer;
12171            } else {
12172              break outer;
12173            }
12174          }
12175        }
12176        result[resIndex++] = value;
12177      }
12178      return result;
12179    }
12180
12181    // Ensure `LazyWrapper` is an instance of `baseLodash`.
12182    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
12183    LazyWrapper.prototype.constructor = LazyWrapper;
12184
12185    /*------------------------------------------------------------------------*/
12186
12187    /**
12188     * Creates a hash object.
12189     *
12190     * @private
12191     * @constructor
12192     * @returns {Object} Returns the new hash object.
12193     */
12194    function Hash() {}
12195
12196    /**
12197     * Removes `key` and its value from the hash.
12198     *
12199     * @private
12200     * @param {Object} hash The hash to modify.
12201     * @param {string} key The key of the value to remove.
12202     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
12203     */
12204    function hashDelete(hash, key) {
12205      return hashHas(hash, key) && delete hash[key];
12206    }
12207
12208    /**
12209     * Gets the hash value for `key`.
12210     *
12211     * @private
12212     * @param {Object} hash The hash to query.
12213     * @param {string} key The key of the value to get.
12214     * @returns {*} Returns the entry value.
12215     */
12216    function hashGet(hash, key) {
12217      if (nativeCreate) {
12218        var result = hash[key];
12219        return result === HASH_UNDEFINED ? undefined : result;
12220      }
12221      return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
12222    }
12223
12224    /**
12225     * Checks if a hash value for `key` exists.
12226     *
12227     * @private
12228     * @param {Object} hash The hash to query.
12229     * @param {string} key The key of the entry to check.
12230     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
12231     */
12232    function hashHas(hash, key) {
12233      return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
12234    }
12235
12236    /**
12237     * Sets the hash `key` to `value`.
12238     *
12239     * @private
12240     * @param {Object} hash The hash to modify.
12241     * @param {string} key The key of the value to set.
12242     * @param {*} value The value to set.
12243     */
12244    function hashSet(hash, key, value) {
12245      hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
12246    }
12247
12248    // Avoid inheriting from `Object.prototype` when possible.
12249    Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
12250
12251    /*------------------------------------------------------------------------*/
12252
12253    /**
12254     * Creates a map cache object to store key-value pairs.
12255     *
12256     * @private
12257     * @constructor
12258     * @param {Array} [values] The values to cache.
12259     */
12260    function MapCache(values) {
12261      var index = -1,
12262          length = values ? values.length : 0;
12263
12264      this.clear();
12265      while (++index < length) {
12266        var entry = values[index];
12267        this.set(entry[0], entry[1]);
12268      }
12269    }
12270
12271    /**
12272     * Removes all key-value entries from the map.
12273     *
12274     * @private
12275     * @name clear
12276     * @memberOf MapCache
12277     */
12278    function mapClear() {
12279      this.__data__ = {
12280        'hash': new Hash,
12281        'map': Map ? new Map : [],
12282        'string': new Hash
12283      };
12284    }
12285
12286    /**
12287     * Removes `key` and its value from the map.
12288     *
12289     * @private
12290     * @name delete
12291     * @memberOf MapCache
12292     * @param {string} key The key of the value to remove.
12293     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
12294     */
12295    function mapDelete(key) {
12296      var data = this.__data__;
12297      if (isKeyable(key)) {
12298        return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
12299      }
12300      return Map ? data.map['delete'](key) : assocDelete(data.map, key);
12301    }
12302
12303    /**
12304     * Gets the map value for `key`.
12305     *
12306     * @private
12307     * @name get
12308     * @memberOf MapCache
12309     * @param {string} key The key of the value to get.
12310     * @returns {*} Returns the entry value.
12311     */
12312    function mapGet(key) {
12313      var data = this.__data__;
12314      if (isKeyable(key)) {
12315        return hashGet(typeof key == 'string' ? data.string : data.hash, key);
12316      }
12317      return Map ? data.map.get(key) : assocGet(data.map, key);
12318    }
12319
12320    /**
12321     * Checks if a map value for `key` exists.
12322     *
12323     * @private
12324     * @name has
12325     * @memberOf MapCache
12326     * @param {string} key The key of the entry to check.
12327     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
12328     */
12329    function mapHas(key) {
12330      var data = this.__data__;
12331      if (isKeyable(key)) {
12332        return hashHas(typeof key == 'string' ? data.string : data.hash, key);
12333      }
12334      return Map ? data.map.has(key) : assocHas(data.map, key);
12335    }
12336
12337    /**
12338     * Sets the map `key` to `value`.
12339     *
12340     * @private
12341     * @name set
12342     * @memberOf MapCache
12343     * @param {string} key The key of the value to set.
12344     * @param {*} value The value to set.
12345     * @returns {Object} Returns the map cache instance.
12346     */
12347    function mapSet(key, value) {
12348      var data = this.__data__;
12349      if (isKeyable(key)) {
12350        hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
12351      } else if (Map) {
12352        data.map.set(key, value);
12353      } else {
12354        assocSet(data.map, key, value);
12355      }
12356      return this;
12357    }
12358
12359    // Add methods to `MapCache`.
12360    MapCache.prototype.clear = mapClear;
12361    MapCache.prototype['delete'] = mapDelete;
12362    MapCache.prototype.get = mapGet;
12363    MapCache.prototype.has = mapHas;
12364    MapCache.prototype.set = mapSet;
12365
12366    /*------------------------------------------------------------------------*/
12367
12368    /**
12369     *
12370     * Creates a set cache object to store unique values.
12371     *
12372     * @private
12373     * @constructor
12374     * @param {Array} [values] The values to cache.
12375     */
12376    function SetCache(values) {
12377      var index = -1,
12378          length = values ? values.length : 0;
12379
12380      this.__data__ = new MapCache;
12381      while (++index < length) {
12382        this.push(values[index]);
12383      }
12384    }
12385
12386    /**
12387     * Checks if `value` is in `cache`.
12388     *
12389     * @private
12390     * @param {Object} cache The set cache to search.
12391     * @param {*} value The value to search for.
12392     * @returns {number} Returns `true` if `value` is found, else `false`.
12393     */
12394    function cacheHas(cache, value) {
12395      var map = cache.__data__;
12396      if (isKeyable(value)) {
12397        var data = map.__data__,
12398            hash = typeof value == 'string' ? data.string : data.hash;
12399
12400        return hash[value] === HASH_UNDEFINED;
12401      }
12402      return map.has(value);
12403    }
12404
12405    /**
12406     * Adds `value` to the set cache.
12407     *
12408     * @private
12409     * @name push
12410     * @memberOf SetCache
12411     * @param {*} value The value to cache.
12412     */
12413    function cachePush(value) {
12414      var map = this.__data__;
12415      if (isKeyable(value)) {
12416        var data = map.__data__,
12417            hash = typeof value == 'string' ? data.string : data.hash;
12418
12419        hash[value] = HASH_UNDEFINED;
12420      }
12421      else {
12422        map.set(value, HASH_UNDEFINED);
12423      }
12424    }
12425
12426    // Add methods to `SetCache`.
12427    SetCache.prototype.push = cachePush;
12428
12429    /*------------------------------------------------------------------------*/
12430
12431    /**
12432     * Creates a stack cache object to store key-value pairs.
12433     *
12434     * @private
12435     * @constructor
12436     * @param {Array} [values] The values to cache.
12437     */
12438    function Stack(values) {
12439      var index = -1,
12440          length = values ? values.length : 0;
12441
12442      this.clear();
12443      while (++index < length) {
12444        var entry = values[index];
12445        this.set(entry[0], entry[1]);
12446      }
12447    }
12448
12449    /**
12450     * Removes all key-value entries from the stack.
12451     *
12452     * @private
12453     * @name clear
12454     * @memberOf Stack
12455     */
12456    function stackClear() {
12457      this.__data__ = { 'array': [], 'map': null };
12458    }
12459
12460    /**
12461     * Removes `key` and its value from the stack.
12462     *
12463     * @private
12464     * @name delete
12465     * @memberOf Stack
12466     * @param {string} key The key of the value to remove.
12467     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
12468     */
12469    function stackDelete(key) {
12470      var data = this.__data__,
12471          array = data.array;
12472
12473      return array ? assocDelete(array, key) : data.map['delete'](key);
12474    }
12475
12476    /**
12477     * Gets the stack value for `key`.
12478     *
12479     * @private
12480     * @name get
12481     * @memberOf Stack
12482     * @param {string} key The key of the value to get.
12483     * @returns {*} Returns the entry value.
12484     */
12485    function stackGet(key) {
12486      var data = this.__data__,
12487          array = data.array;
12488
12489      return array ? assocGet(array, key) : data.map.get(key);
12490    }
12491
12492    /**
12493     * Checks if a stack value for `key` exists.
12494     *
12495     * @private
12496     * @name has
12497     * @memberOf Stack
12498     * @param {string} key The key of the entry to check.
12499     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
12500     */
12501    function stackHas(key) {
12502      var data = this.__data__,
12503          array = data.array;
12504
12505      return array ? assocHas(array, key) : data.map.has(key);
12506    }
12507
12508    /**
12509     * Sets the stack `key` to `value`.
12510     *
12511     * @private
12512     * @name set
12513     * @memberOf Stack
12514     * @param {string} key The key of the value to set.
12515     * @param {*} value The value to set.
12516     * @returns {Object} Returns the stack cache instance.
12517     */
12518    function stackSet(key, value) {
12519      var data = this.__data__,
12520          array = data.array;
12521
12522      if (array) {
12523        if (array.length < (LARGE_ARRAY_SIZE - 1)) {
12524          assocSet(array, key, value);
12525        } else {
12526          data.array = null;
12527          data.map = new MapCache(array);
12528        }
12529      }
12530      var map = data.map;
12531      if (map) {
12532        map.set(key, value);
12533      }
12534      return this;
12535    }
12536
12537    // Add methods to `Stack`.
12538    Stack.prototype.clear = stackClear;
12539    Stack.prototype['delete'] = stackDelete;
12540    Stack.prototype.get = stackGet;
vendor: 12,080 bytes, lines 12541-12924
12541    Stack.prototype.has = stackHas;
12542    Stack.prototype.set = stackSet;
12543
12544    /*------------------------------------------------------------------------*/
12545
12546    /**
12547     * Removes `key` and its value from the associative array.
12548     *
12549     * @private
12550     * @param {Array} array The array to modify.
12551     * @param {string} key The key of the value to remove.
12552     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
12553     */
12554    function assocDelete(array, key) {
12555      var index = assocIndexOf(array, key);
12556      if (index < 0) {
12557        return false;
12558      }
12559      var lastIndex = array.length - 1;
12560      if (index == lastIndex) {
12561        array.pop();
12562      } else {
12563        splice.call(array, index, 1);
12564      }
12565      return true;
12566    }
12567
12568    /**
12569     * Gets the associative array value for `key`.
12570     *
12571     * @private
12572     * @param {Array} array The array to query.
12573     * @param {string} key The key of the value to get.
12574     * @returns {*} Returns the entry value.
12575     */
12576    function assocGet(array, key) {
12577      var index = assocIndexOf(array, key);
12578      return index < 0 ? undefined : array[index][1];
12579    }
12580
12581    /**
12582     * Checks if an associative array value for `key` exists.
12583     *
12584     * @private
12585     * @param {Array} array The array to query.
12586     * @param {string} key The key of the entry to check.
12587     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
12588     */
12589    function assocHas(array, key) {
12590      return assocIndexOf(array, key) > -1;
12591    }
12592
12593    /**
12594     * Gets the index at which the `key` is found in `array` of key-value pairs.
12595     *
12596     * @private
12597     * @param {Array} array The array to search.
12598     * @param {*} key The key to search for.
12599     * @returns {number} Returns the index of the matched value, else `-1`.
12600     */
12601    function assocIndexOf(array, key) {
12602      var length = array.length;
12603      while (length--) {
12604        if (eq(array[length][0], key)) {
12605          return length;
12606        }
12607      }
12608      return -1;
12609    }
12610
12611    /**
12612     * Sets the associative array `key` to `value`.
12613     *
12614     * @private
12615     * @param {Array} array The array to modify.
12616     * @param {string} key The key of the value to set.
12617     * @param {*} value The value to set.
12618     */
12619    function assocSet(array, key, value) {
12620      var index = assocIndexOf(array, key);
12621      if (index < 0) {
12622        array.push([key, value]);
12623      } else {
12624        array[index][1] = value;
12625      }
12626    }
12627
12628    /*------------------------------------------------------------------------*/
12629
12630    /**
12631     * Used by `_.defaults` to customize its `_.assignIn` use.
12632     *
12633     * @private
12634     * @param {*} objValue The destination value.
12635     * @param {*} srcValue The source value.
12636     * @param {string} key The key of the property to assign.
12637     * @param {Object} object The parent object of `objValue`.
12638     * @returns {*} Returns the value to assign.
12639     */
12640    function assignInDefaults(objValue, srcValue, key, object) {
12641      if (objValue === undefined ||
12642          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
12643        return srcValue;
12644      }
12645      return objValue;
12646    }
12647
12648    /**
12649     * This function is like `assignValue` except that it doesn't assign
12650     * `undefined` values.
12651     *
12652     * @private
12653     * @param {Object} object The object to modify.
12654     * @param {string} key The key of the property to assign.
12655     * @param {*} value The value to assign.
12656     */
12657    function assignMergeValue(object, key, value) {
12658      if ((value !== undefined && !eq(object[key], value)) ||
12659          (typeof key == 'number' && value === undefined && !(key in object))) {
12660        object[key] = value;
12661      }
12662    }
12663
12664    /**
12665     * Assigns `value` to `key` of `object` if the existing value is not equivalent
12666     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
12667     * for equality comparisons.
12668     *
12669     * @private
12670     * @param {Object} object The object to modify.
12671     * @param {string} key The key of the property to assign.
12672     * @param {*} value The value to assign.
12673     */
12674    function assignValue(object, key, value) {
12675      var objValue = object[key];
12676      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
12677          (value === undefined && !(key in object))) {
12678        object[key] = value;
12679      }
12680    }
12681
12682    /**
12683     * Aggregates elements of `collection` on `accumulator` with keys transformed
12684     * by `iteratee` and values set by `setter`.
12685     *
12686     * @private
12687     * @param {Array|Object} collection The collection to iterate over.
12688     * @param {Function} setter The function to set `accumulator` values.
12689     * @param {Function} iteratee The iteratee to transform keys.
12690     * @param {Object} accumulator The initial aggregated object.
12691     * @returns {Function} Returns `accumulator`.
12692     */
12693    function baseAggregator(collection, setter, iteratee, accumulator) {
12694      baseEach(collection, function(value, key, collection) {
12695        setter(accumulator, value, iteratee(value), collection);
12696      });
12697      return accumulator;
12698    }
12699
12700    /**
12701     * The base implementation of `_.assign` without support for multiple sources
12702     * or `customizer` functions.
12703     *
12704     * @private
12705     * @param {Object} object The destination object.
12706     * @param {Object} source The source object.
12707     * @returns {Object} Returns `object`.
12708     */
12709    function baseAssign(object, source) {
12710      return object && copyObject(source, keys(source), object);
12711    }
12712
12713    /**
12714     * The base implementation of `_.at` without support for individual paths.
12715     *
12716     * @private
12717     * @param {Object} object The object to iterate over.
12718     * @param {string[]} paths The property paths of elements to pick.
12719     * @returns {Array} Returns the new array of picked elements.
12720     */
12721    function baseAt(object, paths) {
12722      var index = -1,
12723          isNil = object == null,
12724          length = paths.length,
12725          result = Array(length);
12726
12727      while (++index < length) {
12728        result[index] = isNil ? undefined : get(object, paths[index]);
12729      }
12730      return result;
12731    }
12732
12733    /**
12734     * Casts `value` to an empty array if it's not an array like object.
12735     *
12736     * @private
12737     * @param {*} value The value to inspect.
12738     * @returns {Array|Object} Returns the cast array-like object.
12739     */
12740    function baseCastArrayLikeObject(value) {
12741      return isArrayLikeObject(value) ? value : [];
12742    }
12743
12744    /**
12745     * Casts `value` to `identity` if it's not a function.
12746     *
12747     * @private
12748     * @param {*} value The value to inspect.
12749     * @returns {Function} Returns cast function.
12750     */
12751    function baseCastFunction(value) {
12752      return typeof value == 'function' ? value : identity;
12753    }
12754
12755    /**
12756     * Casts `value` to a string if it's not a string or symbol.
12757     *
12758     * @private
12759     * @param {*} value The value to inspect.
12760     * @returns {string|symbol} Returns the cast key.
12761     */
12762    function baseCastKey(key) {
12763      return (typeof key == 'string' || isSymbol(key)) ? key : (key + '');
12764    }
12765
12766    /**
12767     * Casts `value` to a path array if it's not one.
12768     *
12769     * @private
12770     * @param {*} value The value to inspect.
12771     * @returns {Array} Returns the cast property path array.
12772     */
12773    function baseCastPath(value) {
12774      return isArray(value) ? value : stringToPath(value);
12775    }
12776
12777    /**
12778     * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
12779     *
12780     * @private
12781     * @param {number} number The number to clamp.
12782     * @param {number} [lower] The lower bound.
12783     * @param {number} upper The upper bound.
12784     * @returns {number} Returns the clamped number.
12785     */
12786    function baseClamp(number, lower, upper) {
12787      if (number === number) {
12788        if (upper !== undefined) {
12789          number = number <= upper ? number : upper;
12790        }
12791        if (lower !== undefined) {
12792          number = number >= lower ? number : lower;
12793        }
12794      }
12795      return number;
12796    }
12797
12798    /**
12799     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
12800     * traversed objects.
12801     *
12802     * @private
12803     * @param {*} value The value to clone.
12804     * @param {boolean} [isDeep] Specify a deep clone.
12805     * @param {boolean} [isFull] Specify a clone including symbols.
12806     * @param {Function} [customizer] The function to customize cloning.
12807     * @param {string} [key] The key of `value`.
12808     * @param {Object} [object] The parent object of `value`.
12809     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
12810     * @returns {*} Returns the cloned value.
12811     */
12812    function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
12813      var result;
12814      if (customizer) {
12815        result = object ? customizer(value, key, object, stack) : customizer(value);
12816      }
12817      if (result !== undefined) {
12818        return result;
12819      }
12820      if (!isObject(value)) {
12821        return value;
12822      }
12823      var isArr = isArray(value);
12824      if (isArr) {
12825        result = initCloneArray(value);
12826        if (!isDeep) {
12827          return copyArray(value, result);
12828        }
12829      } else {
12830        var tag = getTag(value),
12831            isFunc = tag == funcTag || tag == genTag;
12832
12833        if (isBuffer(value)) {
12834          return cloneBuffer(value, isDeep);
12835        }
12836        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
12837          if (isHostObject(value)) {
12838            return object ? value : {};
12839          }
12840          result = initCloneObject(isFunc ? {} : value);
12841          if (!isDeep) {
12842            return copySymbols(value, baseAssign(result, value));
12843          }
12844        } else {
12845          if (!cloneableTags[tag]) {
12846            return object ? value : {};
12847          }
12848          result = initCloneByTag(value, tag, baseClone, isDeep);
12849        }
12850      }
12851      // Check for circular references and return its corresponding clone.
12852      stack || (stack = new Stack);
12853      var stacked = stack.get(value);
12854      if (stacked) {
12855        return stacked;
12856      }
12857      stack.set(value, result);
12858
12859      if (!isArr) {
12860        var props = isFull ? getAllKeys(value) : keys(value);
12861      }
12862      // Recursively populate clone (susceptible to call stack limits).
12863      arrayEach(props || value, function(subValue, key) {
12864        if (props) {
12865          key = subValue;
12866          subValue = value[key];
12867        }
12868        assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
12869      });
12870      return result;
12871    }
12872
12873    /**
12874     * The base implementation of `_.conforms` which doesn't clone `source`.
12875     *
12876     * @private
12877     * @param {Object} source The object of property predicates to conform to.
12878     * @returns {Function} Returns the new function.
12879     */
12880    function baseConforms(source) {
12881      var props = keys(source),
12882          length = props.length;
12883
12884      return function(object) {
12885        if (object == null) {
12886          return !length;
12887        }
12888        var index = length;
12889        while (index--) {
12890          var key = props[index],
12891              predicate = source[key],
12892              value = object[key];
12893
12894          if ((value === undefined &&
12895              !(key in Object(object))) || !predicate(value)) {
12896            return false;
12897          }
12898        }
12899        return true;
12900      };
12901    }
12902
12903    /**
12904     * The base implementation of `_.create` without support for assigning
12905     * properties to the created object.
12906     *
12907     * @private
12908     * @param {Object} prototype The object to inherit from.
12909     * @returns {Object} Returns the new object.
12910     */
12911    function baseCreate(proto) {
12912      return isObject(proto) ? objectCreate(proto) : {};
12913    }
12914
12915    /**
12916     * The base implementation of `_.delay` and `_.defer` which accepts an array
12917     * of `func` arguments.
12918     *
12919     * @private
12920     * @param {Function} func The function to delay.
12921     * @param {number} wait The number of milliseconds to delay invocation.
12922     * @param {Object} args The arguments to provide to `func`.
12923     * @returns {number} Returns the timer id.
12924     */
vendor: 10,033 bytes, lines 12925-13217
12925    function baseDelay(func, wait, args) {
12926      if (typeof func != 'function') {
12927        throw new TypeError(FUNC_ERROR_TEXT);
12928      }
12929      return setTimeout(function() { func.apply(undefined, args); }, wait);
12930    }
12931
12932    /**
12933     * The base implementation of methods like `_.difference` without support
12934     * for excluding multiple arrays or iteratee shorthands.
12935     *
12936     * @private
12937     * @param {Array} array The array to inspect.
12938     * @param {Array} values The values to exclude.
12939     * @param {Function} [iteratee] The iteratee invoked per element.
12940     * @param {Function} [comparator] The comparator invoked per element.
12941     * @returns {Array} Returns the new array of filtered values.
12942     */
12943    function baseDifference(array, values, iteratee, comparator) {
12944      var index = -1,
12945          includes = arrayIncludes,
12946          isCommon = true,
12947          length = array.length,
12948          result = [],
12949          valuesLength = values.length;
12950
12951      if (!length) {
12952        return result;
12953      }
12954      if (iteratee) {
12955        values = arrayMap(values, baseUnary(iteratee));
12956      }
12957      if (comparator) {
12958        includes = arrayIncludesWith;
12959        isCommon = false;
12960      }
12961      else if (values.length >= LARGE_ARRAY_SIZE) {
12962        includes = cacheHas;
12963        isCommon = false;
12964        values = new SetCache(values);
12965      }
12966      outer:
12967      while (++index < length) {
12968        var value = array[index],
12969            computed = iteratee ? iteratee(value) : value;
12970
12971        if (isCommon && computed === computed) {
12972          var valuesIndex = valuesLength;
12973          while (valuesIndex--) {
12974            if (values[valuesIndex] === computed) {
12975              continue outer;
12976            }
12977          }
12978          result.push(value);
12979        }
12980        else if (!includes(values, computed, comparator)) {
12981          result.push(value);
12982        }
12983      }
12984      return result;
12985    }
12986
12987    /**
12988     * The base implementation of `_.forEach` without support for iteratee shorthands.
12989     *
12990     * @private
12991     * @param {Array|Object} collection The collection to iterate over.
12992     * @param {Function} iteratee The function invoked per iteration.
12993     * @returns {Array|Object} Returns `collection`.
12994     */
12995    var baseEach = createBaseEach(baseForOwn);
12996
12997    /**
12998     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
12999     *
13000     * @private
13001     * @param {Array|Object} collection The collection to iterate over.
13002     * @param {Function} iteratee The function invoked per iteration.
13003     * @returns {Array|Object} Returns `collection`.
13004     */
13005    var baseEachRight = createBaseEach(baseForOwnRight, true);
13006
13007    /**
13008     * The base implementation of `_.every` without support for iteratee shorthands.
13009     *
13010     * @private
13011     * @param {Array|Object} collection The collection to iterate over.
13012     * @param {Function} predicate The function invoked per iteration.
13013     * @returns {boolean} Returns `true` if all elements pass the predicate check,
13014     *  else `false`
13015     */
13016    function baseEvery(collection, predicate) {
13017      var result = true;
13018      baseEach(collection, function(value, index, collection) {
13019        result = !!predicate(value, index, collection);
13020        return result;
13021      });
13022      return result;
13023    }
13024
13025    /**
13026     * The base implementation of `_.fill` without an iteratee call guard.
13027     *
13028     * @private
13029     * @param {Array} array The array to fill.
13030     * @param {*} value The value to fill `array` with.
13031     * @param {number} [start=0] The start position.
13032     * @param {number} [end=array.length] The end position.
13033     * @returns {Array} Returns `array`.
13034     */
13035    function baseFill(array, value, start, end) {
13036      var length = array.length;
13037
13038      start = toInteger(start);
13039      if (start < 0) {
13040        start = -start > length ? 0 : (length + start);
13041      }
13042      end = (end === undefined || end > length) ? length : toInteger(end);
13043      if (end < 0) {
13044        end += length;
13045      }
13046      end = start > end ? 0 : toLength(end);
13047      while (start < end) {
13048        array[start++] = value;
13049      }
13050      return array;
13051    }
13052
13053    /**
13054     * The base implementation of `_.filter` without support for iteratee shorthands.
13055     *
13056     * @private
13057     * @param {Array|Object} collection The collection to iterate over.
13058     * @param {Function} predicate The function invoked per iteration.
13059     * @returns {Array} Returns the new filtered array.
13060     */
13061    function baseFilter(collection, predicate) {
13062      var result = [];
13063      baseEach(collection, function(value, index, collection) {
13064        if (predicate(value, index, collection)) {
13065          result.push(value);
13066        }
13067      });
13068      return result;
13069    }
13070
13071    /**
13072     * The base implementation of `_.flatten` with support for restricting flattening.
13073     *
13074     * @private
13075     * @param {Array} array The array to flatten.
13076     * @param {number} depth The maximum recursion depth.
13077     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
13078     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
13079     * @param {Array} [result=[]] The initial result value.
13080     * @returns {Array} Returns the new flattened array.
13081     */
13082    function baseFlatten(array, depth, predicate, isStrict, result) {
13083      var index = -1,
13084          length = array.length;
13085
13086      predicate || (predicate = isFlattenable);
13087      result || (result = []);
13088
13089      while (++index < length) {
13090        var value = array[index];
13091        if (depth > 0 && predicate(value)) {
13092          if (depth > 1) {
13093            // Recursively flatten arrays (susceptible to call stack limits).
13094            baseFlatten(value, depth - 1, predicate, isStrict, result);
13095          } else {
13096            arrayPush(result, value);
13097          }
13098        } else if (!isStrict) {
13099          result[result.length] = value;
13100        }
13101      }
13102      return result;
13103    }
13104
13105    /**
13106     * The base implementation of `baseForOwn` which iterates over `object`
13107     * properties returned by `keysFunc` invoking `iteratee` for each property.
13108     * Iteratee functions may exit iteration early by explicitly returning `false`.
13109     *
13110     * @private
13111     * @param {Object} object The object to iterate over.
13112     * @param {Function} iteratee The function invoked per iteration.
13113     * @param {Function} keysFunc The function to get the keys of `object`.
13114     * @returns {Object} Returns `object`.
13115     */
13116    var baseFor = createBaseFor();
13117
13118    /**
13119     * This function is like `baseFor` except that it iterates over properties
13120     * in the opposite order.
13121     *
13122     * @private
13123     * @param {Object} object The object to iterate over.
13124     * @param {Function} iteratee The function invoked per iteration.
13125     * @param {Function} keysFunc The function to get the keys of `object`.
13126     * @returns {Object} Returns `object`.
13127     */
13128    var baseForRight = createBaseFor(true);
13129
13130    /**
13131     * The base implementation of `_.forOwn` without support for iteratee shorthands.
13132     *
13133     * @private
13134     * @param {Object} object The object to iterate over.
13135     * @param {Function} iteratee The function invoked per iteration.
13136     * @returns {Object} Returns `object`.
13137     */
13138    function baseForOwn(object, iteratee) {
13139      return object && baseFor(object, iteratee, keys);
13140    }
13141
13142    /**
13143     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
13144     *
13145     * @private
13146     * @param {Object} object The object to iterate over.
13147     * @param {Function} iteratee The function invoked per iteration.
13148     * @returns {Object} Returns `object`.
13149     */
13150    function baseForOwnRight(object, iteratee) {
13151      return object && baseForRight(object, iteratee, keys);
13152    }
13153
13154    /**
13155     * The base implementation of `_.functions` which creates an array of
13156     * `object` function property names filtered from `props`.
13157     *
13158     * @private
13159     * @param {Object} object The object to inspect.
13160     * @param {Array} props The property names to filter.
13161     * @returns {Array} Returns the new array of filtered property names.
13162     */
13163    function baseFunctions(object, props) {
13164      return arrayFilter(props, function(key) {
13165        return isFunction(object[key]);
13166      });
13167    }
13168
13169    /**
13170     * The base implementation of `_.get` without support for default values.
13171     *
13172     * @private
13173     * @param {Object} object The object to query.
13174     * @param {Array|string} path The path of the property to get.
13175     * @returns {*} Returns the resolved value.
13176     */
13177    function baseGet(object, path) {
13178      path = isKey(path, object) ? [path] : baseCastPath(path);
13179
13180      var index = 0,
13181          length = path.length;
13182
13183      while (object != null && index < length) {
13184        object = object[path[index++]];
13185      }
13186      return (index && index == length) ? object : undefined;
13187    }
13188
13189    /**
13190     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
13191     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
13192     * symbols of `object`.
13193     *
13194     * @private
13195     * @param {Object} object The object to query.
13196     * @param {Function} keysFunc The function to get the keys of `object`.
13197     * @param {Function} symbolsFunc The function to get the symbols of `object`.
13198     * @returns {Array} Returns the array of property names and symbols.
13199     */
13200    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
13201      var result = keysFunc(object);
13202      return isArray(object)
13203        ? result
13204        : arrayPush(result, symbolsFunc(object));
13205    }
13206
13207    /**
13208     * The base implementation of `_.has` without support for deep paths.
13209     *
13210     * @private
13211     * @param {Object} object The object to query.
13212     * @param {Array|string} key The key to check.
13213     * @returns {boolean} Returns `true` if `key` exists, else `false`.
13214     */
13215    function baseHas(object, key) {
13216      // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
13217      // that are composed entirely of index properties, return `false` for
13218      // `hasOwnProperty` checks of them.
13219      return hasOwnProperty.call(object, key) ||
13220        (typeof object == 'object' && key in object && getPrototype(object) === null);
13221    }
13222
13223    /**
13224     * The base implementation of `_.hasIn` without support for deep paths.
13225     *
13226     * @private
13227     * @param {Object} object The object to query.
13228     * @param {Array|string} key The key to check.
13229     * @returns {boolean} Returns `true` if `key` exists, else `false`.
13230     */
13231    function baseHasIn(object, key) {
13232      return key in Object(object);
13233    }
13234
13235    /**
13236     * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
13237     *
13238     * @private
13239     * @param {number} number The number to check.
13240     * @param {number} start The start of the range.
13241     * @param {number} end The end of the range.
13242     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
13243     */
13244    function baseInRange(number, start, end) {
13245      return number >= nativeMin(start, end) && number < nativeMax(start, end);
13246    }
13247
13248    /**
13249     * The base implementation of methods like `_.intersection`, without support
13250     * for iteratee shorthands, that accepts an array of arrays to inspect.
13251     *
13252     * @private
13253     * @param {Array} arrays The arrays to inspect.
13254     * @param {Function} [iteratee] The iteratee invoked per element.
13255     * @param {Function} [comparator] The comparator invoked per element.
13256     * @returns {Array} Returns the new array of shared values.
13257     */
13258    function baseIntersection(arrays, iteratee, comparator) {
13259      var includes = comparator ? arrayIncludesWith : arrayIncludes,
13260          length = arrays[0].length,
13261          othLength = arrays.length,
13262          othIndex = othLength,
13263          caches = Array(othLength),
13264          maxLength = Infinity,
13265          result = [];
13266
13267      while (othIndex--) {
13268        var array = arrays[othIndex];
13269        if (othIndex && iteratee) {
13270          array = arrayMap(array, baseUnary(iteratee));
13271        }
13272        maxLength = nativeMin(array.length, maxLength);
13273        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
13274          ? new SetCache(othIndex && array)
13275          : undefined;
13276      }
13277      array = arrays[0];
13278
13279      var index = -1,
13280          seen = caches[0];
13281
13282      outer:
13283      while (++index < length && result.length < maxLength) {
13284        var value = array[index],
13285            computed = iteratee ? iteratee(value) : value;
13286
13287        if (!(seen
13288              ? cacheHas(seen, computed)
13289              : includes(result, computed, comparator)
13290            )) {
13291          othIndex = othLength;
13292          while (--othIndex) {
13293            var cache = caches[othIndex];
13294            if (!(cache
13295                  ? cacheHas(cache, computed)
13296                  : includes(arrays[othIndex], computed, comparator))
13297                ) {
13298              continue outer;
13299            }
13300          }
13301          if (seen) {
13302            seen.push(computed);
13303          }
13304          result.push(value);
13305        }
13306      }
13307      return result;
13308    }
13309
13310    /**
13311     * The base implementation of `_.invert` and `_.invertBy` which inverts
13312     * `object` with values transformed by `iteratee` and set by `setter`.
13313     *
13314     * @private
13315     * @param {Object} object The object to iterate over.
13316     * @param {Function} setter The function to set `accumulator` values.
13317     * @param {Function} iteratee The iteratee to transform values.
13318     * @param {Object} accumulator The initial inverted object.
13319     * @returns {Function} Returns `accumulator`.
13320     */
13321    function baseInverter(object, setter, iteratee, accumulator) {
13322      baseForOwn(object, function(value, key, object) {
13323        setter(accumulator, iteratee(value), key, object);
13324      });
13325      return accumulator;
13326    }
13327
13328    /**
13329     * The base implementation of `_.invoke` without support for individual
13330     * method arguments.
13331     *
13332     * @private
13333     * @param {Object} object The object to query.
13334     * @param {Array|string} path The path of the method to invoke.
13335     * @param {Array} args The arguments to invoke the method with.
13336     * @returns {*} Returns the result of the invoked method.
13337     */
13338    function baseInvoke(object, path, args) {
13339      if (!isKey(path, object)) {
13340        path = baseCastPath(path);
13341        object = parent(object, path);
13342        path = last(path);
13343      }
13344      var func = object == null ? object : object[path];
13345      return func == null ? undefined : apply(func, object, args);
13346    }
13347
13348    /**
13349     * The base implementation of `_.isEqual` which supports partial comparisons
13350     * and tracks traversed objects.
13351     *
13352     * @private
13353     * @param {*} value The value to compare.
13354     * @param {*} other The other value to compare.
13355     * @param {Function} [customizer] The function to customize comparisons.
13356     * @param {boolean} [bitmask] The bitmask of comparison flags.
13357     *  The bitmask may be composed of the following flags:
13358     *     1 - Unordered comparison
13359     *     2 - Partial comparison
13360     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
13361     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
13362     */
13363    function baseIsEqual(value, other, customizer, bitmask, stack) {
13364      if (value === other) {
13365        return true;
13366      }
13367      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
13368        return value !== value && other !== other;
13369      }
13370      return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
13371    }
13372
13373    /**
13374     * A specialized version of `baseIsEqual` for arrays and objects which performs
13375     * deep comparisons and tracks traversed objects enabling objects with circular
13376     * references to be compared.
13377     *
13378     * @private
13379     * @param {Object} object The object to compare.
13380     * @param {Object} other The other object to compare.
13381     * @param {Function} equalFunc The function to determine equivalents of values.
13382     * @param {Function} [customizer] The function to customize comparisons.
13383     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
13384     *  for more details.
13385     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
13386     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
13387     */
13388    function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
13389      var objIsArr = isArray(object),
13390          othIsArr = isArray(other),
13391          objTag = arrayTag,
13392          othTag = arrayTag;
13393
13394      if (!objIsArr) {
13395        objTag = getTag(object);
13396        objTag = objTag == argsTag ? objectTag : objTag;
13397      }
13398      if (!othIsArr) {
13399        othTag = getTag(other);
13400        othTag = othTag == argsTag ? objectTag : othTag;
13401      }
vendor: 5,075 bytes, lines 13402-13552
13402      var objIsObj = objTag == objectTag && !isHostObject(object),
13403          othIsObj = othTag == objectTag && !isHostObject(other),
13404          isSameTag = objTag == othTag;
13405
13406      if (isSameTag && !objIsObj) {
13407        stack || (stack = new Stack);
13408        return (objIsArr || isTypedArray(object))
13409          ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
13410          : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
13411      }
13412      if (!(bitmask & PARTIAL_COMPARE_FLAG)) {
13413        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
13414            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
13415
13416        if (objIsWrapped || othIsWrapped) {
13417          var objUnwrapped = objIsWrapped ? object.value() : object,
13418              othUnwrapped = othIsWrapped ? other.value() : other;
13419
13420          stack || (stack = new Stack);
13421          return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);
13422        }
13423      }
13424      if (!isSameTag) {
13425        return false;
13426      }
13427      stack || (stack = new Stack);
13428      return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
13429    }
13430
13431    /**
13432     * The base implementation of `_.isMatch` without support for iteratee shorthands.
13433     *
13434     * @private
13435     * @param {Object} object The object to inspect.
13436     * @param {Object} source The object of property values to match.
13437     * @param {Array} matchData The property names, values, and compare flags to match.
13438     * @param {Function} [customizer] The function to customize comparisons.
13439     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
13440     */
13441    function baseIsMatch(object, source, matchData, customizer) {
13442      var index = matchData.length,
13443          length = index,
13444          noCustomizer = !customizer;
13445
13446      if (object == null) {
13447        return !length;
13448      }
13449      object = Object(object);
13450      while (index--) {
13451        var data = matchData[index];
13452        if ((noCustomizer && data[2])
13453              ? data[1] !== object[data[0]]
13454              : !(data[0] in object)
13455            ) {
13456          return false;
13457        }
13458      }
13459      while (++index < length) {
13460        data = matchData[index];
13461        var key = data[0],
13462            objValue = object[key],
13463            srcValue = data[1];
13464
13465        if (noCustomizer && data[2]) {
13466          if (objValue === undefined && !(key in object)) {
13467            return false;
13468          }
13469        } else {
13470          var stack = new Stack;
13471          if (customizer) {
13472            var result = customizer(objValue, srcValue, key, object, source, stack);
13473          }
13474          if (!(result === undefined
13475                ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
13476                : result
13477              )) {
13478            return false;
13479          }
13480        }
13481      }
13482      return true;
13483    }
13484
13485    /**
13486     * The base implementation of `_.iteratee`.
13487     *
13488     * @private
13489     * @param {*} [value=_.identity] The value to convert to an iteratee.
13490     * @returns {Function} Returns the iteratee.
13491     */
13492    function baseIteratee(value) {
13493      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
13494      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
13495      if (typeof value == 'function') {
13496        return value;
13497      }
13498      if (value == null) {
13499        return identity;
13500      }
13501      if (typeof value == 'object') {
13502        return isArray(value)
13503          ? baseMatchesProperty(value[0], value[1])
13504          : baseMatches(value);
13505      }
13506      return property(value);
13507    }
13508
13509    /**
13510     * The base implementation of `_.keys` which doesn't skip the constructor
13511     * property of prototypes or treat sparse arrays as dense.
13512     *
13513     * @private
13514     * @param {Object} object The object to query.
13515     * @returns {Array} Returns the array of property names.
13516     */
13517    function baseKeys(object) {
13518      return nativeKeys(Object(object));
13519    }
13520
13521    /**
13522     * The base implementation of `_.keysIn` which doesn't skip the constructor
13523     * property of prototypes or treat sparse arrays as dense.
13524     *
13525     * @private
13526     * @param {Object} object The object to query.
13527     * @returns {Array} Returns the array of property names.
13528     */
13529    function baseKeysIn(object) {
13530      object = object == null ? object : Object(object);
13531
13532      var result = [];
13533      for (var key in object) {
13534        result.push(key);
13535      }
13536      return result;
13537    }
13538
13539    // Fallback for IE < 9 with es6-shim.
13540    if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
13541      baseKeysIn = function(object) {
13542        return iteratorToArray(enumerate(object));
13543      };
13544    }
13545
13546    /**
13547     * The base implementation of `_.map` without support for iteratee shorthands.
13548     *
13549     * @private
13550     * @param {Array|Object} collection The collection to iterate over.
13551     * @param {Function} iteratee The function invoked per iteration.
13552     * @returns {Array} Returns the new mapped array.
vendor: 4,471 bytes, lines 13553-13681
13553     */
13554    function baseMap(collection, iteratee) {
13555      var index = -1,
13556          result = isArrayLike(collection) ? Array(collection.length) : [];
13557
13558      baseEach(collection, function(value, key, collection) {
13559        result[++index] = iteratee(value, key, collection);
13560      });
13561      return result;
13562    }
13563
13564    /**
13565     * The base implementation of `_.matches` which doesn't clone `source`.
13566     *
13567     * @private
13568     * @param {Object} source The object of property values to match.
13569     * @returns {Function} Returns the new function.
13570     */
13571    function baseMatches(source) {
13572      var matchData = getMatchData(source);
13573      if (matchData.length == 1 && matchData[0][2]) {
13574        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
13575      }
13576      return function(object) {
13577        return object === source || baseIsMatch(object, source, matchData);
13578      };
13579    }
13580
13581    /**
13582     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
13583     *
13584     * @private
13585     * @param {string} path The path of the property to get.
13586     * @param {*} srcValue The value to match.
13587     * @returns {Function} Returns the new function.
13588     */
13589    function baseMatchesProperty(path, srcValue) {
13590      if (isKey(path) && isStrictComparable(srcValue)) {
13591        return matchesStrictComparable(path, srcValue);
13592      }
13593      return function(object) {
13594        var objValue = get(object, path);
13595        return (objValue === undefined && objValue === srcValue)
13596          ? hasIn(object, path)
13597          : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
13598      };
13599    }
13600
13601    /**
13602     * The base implementation of `_.merge` without support for multiple sources.
13603     *
13604     * @private
13605     * @param {Object} object The destination object.
13606     * @param {Object} source The source object.
13607     * @param {number} srcIndex The index of `source`.
13608     * @param {Function} [customizer] The function to customize merged values.
13609     * @param {Object} [stack] Tracks traversed source values and their merged
13610     *  counterparts.
13611     */
13612    function baseMerge(object, source, srcIndex, customizer, stack) {
13613      if (object === source) {
13614        return;
13615      }
13616      if (!(isArray(source) || isTypedArray(source))) {
13617        var props = keysIn(source);
13618      }
13619      arrayEach(props || source, function(srcValue, key) {
13620        if (props) {
13621          key = srcValue;
13622          srcValue = source[key];
13623        }
13624        if (isObject(srcValue)) {
13625          stack || (stack = new Stack);
13626          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
13627        }
13628        else {
13629          var newValue = customizer
13630            ? customizer(object[key], srcValue, (key + ''), object, source, stack)
13631            : undefined;
13632
13633          if (newValue === undefined) {
13634            newValue = srcValue;
13635          }
13636          assignMergeValue(object, key, newValue);
13637        }
13638      });
13639    }
13640
13641    /**
13642     * A specialized version of `baseMerge` for arrays and objects which performs
13643     * deep merges and tracks traversed objects enabling objects with circular
13644     * references to be merged.
13645     *
13646     * @private
13647     * @param {Object} object The destination object.
13648     * @param {Object} source The source object.
13649     * @param {string} key The key of the value to merge.
13650     * @param {number} srcIndex The index of `source`.
13651     * @param {Function} mergeFunc The function to merge values.
13652     * @param {Function} [customizer] The function to customize assigned values.
13653     * @param {Object} [stack] Tracks traversed source values and their merged
13654     *  counterparts.
13655     */
13656    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
13657      var objValue = object[key],
13658          srcValue = source[key],
13659          stacked = stack.get(srcValue);
13660
13661      if (stacked) {
13662        assignMergeValue(object, key, stacked);
13663        return;
13664      }
13665      var newValue = customizer
13666        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
13667        : undefined;
13668
13669      var isCommon = newValue === undefined;
13670
13671      if (isCommon) {
13672        newValue = srcValue;
13673        if (isArray(srcValue) || isTypedArray(srcValue)) {
13674          if (isArray(objValue)) {
13675            newValue = objValue;
13676          }
13677          else if (isArrayLikeObject(objValue)) {
13678            newValue = copyArray(objValue);
13679          }
13680          else {
13681            isCommon = false;
13682            newValue = baseClone(srcValue, true);
13683          }
13684        }
13685        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
13686          if (isArguments(objValue)) {
13687            newValue = toPlainObject(objValue);
13688          }
13689          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
13690            isCommon = false;
13691            newValue = baseClone(srcValue, true);
13692          }
13693          else {
13694            newValue = objValue;
13695          }
13696        }
13697        else {
13698          isCommon = false;
13699        }
13700      }
13701      stack.set(srcValue, newValue);
13702
13703      if (isCommon) {
13704        // Recursively merge objects and arrays (susceptible to call stack limits).
13705        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
13706      }
13707      stack['delete'](srcValue);
13708      assignMergeValue(object, key, newValue);
13709    }
13710
13711    /**
13712     * The base implementation of `_.orderBy` without param guards.
13713     *
13714     * @private
13715     * @param {Array|Object} collection The collection to iterate over.
13716     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
13717     * @param {string[]} orders The sort orders of `iteratees`.
13718     * @returns {Array} Returns the new sorted array.
13719     */
13720    function baseOrderBy(collection, iteratees, orders) {
13721      var index = -1;
13722      iteratees = arrayMap(iteratees.length ? iteratees : [identity], getIteratee());
13723
13724      var result = baseMap(collection, function(value, key, collection) {
13725        var criteria = arrayMap(iteratees, function(iteratee) {
13726          return iteratee(value);
13727        });
13728        return { 'criteria': criteria, 'index': ++index, 'value': value };
13729      });
13730
13731      return baseSortBy(result, function(object, other) {
13732        return compareMultiple(object, other, orders);
13733      });
13734    }
13735
13736    /**
13737     * The base implementation of `_.pick` without support for individual
13738     * property identifiers.
13739     *
13740     * @private
13741     * @param {Object} object The source object.
13742     * @param {string[]} props The property identifiers to pick.
13743     * @returns {Object} Returns the new object.
13744     */
13745    function basePick(object, props) {
13746      object = Object(object);
13747      return arrayReduce(props, function(result, key) {
13748        if (key in object) {
13749          result[key] = object[key];
13750        }
13751        return result;
13752      }, {});
13753    }
13754
13755    /**
13756     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
13757     *
13758     * @private
13759     * @param {Object} object The source object.
13760     * @param {Function} predicate The function invoked per property.
13761     * @returns {Object} Returns the new object.
13762     */
13763    function basePickBy(object, predicate) {
13764      var index = -1,
13765          props = getAllKeysIn(object),
13766          length = props.length,
13767          result = {};
13768
13769      while (++index < length) {
13770        var key = props[index],
13771            value = object[key];
13772
13773        if (predicate(value, key)) {
13774          result[key] = value;
13775        }
13776      }
13777      return result;
13778    }
13779
13780    /**
13781     * The base implementation of `_.property` without support for deep paths.
13782     *
13783     * @private
13784     * @param {string} key The key of the property to get.
13785     * @returns {Function} Returns the new function.
13786     */
13787    function baseProperty(key) {
13788      return function(object) {
13789        return object == null ? undefined : object[key];
13790      };
13791    }
13792
13793    /**
13794     * A specialized version of `baseProperty` which supports deep paths.
13795     *
13796     * @private
13797     * @param {Array|string} path The path of the property to get.
13798     * @returns {Function} Returns the new function.
13799     */
13800    function basePropertyDeep(path) {
13801      return function(object) {
13802        return baseGet(object, path);
13803      };
13804    }
13805
13806    /**
13807     * The base implementation of `_.pullAllBy` without support for iteratee
13808     * shorthands.
13809     *
13810     * @private
13811     * @param {Array} array The array to modify.
13812     * @param {Array} values The values to remove.
13813     * @param {Function} [iteratee] The iteratee invoked per element.
13814     * @param {Function} [comparator] The comparator invoked per element.
13815     * @returns {Array} Returns `array`.
13816     */
13817    function basePullAll(array, values, iteratee, comparator) {
13818      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
13819          index = -1,
13820          length = values.length,
13821          seen = array;
13822
13823      if (iteratee) {
13824        seen = arrayMap(array, baseUnary(iteratee));
13825      }
13826      while (++index < length) {
13827        var fromIndex = 0,
13828            value = values[index],
13829            computed = iteratee ? iteratee(value) : value;
13830
13831        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
13832          if (seen !== array) {
13833            splice.call(seen, fromIndex, 1);
13834          }
13835          splice.call(array, fromIndex, 1);
13836        }
13837      }
13838      return array;
13839    }
13840
13841    /**
13842     * The base implementation of `_.pullAt` without support for individual
13843     * indexes or capturing the removed elements.
13844     *
13845     * @private
13846     * @param {Array} array The array to modify.
13847     * @param {number[]} indexes The indexes of elements to remove.
13848     * @returns {Array} Returns `array`.
13849     */
13850    function basePullAt(array, indexes) {
13851      var length = array ? indexes.length : 0,
13852          lastIndex = length - 1;
13853
13854      while (length--) {
13855        var index = indexes[length];
13856        if (lastIndex == length || index != previous) {
13857          var previous = index;
13858          if (isIndex(index)) {
13859            splice.call(array, index, 1);
13860          }
13861          else if (!isKey(index, array)) {
13862            var path = baseCastPath(index),
13863                object = parent(array, path);
13864
13865            if (object != null) {
13866              delete object[last(path)];
13867            }
13868          }
13869          else {
13870            delete array[index];
13871          }
13872        }
13873      }
13874      return array;
13875    }
13876
13877    /**
13878     * The base implementation of `_.random` without support for returning
13879     * floating-point numbers.
13880     *
13881     * @private
13882     * @param {number} lower The lower bound.
13883     * @param {number} upper The upper bound.
13884     * @returns {number} Returns the random number.
13885     */
13886    function baseRandom(lower, upper) {
13887      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
13888    }
13889
13890    /**
13891     * The base implementation of `_.range` and `_.rangeRight` which doesn't
13892     * coerce arguments to numbers.
13893     *
13894     * @private
13895     * @param {number} start The start of the range.
13896     * @param {number} end The end of the range.
13897     * @param {number} step The value to increment or decrement by.
13898     * @param {boolean} [fromRight] Specify iterating from right to left.
13899     * @returns {Array} Returns the new array of numbers.
13900     */
13901    function baseRange(start, end, step, fromRight) {
13902      var index = -1,
13903          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
13904          result = Array(length);
13905
13906      while (length--) {
13907        result[fromRight ? length : ++index] = start;
13908        start += step;
13909      }
13910      return result;
13911    }
13912
13913    /**
13914     * The base implementation of `_.repeat` which doesn't coerce arguments.
13915     *
13916     * @private
13917     * @param {string} string The string to repeat.
13918     * @param {number} n The number of times to repeat the string.
13919     * @returns {string} Returns the repeated string.
13920     */
13921    function baseRepeat(string, n) {
13922      var result = '';
13923      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
13924        return result;
13925      }
13926      // Leverage the exponentiation by squaring algorithm for a faster repeat.
13927      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
13928      do {
13929        if (n % 2) {
13930          result += string;
13931        }
13932        n = nativeFloor(n / 2);
13933        if (n) {
13934          string += string;
13935        }
13936      } while (n);
13937
13938      return result;
13939    }
13940
13941    /**
13942     * The base implementation of `_.set`.
13943     *
13944     * @private
13945     * @param {Object} object The object to query.
13946     * @param {Array|string} path The path of the property to set.
13947     * @param {*} value The value to set.
13948     * @param {Function} [customizer] The function to customize path creation.
13949     * @returns {Object} Returns `object`.
13950     */
13951    function baseSet(object, path, value, customizer) {
13952      path = isKey(path, object) ? [path] : baseCastPath(path);
13953
13954      var index = -1,
13955          length = path.length,
13956          lastIndex = length - 1,
13957          nested = object;
13958
13959      while (nested != null && ++index < length) {
13960        var key = path[index];
13961        if (isObject(nested)) {
13962          var newValue = value;
13963          if (index != lastIndex) {
13964            var objValue = nested[key];
13965            newValue = customizer ? customizer(objValue, key, nested) : undefined;
13966            if (newValue === undefined) {
13967              newValue = objValue == null
13968                ? (isIndex(path[index + 1]) ? [] : {})
13969                : objValue;
13970            }
13971          }
13972          assignValue(nested, key, newValue);
13973        }
13974        nested = nested[key];
13975      }
13976      return object;
13977    }
13978
13979    /**
13980     * The base implementation of `setData` without support for hot loop detection.
13981     *
13982     * @private
13983     * @param {Function} func The function to associate metadata with.
13984     * @param {*} data The metadata.
13985     * @returns {Function} Returns `func`.
13986     */
13987    var baseSetData = !metaMap ? identity : function(func, data) {
13988      metaMap.set(func, data);
13989      return func;
13990    };
13991
13992    /**
13993     * The base implementation of `_.slice` without an iteratee call guard.
13994     *
13995     * @private
13996     * @param {Array} array The array to slice.
13997     * @param {number} [start=0] The start position.
13998     * @param {number} [end=array.length] The end position.
13999     * @returns {Array} Returns the slice of `array`.
14000     */
14001    function baseSlice(array, start, end) {
14002      var index = -1,
14003          length = array.length;
14004
14005      if (start < 0) {
14006        start = -start > length ? 0 : (length + start);
14007      }
14008      end = end > length ? length : end;
14009      if (end < 0) {
14010        end += length;
14011      }
14012      length = start > end ? 0 : ((end - start) >>> 0);
14013      start >>>= 0;
14014
14015      var result = Array(length);
14016      while (++index < length) {
14017        result[index] = array[index + start];
14018      }
14019      return result;
14020    }
14021
14022    /**
14023     * The base implementation of `_.some` without support for iteratee shorthands.
14024     *
14025     * @private
14026     * @param {Array|Object} collection The collection to iterate over.
14027     * @param {Function} predicate The function invoked per iteration.
14028     * @returns {boolean} Returns `true` if any element passes the predicate check,
14029     *  else `false`.
14030     */
14031    function baseSome(collection, predicate) {
14032      var result;
14033
14034      baseEach(collection, function(value, index, collection) {
14035        result = predicate(value, index, collection);
14036        return !result;
14037      });
14038      return !!result;
14039    }
14040
14041    /**
14042     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
14043     * performs a binary search of `array` to determine the index at which `value`
14044     * should be inserted into `array` in order to maintain its sort order.
14045     *
14046     * @private
14047     * @param {Array} array The sorted array to inspect.
14048     * @param {*} value The value to evaluate.
14049     * @param {boolean} [retHighest] Specify returning the highest qualified index.
14050     * @returns {number} Returns the index at which `value` should be inserted
14051     *  into `array`.
14052     */
14053    function baseSortedIndex(array, value, retHighest) {
14054      var low = 0,
14055          high = array ? array.length : low;
14056
14057      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
14058        while (low < high) {
14059          var mid = (low + high) >>> 1,
14060              computed = array[mid];
14061
14062          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
14063            low = mid + 1;
14064          } else {
14065            high = mid;
14066          }
14067        }
14068        return high;
14069      }
14070      return baseSortedIndexBy(array, value, identity, retHighest);
14071    }
14072
14073    /**
14074     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
14075     * which invokes `iteratee` for `value` and each element of `array` to compute
14076     * their sort ranking. The iteratee is invoked with one argument; (value).
14077     *
14078     * @private
14079     * @param {Array} array The sorted array to inspect.
14080     * @param {*} value The value to evaluate.
14081     * @param {Function} iteratee The iteratee invoked per element.
14082     * @param {boolean} [retHighest] Specify returning the highest qualified index.
14083     * @returns {number} Returns the index at which `value` should be inserted
14084     *  into `array`.
14085     */
14086    function baseSortedIndexBy(array, value, iteratee, retHighest) {
14087      value = iteratee(value);
14088
14089      var low = 0,
14090          high = array ? array.length : 0,
14091          valIsNaN = value !== value,
14092          valIsNull = value === null,
14093          valIsUndef = value === undefined;
14094
14095      while (low < high) {
14096        var mid = nativeFloor((low + high) / 2),
14097            computed = iteratee(array[mid]),
14098            isDef = computed !== undefined,
14099            isReflexive = computed === computed;
14100
14101        if (valIsNaN) {
14102          var setLow = isReflexive || retHighest;
14103        } else if (valIsNull) {
14104          setLow = isReflexive && isDef && (retHighest || computed != null);
14105        } else if (valIsUndef) {
14106          setLow = isReflexive && (retHighest || isDef);
14107        } else if (computed == null) {
14108          setLow = false;
14109        } else {
14110          setLow = retHighest ? (computed <= value) : (computed < value);
14111        }
14112        if (setLow) {
14113          low = mid + 1;
14114        } else {
14115          high = mid;
14116        }
14117      }
14118      return nativeMin(high, MAX_ARRAY_INDEX);
14119    }
14120
14121    /**
14122     * The base implementation of `_.sortedUniq`.
14123     *
14124     * @private
14125     * @param {Array} array The array to inspect.
14126     * @returns {Array} Returns the new duplicate free array.
14127     */
14128    function baseSortedUniq(array) {
14129      return baseSortedUniqBy(array);
14130    }
14131
14132    /**
14133     * The base implementation of `_.sortedUniqBy` without support for iteratee
14134     * shorthands.
14135     *
14136     * @private
14137     * @param {Array} array The array to inspect.
14138     * @param {Function} [iteratee] The iteratee invoked per element.
14139     * @returns {Array} Returns the new duplicate free array.
14140     */
14141    function baseSortedUniqBy(array, iteratee) {
14142      var index = 0,
14143          length = array.length,
14144          value = array[0],
14145          computed = iteratee ? iteratee(value) : value,
14146          seen = computed,
14147          resIndex = 1,
14148          result = [value];
14149
14150      while (++index < length) {
14151        value = array[index],
14152        computed = iteratee ? iteratee(value) : value;
14153
14154        if (!eq(computed, seen)) {
14155          seen = computed;
14156          result[resIndex++] = value;
14157        }
14158      }
14159      return result;
14160    }
14161
14162    /**
14163     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
14164     *
14165     * @private
14166     * @param {Array} array The array to inspect.
14167     * @param {Function} [iteratee] The iteratee invoked per element.
14168     * @param {Function} [comparator] The comparator invoked per element.
14169     * @returns {Array} Returns the new duplicate free array.
14170     */
14171    function baseUniq(array, iteratee, comparator) {
14172      var index = -1,
14173          includes = arrayIncludes,
14174          length = array.length,
14175          isCommon = true,
14176          result = [],
14177          seen = result;
14178
14179      if (comparator) {
14180        isCommon = false;
14181        includes = arrayIncludesWith;
14182      }
14183      else if (length >= LARGE_ARRAY_SIZE) {
14184        var set = iteratee ? null : createSet(array);
14185        if (set) {
14186          return setToArray(set);
14187        }
14188        isCommon = false;
14189        includes = cacheHas;
14190        seen = new SetCache;
14191      }
14192      else {
14193        seen = iteratee ? [] : result;
14194      }
14195      outer:
14196      while (++index < length) {
14197        var value = array[index],
14198            computed = iteratee ? iteratee(value) : value;
14199
14200        if (isCommon && computed === computed) {
14201          var seenIndex = seen.length;
14202          while (seenIndex--) {
14203            if (seen[seenIndex] === computed) {
14204              continue outer;
14205            }
14206          }
14207          if (iteratee) {
14208            seen.push(computed);
14209          }
14210          result.push(value);
14211        }
14212        else if (!includes(seen, computed, comparator)) {
14213          if (seen !== result) {
14214            seen.push(computed);
14215          }
14216          result.push(value);
14217        }
14218      }
14219      return result;
14220    }
14221
14222    /**
14223     * The base implementation of `_.unset`.
14224     *
14225     * @private
14226     * @param {Object} object The object to modify.
14227     * @param {Array|string} path The path of the property to unset.
14228     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
14229     */
14230    function baseUnset(object, path) {
14231      path = isKey(path, object) ? [path] : baseCastPath(path);
14232      object = parent(object, path);
14233      var key = last(path);
14234      return (object != null && has(object, key)) ? delete object[key] : true;
14235    }
14236
14237    /**
14238     * The base implementation of `_.update`.
14239     *
14240     * @private
14241     * @param {Object} object The object to query.
14242     * @param {Array|string} path The path of the property to update.
14243     * @param {Function} updater The function to produce the updated value.
14244     * @param {Function} [customizer] The function to customize path creation.
14245     * @returns {Object} Returns `object`.
14246     */
14247    function baseUpdate(object, path, updater, customizer) {
14248      return baseSet(object, path, updater(baseGet(object, path)), customizer);
14249    }
14250
14251    /**
14252     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
14253     * without support for iteratee shorthands.
14254     *
14255     * @private
14256     * @param {Array} array The array to query.
14257     * @param {Function} predicate The function invoked per iteration.
14258     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
14259     * @param {boolean} [fromRight] Specify iterating from right to left.
14260     * @returns {Array} Returns the slice of `array`.
14261     */
14262    function baseWhile(array, predicate, isDrop, fromRight) {
14263      var length = array.length,
14264          index = fromRight ? length : -1;
14265
14266      while ((fromRight ? index-- : ++index < length) &&
14267        predicate(array[index], index, array)) {}
14268
14269      return isDrop
14270        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
14271        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
14272    }
14273
14274    /**
14275     * The base implementation of `wrapperValue` which returns the result of
14276     * performing a sequence of actions on the unwrapped `value`, where each
14277     * successive action is supplied the return value of the previous.
14278     *
14279     * @private
14280     * @param {*} value The unwrapped value.
14281     * @param {Array} actions Actions to perform to resolve the unwrapped value.
14282     * @returns {*} Returns the resolved value.
14283     */
14284    function baseWrapperValue(value, actions) {
14285      var result = value;
14286      if (result instanceof LazyWrapper) {
14287        result = result.value();
14288      }
14289      return arrayReduce(actions, function(result, action) {
14290        return action.func.apply(action.thisArg, arrayPush([result], action.args
14290));
14291      }, result);
14292    }
14293
14294    /**
14295     * The base implementation of methods like `_.xor`, without support for
14296     * iteratee shorthands, that accepts an array of arrays to inspect.
14297     *
14298     * @private
14299     * @param {Array} arrays The arrays to inspect.
14300     * @param {Function} [iteratee] The iteratee invoked per element.
14301     * @param {Function} [comparator] The comparator invoked per element.
14302     * @returns {Array} Returns the new array of values.
14303     */
14304    function baseXor(arrays, iteratee, comparator) {
14305      var index = -1,
14306          length = arrays.length;
14307
14308      while (++index < length) {
14309        var result = result
14310          ? arrayPush(
14311              baseDifference(result, arrays[index], iteratee, comparator),
14312              baseDifference(arrays[index], result, iteratee, comparator)
14313            )
14314          : arrays[index];
14315      }
14316      return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
14317    }
14318
14319    /**
14320     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
14321     *
14322     * @private
14323     * @param {Array} props The property identifiers.
14324     * @param {Array} values The property values.
14325     * @param {Function} assignFunc The function to assign values.
14326     * @returns {Object} Returns the new object.
14327     */
14328    function baseZipObject(props, values, assignFunc) {
14329      var index = -1,
14330          length = props.length,
14331          valsLength = values.length,
14332          result = {};
14333
14334      while (++index < length) {
14335        var value = index < valsLength ? values[index] : undefined;
14336        assignFunc(result, props[index], value);
14337      }
14338      return result;
14339    }
14340
14341    /**
14342     * Creates a clone of  `buffer`.
14343     *
14344     * @private
14345     * @param {Buffer} buffer The buffer to clone.
14346     * @param {boolean} [isDeep] Specify a deep clone.
14347     * @returns {Buffer} Returns the cloned buffer.
14348     */
14349    function cloneBuffer(buffer, isDeep) {
14350      if (isDeep) {
14351        return buffer.slice();
14352      }
14353      var result = new buffer.constructor(buffer.length);
14354      buffer.copy(result);
14355      return result;
14356    }
14357
14358    /**
14359     * Creates a clone of `arrayBuffer`.
14360     *
14361     * @private
14362     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
14363     * @returns {ArrayBuffer} Returns the cloned array buffer.
14364     */
14365    function cloneArrayBuffer(arrayBuffer) {
14366      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
14367      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
14368      return result;
14369    }
14370
14371    /**
14372     * Creates a clone of `dataView`.
14373     *
14374     * @private
14375     * @param {Object} dataView The data view to clone.
14376     * @param {boolean} [isDeep] Specify a deep clone.
14377     * @returns {Object} Returns the cloned data view.
14378     */
14379    function cloneDataView(dataView, isDeep) {
14380      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
14381      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
14382    }
14383
14384    /**
14385     * Creates a clone of `map`.
14386     *
14387     * @private
14388     * @param {Object} map The map to clone.
14389     * @param {Function} cloneFunc The function to clone values.
14390     * @param {boolean} [isDeep] Specify a deep clone.
14391     * @returns {Object} Returns the cloned map.
14392     */
14393    function cloneMap(map, isDeep, cloneFunc) {
14394      var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
14395      return arrayReduce(array, addMapEntry, new map.constructor);
14396    }
14397
14398    /**
14399     * Creates a clone of `regexp`.
14400     *
14401     * @private
14402     * @param {Object} regexp The regexp to clone.
14403     * @returns {Object} Returns the cloned regexp.
14404     */
14405    function cloneRegExp(regexp) {
14406      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
14407      result.lastIndex = regexp.lastIndex;
14408      return result;
14409    }
14410
14411    /**
14412     * Creates a clone of `set`.
14413     *
14414     * @private
14415     * @param {Object} set The set to clone.
14416     * @param {Function} cloneFunc The function to clone values.
14417     * @param {boolean} [isDeep] Specify a deep clone.
14418     * @returns {Object} Returns the cloned set.
14419     */
14420    function cloneSet(set, isDeep, cloneFunc) {
14421      var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
14422      return arrayReduce(array, addSetEntry, new set.constructor);
14423    }
14424
14425    /**
14426     * Creates a clone of the `symbol` object.
14427     *
14428     * @private
14429     * @param {Object} symbol The symbol object to clone.
14430     * @returns {Object} Returns the cloned symbol object.
14431     */
14432    function cloneSymbol(symbol) {
14433      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
14434    }
14435
14436    /**
14437     * Creates a clone of `typedArray`.
14438     *
14439     * @private
14440     * @param {Object} typedArray The typed array to clone.
14441     * @param {boolean} [isDeep] Specify a deep clone.
14442     * @returns {Object} Returns the cloned typed array.
vendor: 5,086 bytes, lines 14443-14590
14443     */
14444    function cloneTypedArray(typedArray, isDeep) {
14445      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
14446      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
14447    }
14448
14449    /**
14450     * Creates an array that is the composition of partially applied arguments,
14451     * placeholders, and provided arguments into a single array of arguments.
14452     *
14453     * @private
14454     * @param {Array|Object} args The provided arguments.
14455     * @param {Array} partials The arguments to prepend to those provided.
14456     * @param {Array} holders The `partials` placeholder indexes.
14457     * @params {boolean} [isCurried] Specify composing for a curried function.
14458     * @returns {Array} Returns the new array of composed arguments.
14459     */
14460    function composeArgs(args, partials, holders, isCurried) {
14461      var argsIndex = -1,
14462          argsLength = args.length,
14463          holdersLength = holders.length,
14464          leftIndex = -1,
14465          leftLength = partials.length,
14466          rangeLength = nativeMax(argsLength - holdersLength, 0),
14467          result = Array(leftLength + rangeLength),
14468          isUncurried = !isCurried;
14469
14470      while (++leftIndex < leftLength) {
14471        result[leftIndex] = partials[leftIndex];
14472      }
14473      while (++argsIndex < holdersLength) {
14474        if (isUncurried || argsIndex < argsLength) {
14475          result[holders[argsIndex]] = args[argsIndex];
14476        }
14477      }
14478      while (rangeLength--) {
14479        result[leftIndex++] = args[argsIndex++];
14480      }
14481      return result;
14482    }
14483
14484    /**
14485     * This function is like `composeArgs` except that the arguments composition
14486     * is tailored for `_.partialRight`.
14487     *
14488     * @private
14489     * @param {Array|Object} args The provided arguments.
14490     * @param {Array} partials The arguments to append to those provided.
14491     * @param {Array} holders The `partials` placeholder indexes.
14492     * @params {boolean} [isCurried] Specify composing for a curried function.
14493     * @returns {Array} Returns the new array of composed arguments.
14494     */
14495    function composeArgsRight(args, partials, holders, isCurried) {
14496      var argsIndex = -1,
14497          argsLength = args.length,
14498          holdersIndex = -1,
14499          holdersLength = holders.length,
14500          rightIndex = -1,
14501          rightLength = partials.length,
14502          rangeLength = nativeMax(argsLength - holdersLength, 0),
14503          result = Array(rangeLength + rightLength),
14504          isUncurried = !isCurried;
14505
14506      while (++argsIndex < rangeLength) {
14507        result[argsIndex] = args[argsIndex];
14508      }
14509      var offset = argsIndex;
14510      while (++rightIndex < rightLength) {
14511        result[offset + rightIndex] = partials[rightIndex];
14512      }
14513      while (++holdersIndex < holdersLength) {
14514        if (isUncurried || argsIndex < argsLength) {
14515          result[offset + holders[holdersIndex]] = args[argsIndex++];
14516        }
14517      }
14518      return result;
14519    }
14520
14521    /**
14522     * Copies the values of `source` to `array`.
14523     *
14524     * @private
14525     * @param {Array} source The array to copy values from.
14526     * @param {Array} [array=[]] The array to copy values to.
14527     * @returns {Array} Returns `array`.
14528     */
14529    function copyArray(source, array) {
14530      var index = -1,
14531          length = source.length;
14532
14533      array || (array = Array(length));
14534      while (++index < length) {
14535        array[index] = source[index];
14536      }
14537      return array;
14538    }
14539
14540    /**
14541     * Copies properties of `source` to `object`.
14542     *
14543     * @private
14544     * @param {Object} source The object to copy properties from.
14545     * @param {Array} props The property identifiers to copy.
14546     * @param {Object} [object={}] The object to copy properties to.
14547     * @returns {Object} Returns `object`.
14548     */
14549    function copyObject(source, props, object) {
14550      return copyObjectWith(source, props, object);
14551    }
14552
14553    /**
14554     * This function is like `copyObject` except that it accepts a function to
14555     * customize copied values.
14556     *
14557     * @private
14558     * @param {Object} source The object to copy properties from.
14559     * @param {Array} props The property identifiers to copy.
14560     * @param {Object} [object={}] The object to copy properties to.
14561     * @param {Function} [customizer] The function to customize copied values.
14562     * @returns {Object} Returns `object`.
14563     */
14564    function copyObjectWith(source, props, object, customizer) {
14565      object || (object = {});
14566
14567      var index = -1,
14568          length = props.length;
14569
14570      while (++index < length) {
14571        var key = props[index];
14572
14573        var newValue = customizer
14574          ? customizer(object[key], source[key], key, object, source)
14575          : source[key];
14576
14577        assignValue(object, key, newValue);
14578      }
14579      return object;
14580    }
14581
14582    /**
14583     * Copies own symbol properties of `source` to `object`.
14584     *
14585     * @private
14586     * @param {Object} source The object to copy symbols from.
14587     * @param {Object} [object={}] The object to copy symbols to.
14588     * @returns {Object} Returns `object`.
14589     */
14590    function copySymbols(source, object) {
vendor: 4,388 bytes, lines 14591-14727
14591      return copyObject(source, getSymbols(source), object);
14592    }
14593
14594    /**
14595     * Creates a function like `_.groupBy`.
14596     *
14597     * @private
14598     * @param {Function} setter The function to set accumulator values.
14599     * @param {Function} [initializer] The accumulator object initializer.
14600     * @returns {Function} Returns the new aggregator function.
14601     */
14602    function createAggregator(setter, initializer) {
14603      return function(collection, iteratee) {
14604        var func = isArray(collection) ? arrayAggregator : baseAggregator,
14605            accumulator = initializer ? initializer() : {};
14606
14607        return func(collection, setter, getIteratee(iteratee), accumulator);
14608      };
14609    }
14610
14611    /**
14612     * Creates a function like `_.assign`.
14613     *
14614     * @private
14615     * @param {Function} assigner The function to assign values.
14616     * @returns {Function} Returns the new assigner function.
14617     */
14618    function createAssigner(assigner) {
14619      return rest(function(object, sources) {
14620        var index = -1,
14621            length = sources.length,
14622            customizer = length > 1 ? sources[length - 1] : undefined,
14623            guard = length > 2 ? sources[2] : undefined;
14624
14625        customizer = typeof customizer == 'function'
14626          ? (length--, customizer)
14627          : undefined;
14628
14629        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
14630          customizer = length < 3 ? undefined : customizer;
14631          length = 1;
14632        }
14633        object = Object(object);
14634        while (++index < length) {
14635          var source = sources[index];
14636          if (source) {
14637            assigner(object, source, index, customizer);
14638          }
14639        }
14640        return object;
14641      });
14642    }
14643
14644    /**
14645     * Creates a `baseEach` or `baseEachRight` function.
14646     *
14647     * @private
14648     * @param {Function} eachFunc The function to iterate over a collection.
14649     * @param {boolean} [fromRight] Specify iterating from right to left.
14650     * @returns {Function} Returns the new base function.
14651     */
14652    function createBaseEach(eachFunc, fromRight) {
14653      return function(collection, iteratee) {
14654        if (collection == null) {
14655          return collection;
14656        }
14657        if (!isArrayLike(collection)) {
14658          return eachFunc(collection, iteratee);
14659        }
14660        var length = collection.length,
14661            index = fromRight ? length : -1,
14662            iterable = Object(collection);
14663
14664        while ((fromRight ? index-- : ++index < length)) {
14665          if (iteratee(iterable[index], index, iterable) === false) {
14666            break;
14667          }
14668        }
14669        return collection;
14670      };
14671    }
14672
14673    /**
14674     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
14675     *
14676     * @private
14677     * @param {boolean} [fromRight] Specify iterating from right to left.
14678     * @returns {Function} Returns the new base function.
14679     */
14680    function createBaseFor(fromRight) {
14681      return function(object, iteratee, keysFunc) {
14682        var index = -1,
14683            iterable = Object(object),
14684            props = keysFunc(object),
14685            length = props.length;
14686
14687        while (length--) {
14688          var key = props[fromRight ? length : ++index];
14689          if (iteratee(iterable[key], key, iterable) === false) {
14690            break;
14691          }
14692        }
14693        return object;
14694      };
14695    }
14696
14697    /**
14698     * Creates a function that wraps `func` to invoke it with the optional `this`
14699     * binding of `thisArg`.
14700     *
14701     * @private
14702     * @param {Function} func The function to wrap.
14703     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
14704     *  for more details.
14705     * @param {*} [thisArg] The `this` binding of `func`.
14706     * @returns {Function} Returns the new wrapped function.
14707     */
14708    function createBaseWrapper(func, bitmask, thisArg) {
14709      var isBind = bitmask & BIND_FLAG,
14710          Ctor = createCtorWrapper(func);
14711
14712      function wrapper() {
14713        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
14714        return fn.apply(isBind ? thisArg : this, arguments);
14715      }
14716      return wrapper;
14717    }
14718
14719    /**
14720     * Creates a function like `_.lowerFirst`.
14721     *
14722     * @private
14723     * @param {string} methodName The name of the `String` case method to use.
14724     * @returns {Function} Returns the new function.
14725     */
14726    function createCaseFirst(methodName) {
14727      return function(string) {
vendor: 4,791 bytes, lines 14728-14862
14728        string = toString(string);
14729
14730        var strSymbols = reHasComplexSymbol.test(string)
14731          ? stringToArray(string)
14732          : undefined;
14733
14734        var chr = strSymbols ? strSymbols[0] : string.charAt(0),
14735            trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
14736
14737        return chr[methodName]() + trailing;
14738      };
14739    }
14740
14741    /**
14742     * Creates a function like `_.camelCase`.
14743     *
14744     * @private
14745     * @param {Function} callback The function to combine each word.
14746     * @returns {Function} Returns the new compounder function.
14747     */
14748    function createCompounder(callback) {
14749      return function(string) {
14750        return arrayReduce(words(deburr(string)), callback, '');
14751      };
14752    }
14753
14754    /**
14755     * Creates a function that produces an instance of `Ctor` regardless of
14756     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
14757     *
14758     * @private
14759     * @param {Function} Ctor The constructor to wrap.
14760     * @returns {Function} Returns the new wrapped function.
14761     */
14762    function createCtorWrapper(Ctor) {
14763      return function() {
14764        // Use a `switch` statement to work with class constructors. See
14765        // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
14766        // for more details.
14767        var args = arguments;
14768        switch (args.length) {
14769          case 0: return new Ctor;
14770          case 1: return new Ctor(args[0]);
14771          case 2: return new Ctor(args[0], args[1]);
14772          case 3: return new Ctor(args[0], args[1], args[2]);
14773          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
14774          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
14775          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
14776          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
14777        }
14778        var thisBinding = baseCreate(Ctor.prototype),
14779            result = Ctor.apply(thisBinding, args);
14780
14781        // Mimic the constructor's `return` behavior.
14782        // See https://es5.github.io/#x13.2.2 for more details.
14783        return isObject(result) ? result : thisBinding;
14784      };
14785    }
14786
14787    /**
14788     * Creates a function that wraps `func` to enable currying.
14789     *
14790     * @private
14791     * @param {Function} func The function to wrap.
14792     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
14793     *  for more details.
14794     * @param {number} arity The arity of `func`.
14795     * @returns {Function} Returns the new wrapped function.
14796     */
14797    function createCurryWrapper(func, bitmask, arity) {
14798      var Ctor = createCtorWrapper(func);
14799
14800      function wrapper() {
14801        var length = arguments.length,
14802            args = Array(length),
14803            index = length,
14804            placeholder = getPlaceholder(wrapper);
14805
14806        while (index--) {
14807          args[index] = arguments[index];
14808        }
14809        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
14810          ? []
14811          : replaceHolders(args, placeholder);
14812
14813        length -= holders.length;
14814        if (length < arity) {
14815          return createRecurryWrapper(
14816            func, bitmask, createHybridWrapper, wrapper.placeholder, undefined,
14817            args, holders, undefined, undefined, arity - length);
14818        }
14819        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
14820        return apply(fn, this, args);
14821      }
14822      return wrapper;
14823    }
14824
14825    /**
14826     * Creates a `_.flow` or `_.flowRight` function.
14827     *
14828     * @private
14829     * @param {boolean} [fromRight] Specify iterating from right to left.
14830     * @returns {Function} Returns the new flow function.
14831     */
14832    function createFlow(fromRight) {
14833      return rest(function(funcs) {
14834        funcs = baseFlatten(funcs, 1);
14835
14836        var length = funcs.length,
14837            index = length,
14838            prereq = LodashWrapper.prototype.thru;
14839
14840        if (fromRight) {
14841          funcs.reverse();
14842        }
14843        while (index--) {
14844          var func = funcs[index];
14845          if (typeof func != 'function') {
14846            throw new TypeError(FUNC_ERROR_TEXT);
14847          }
14848          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
14849            var wrapper = new LodashWrapper([], true);
14850          }
14851        }
14852        index = wrapper ? index : length;
14853        while (++index < length) {
14854          func = funcs[index];
14855
14856          var funcName = getFuncName(func),
14857              data = funcName == 'wrapper' ? getData(func) : undefined;
14858
14859          if (data && isLaziable(data[0]) &&
14860                data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
14861                !data[4].length && data[9] == 1
14862              ) {
vendor: 5,355 bytes, lines 14863-15011
14863            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
14864          } else {
14865            wrapper = (func.length == 1 && isLaziable(func))
14866              ? wrapper[funcName]()
14867              : wrapper.thru(func);
14868          }
14869        }
14870        return function() {
14871          var args = arguments,
14872              value = args[0];
14873
14874          if (wrapper && args.length == 1 &&
14875              isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
14876            return wrapper.plant(value).value();
14877          }
14878          var index = 0,
14879              result = length ? funcs[index].apply(this, args) : value;
14880
14881          while (++index < length) {
14882            result = funcs[index].call(this, result);
14883          }
14884          return result;
14885        };
14886      });
14887    }
14888
14889    /**
14890     * Creates a function that wraps `func` to invoke it with optional `this`
14891     * binding of `thisArg`, partial application, and currying.
14892     *
14893     * @private
14894     * @param {Function|string} func The function or method name to wrap.
14895     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
14896     *  for more details.
14897     * @param {*} [thisArg] The `this` binding of `func`.
14898     * @param {Array} [partials] The arguments to prepend to those provided to
14899     *  the new function.
14900     * @param {Array} [holders] The `partials` placeholder indexes.
14901     * @param {Array} [partialsRight] The arguments to append to those provided
14902     *  to the new function.
14903     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
14904     * @param {Array} [argPos] The argument positions of the new function.
14905     * @param {number} [ary] The arity cap of `func`.
14906     * @param {number} [arity] The arity of `func`.
14907     * @returns {Function} Returns the new wrapped function.
14908     */
14909    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
14910      var isAry = bitmask & ARY_FLAG,
14911          isBind = bitmask & BIND_FLAG,
14912          isBindKey = bitmask & BIND_KEY_FLAG,
14913          isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
14914          isFlip = bitmask & FLIP_FLAG,
14915          Ctor = isBindKey ? undefined : createCtorWrapper(func);
14916
14917      function wrapper() {
14918        var length = arguments.length,
14919            index = length,
14920            args = Array(length);
14921
14922        while (index--) {
14923          args[index] = arguments[index];
14924        }
14925        if (isCurried) {
14926          var placeholder = getPlaceholder(wrapper),
14927              holdersCount = countHolders(args, placeholder);
14928        }
14929        if (partials) {
14930          args = composeArgs(args, partials, holders, isCurried);
14931        }
14932        if (partialsRight) {
14933          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
14934        }
14935        length -= holdersCount;
14936        if (isCurried && length < arity) {
14937          var newHolders = replaceHolders(args, placeholder);
14938          return createRecurryWrapper(
14939            func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg,
14940            args, newHolders, argPos, ary, arity - length
14941          );
14942        }
14943        var thisBinding = isBind ? thisArg : this,
14944            fn = isBindKey ? thisBinding[func] : func;
14945
14946        length = args.length;
14947        if (argPos) {
14948          args = reorder(args, argPos);
14949        } else if (isFlip && length > 1) {
14950          args.reverse();
14951        }
14952        if (isAry && ary < length) {
14953          args.length = ary;
14954        }
14955        if (this && this !== root && this instanceof wrapper) {
14956          fn = Ctor || createCtorWrapper(fn);
14957        }
14958        return fn.apply(thisBinding, args);
14959      }
14960      return wrapper;
14961    }
14962
14963    /**
14964     * Creates a function like `_.invertBy`.
14965     *
14966     * @private
14967     * @param {Function} setter The function to set accumulator values.
14968     * @param {Function} toIteratee The function to resolve iteratees.
14969     * @returns {Function} Returns the new inverter function.
14970     */
14971    function createInverter(setter, toIteratee) {
14972      return function(object, iteratee) {
14973        return baseInverter(object, setter, toIteratee(iteratee), {});
14974      };
14975    }
14976
14977    /**
14978     * Creates a function like `_.over`.
14979     *
14980     * @private
14981     * @param {Function} arrayFunc The function to iterate over iteratees.
14982     * @returns {Function} Returns the new invoker function.
14983     */
14984    function createOver(arrayFunc) {
14985      return rest(function(iteratees) {
14986        iteratees = arrayMap(baseFlatten(iteratees, 1, isFlattenableIteratee), getIteratee());
14987        return rest(function(args) {
14988          var thisArg = this;
14989          return arrayFunc(iteratees, function(iteratee) {
14990            return apply(iteratee, thisArg, args);
14991          });
14992        });
14993      });
14994    }
14995
14996    /**
14997     * Creates the padding for `string` based on `length`. The `chars` string
14998     * is truncated if the number of characters exceeds `length`.
14999     *
15000     * @private
15001     * @param {number} length The padding length.
15002     * @param {string} [chars=' '] The string used as padding.
15003     * @returns {string} Returns the padding for `string`.
15004     */
15005    function createPadding(length, chars) {
15006      chars = chars === undefined ? ' ' : (chars + '');
15007
15008      var charsLength = chars.length;
15009      if (charsLength < 2) {
15010        return charsLength ? baseRepeat(chars, length) : chars;
15011      }
15012      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
15013      return reHasComplexSymbol.test(chars)
15014        ? stringToArray(result).slice(0, length).join('')
15015        : result.slice(0, length);
15016    }
15017
15018    /**
15019     * Creates a function that wraps `func` to invoke it with the `this` binding
15020     * of `thisArg` and `partials` prepended to the arguments it receives.
15021     *
15022     * @private
15023     * @param {Function} func The function to wrap.
15024     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
15025     *  for more details.
15026     * @param {*} thisArg The `this` binding of `func`.
15027     * @param {Array} partials The arguments to prepend to those provided to
15028     *  the new function.
15029     * @returns {Function} Returns the new wrapped function.
15030     */
15031    function createPartialWrapper(func, bitmask, thisArg, partials) {
15032      var isBind = bitmask & BIND_FLAG,
15033          Ctor = createCtorWrapper(func);
15034
15035      function wrapper() {
15036        var argsIndex = -1,
15037            argsLength = arguments.length,
15038            leftIndex = -1,
15039            leftLength = partials.length,
15040            args = Array(leftLength + argsLength),
15041            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
15042
15043        while (++leftIndex < leftLength) {
15044          args[leftIndex] = partials[leftIndex];
15045        }
15046        while (argsLength--) {
15047          args[leftIndex++] = arguments[++argsIndex];
15048        }
15049        return apply(fn, isBind ? thisArg : this, args);
15050      }
15051      return wrapper;
15052    }
15053
15054    /**
15055     * Creates a `_.range` or `_.rangeRight` function.
15056     *
15057     * @private
15058     * @param {boolean} [fromRight] Specify iterating from right to left.
15059     * @returns {Function} Returns the new range function.
15060     */
15061    function createRange(fromRight) {
15062      return function(start, end, step) {
15063        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
15064          end = step = undefined;
15065        }
15066        // Ensure the sign of `-0` is preserved.
15067        start = toNumber(start);
15068        start = start === start ? start : 0;
15069        if (end === undefined) {
15070          end = start;
15071          start = 0;
15072        } else {
15073          end = toNumber(end) || 0;
15074        }
15075        step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
15076        return baseRange(start, end, step, fromRight);
15077      };
15078    }
15079
15080    /**
15081     * Creates a function that wraps `func` to continue currying.
15082     *
15083     * @private
15084     * @param {Function} func The function to wrap.
15085     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
15086     *  for more details.
15087     * @param {Function} wrapFunc The function to create the `func` wrapper.
15088     * @param {*} placeholder The placeholder value.
15089     * @param {*} [thisArg] The `this` binding of `func`.
15090     * @param {Array} [partials] The arguments to prepend to those provided to
15091     *  the new function.
15092     * @param {Array} [holders] The `partials` placeholder indexes.
15093     * @param {Array} [argPos] The argument positions of the new function.
15094     * @param {number} [ary] The arity cap of `func`.
15095     * @param {number} [arity] The arity of `func`.
15096     * @returns {Function} Returns the new wrapped function.
15097     */
15098    function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
15099      var isCurry = bitmask & CURRY_FLAG,
15100          newArgPos = argPos ? copyArray(argPos) : undefined,
15101          newHolders = isCurry ? holders : undefined,
15102          newHoldersRight = isCurry ? undefined : holders,
15103          newPartials = isCurry ? partials : undefined,
15104          newPartialsRight = isCurry ? undefined : partials;
15105
15106      bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
15107      bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
15108
15109      if (!(bitmask & CURRY_BOUND_FLAG)) {
15110        bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
15111      }
15112      var newData = [
15113        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
15114        newHoldersRight, newArgPos, ary, arity
15115      ];
15116
15117      var result = wrapFunc.apply(undefined, newData);
15118      if (isLaziable(func)) {
15119        setData(result, newData);
15120      }
15121      result.placeholder = placeholder;
15122      return result;
15123    }
15124
15125    /**
15126     * Creates a function like `_.round`.
15127     *
15128     * @private
15129     * @param {string} methodName The name of the `Math` method to use when rounding.
15130     * @returns {Function} Returns the new round function.
15131     */
15132    function createRound(methodName) {
15133      var func = Math[methodName];
15134      return function(number, precision) {
15135        number = toNumber(number);
15136        precision = toInteger(precision);
15137        if (precision) {
15138          // Shift with exponential notation to avoid floating-point issues.
15139          // See [MDN](https://mdn.io/round#Examples) for more details.
15140          var pair = (toString(number) + 'e').split('e'),
15141              value = func(pair[0] + 'e' + (+pair[1] + precision));
15142
15143          pair = (toString(value) + 'e').split('e');
15144          return +(pair[0] + 'e' + (+pair[1] - precision));
15145        }
15146        return func(number);
15147      };
15148    }
15149
15150    /**
15151     * Creates a set of `values`.
15152     *
15153     * @private
15154     * @param {Array} values The values to add to the set.
15155     * @returns {Object} Returns the new set.
15156     */
15157    var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
15158      return new Set(values);
15159    };
15160
15161    /**
15162     * Creates a function that either curries or invokes `func` with optional
15163     * `this` binding and partially applied arguments.
15164     *
15165     * @private
15166     * @param {Function|string}
15166 func The function or method name to wrap.
15167     * @param {number} bitmask The bitmask of wrapper flags.
15168     *  The bitmask may be composed of the following flags:
15169     *     1 - `_.bind`
15170     *     2 - `_.bindKey`
15171     *     4 - `_.curry` or `_.curryRight` of a bound function
15172     *     8 - `_.curry`
15173     *    16 - `_.curryRight`
15174     *    32 - `_.partial`
15175     *    64 - `_.partialRight`
15176     *   128 - `_.rearg`
15177     *   256 - `_.ary`
15178     * @param {*} [thisArg] The `this` binding of `func`.
15179     * @param {Array} [partials] The arguments to be partially applied.
15180     * @param {Array} [holders] The `partials` placeholder indexes.
15181     * @param {Array} [argPos] The argument positions of the new function.
15182     * @param {number} [ary] The arity cap of `func`.
15183     * @param {number} [arity] The arity of `func`.
15184     * @returns {Function} Returns the new wrapped function.
15185     */
15186    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
15187      var isBindKey = bitmask & BIND_KEY_FLAG;
15188      if (!isBindKey && typeof func != 'function') {
15189        throw new TypeError(FUNC_ERROR_TEXT);
15190      }
15191      var length = partials ? partials.length : 0;
15192      if (!length) {
15193        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
15194        partials = holders = undefined;
15195      }
15196      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
15197      arity = arity === undefined ? arity : toInteger(arity);
15198      length -= holders ? holders.length : 0;
15199
15200      if (bitmask & PARTIAL_RIGHT_FLAG) {
15201        var partialsRight = partials,
15202            holdersRight = holders;
15203
15204        partials = holders = undefined;
15205      }
15206      var data = isBindKey ? undefined : getData(func);
15207
15208      var newData = [
15209        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
15210        argPos, ary, arity
15211      ];
15212
15213      if (data) {
15214        mergeData(newData, data);
15215      }
15216      func = newData[0];
15217      bitmask = newData[1];
15218      thisArg = newData[2];
15219      partials = newData[3];
15220      holders = newData[4];
15221      arity = newData[9] = newData[9] == null
15222        ? (isBindKey ? 0 : func.length)
15223        : nativeMax(newData[9] - length, 0);
15224
15225      if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
15226        bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
15227      }
15228      if (!bitmask || bitmask == BIND_FLAG) {
15229        var result = createBaseWrapper(func, bitmask, thisArg);
15230      } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
15231        result = createCurryWrapper(func, bitmask, arity);
15232      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
15233        result = createPartialWrapper(func, bitmask, thisArg, partials);
15234      } else {
15235        result = createHybridWrapper.apply(undefined, newData);
15236      }
15237      var setter = data ? baseSetData : setData;
15238      return setter(result, newData);
15239    }
15240
15241    /**
15242     * A specialized version of `baseIsEqualDeep` for arrays with support for
15243     * partial deep comparisons.
15244     *
15245     * @private
15246     * @param {Array} array The array to compare.
15247     * @param {Array} other The other array to compare.
15248     * @param {Function} equalFunc The function to determine equivalents of values.
15249     * @param {Function} customizer The function to customize comparisons.
15250     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
15251     *  for more details.
15252     * @param {Object} stack Tracks traversed `array` and `other` objects.
15253     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
15254     */
15255    function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
15256      var index = -1,
15257          isPartial = bitmask & PARTIAL_COMPARE_FLAG,
15258          isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
15259          arrLength = array.length,
15260          othLength = other.length;
15261
15262      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
15263        return false;
15264      }
15265      // Assume cyclic values are equal.
15266      var stacked = stack.get(array);
15267      if (stacked) {
15268        return stacked == other;
15269      }
15270      var result = true;
15271      stack.set(array, other);
15272
15273      // Ignore non-index properties.
15274      while (++index < arrLength) {
15275        var arrValue = array[index],
15276            othValue = other[index];
15277
15278        if (customizer) {
15279          var compared = isPartial
15280            ? customizer(othValue, arrValue, index, other, array, stack)
15281            : customizer(arrValue, othValue, index, array, other, stack);
15282        }
15283        if (compared !== undefined) {
15284          if (compared) {
15285            continue;
15286          }
15287          result = false;
15288          break;
15289        }
15290        // Recursively compare arrays (susceptible to call stack limits).
15291        if (isUnordered) {
15292          if (!arraySome(other, function(othValue) {
15293                return arrValue === othValue ||
15294                  equalFunc(arrValue, othValue, customizer, bitmask, stack);
15295              })) {
15296            result = false;
15297            break;
15298          }
15299        } else if (!(
15300              arrValue === othValue ||
15301                equalFunc(arrValue, othValue, customizer, bitmask, stack)
15302            )) {
15303          result = false;
15304          break;
15305        }
15306      }
15307      stack['delete'](array);
15308      return result;
15309    }
15310
15311    /**
15312     * A specialized version of `baseIsEqualDeep` for comparing objects of
15313     * the same `toStringTag`.
15314     *
15315     * **Note:** This function only supports comparing values with tags of
15316     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
15317     *
15318     * @private
15319     * @param {Object} object The object to compare.
15320     * @param {Object} other The other object to compare.
15321     * @param {string} tag The `toStringTag` of the objects to compare.
15322     * @param {Function} equalFunc The function to determine equivalents of values.
15323     * @param {Function} customizer The function to customize comparisons.
15324     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
15325     *  for more details.
15326     * @param {Object} stack Tracks traversed `object` and `other` objects.
15327     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
15328     */
15329    function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {
15330      switch (tag) {
15331        case dataViewTag:
15332          if ((object.byteLength != other.byteLength) ||
15333              (object.byteOffset != other.byteOffset)) {
15334            return false;
15335          }
15336          object = object.buffer;
15337          other = other.buffer;
15338
15339        case arrayBufferTag:
15340          if ((object.byteLength != other.byteLength) ||
15341              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
15342            return false;
15343          }
15344          return true;
15345
15346        case boolTag:
15347        case dateTag:
15348          // Coerce dates and booleans to numbers, dates to milliseconds and
15349          // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
15350          // not equal.
15351          return +object == +other;
15352
15353        case errorTag:
15354          return object.name == other.name && object.message == other.message;
15355
15356        case numberTag:
15357          // Treat `NaN` vs. `NaN` as equal.
15358          return (object != +object) ? other != +other : object == +other;
15359
15360        case regexpTag:
15361        case stringTag:
15362          // Coerce regexes to strings and treat strings, primitives and objects,
15363          // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
15364          // for more details.
15365          return object == (other + '');
15366
15367        case mapTag:
15368          var convert = mapToArray;
15369
15370        case setTag:
15371          var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
15372          convert || (convert = setToArray);
15373
15374          if (object.size != other.size && !isPartial) {
15375            return false;
15376          }
15377          // Assume cyclic values are equal.
15378          var stacked = stack.get(object);
15379          if (stacked) {
15380            return stacked == other;
15381          }
15382          bitmask |= UNORDERED_COMPARE_FLAG;
15383          stack.set(object, other);
15384
15385          // Recursively compare objects (susceptible to call stack limits).
15386          return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
15387
15388        case symbolTag:
15389          if (symbolValueOf) {
15390            return symbolValueOf.call(object) == symbolValueOf.call(other);
15391          }
15392      }
15393      return false;
15394    }
15395
15396    /**
15397     * A specialized version of `baseIsEqualDeep` for objects with support for
15398     * partial deep comparisons.
15399     *
15400     * @private
15401     * @param {Object} object The object to compare.
15402     * @param {Object} other The other object to compare.
15403     * @param {Function} equalFunc The function to determine equivalents of values.
15404     * @param {Function} customizer The function to customize comparisons.
15405     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
15406     *  for more details.
15407     * @param {Object} stack Tracks traversed `object` and `other` objects.
15408     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
15409     */
15410    function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
15411      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
vendor: 1,291 bytes, lines 15412-15451
15412          objProps = keys(object),
15413          objLength = objProps.length,
15414          othProps = keys(other),
15415          othLength = othProps.length;
15416
15417      if (objLength != othLength && !isPartial) {
15418        return false;
15419      }
15420      var index = objLength;
15421      while (index--) {
15422        var key = objProps[index];
15423        if (!(isPartial ? key in other : baseHas(other, key))) {
15424          return false;
15425        }
15426      }
15427      // Assume cyclic values are equal.
15428      var stacked = stack.get(object);
15429      if (stacked) {
15430        return stacked == other;
15431      }
15432      var result = true;
15433      stack.set(object, other);
15434
15435      var skipCtor = isPartial;
15436      while (++index < objLength) {
15437        key = objProps[index];
15438        var objValue = object[key],
15439            othValue = other[key];
15440
15441        if (customizer) {
15442          var compared = isPartial
15443            ? customizer(othValue, objValue, key, other, object, stack)
15444            : customizer(objValue, othValue, key, object, other, stack);
15445        }
15446        // Recursively compare objects (susceptible to call stack limits).
15447        if (!(compared === undefined
15448              ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
15449              : compared
15450            )) {
15451          result = false;
15452          break;
15453        }
15454        skipCtor || (skipCtor = key == 'constructor');
15455      }
15456      if (result && !skipCtor) {
15457        var objCtor = object.constructor,
15458            othCtor = other.constructor;
15459
15460        // Non `Object` object instances with different constructors are not equal.
15461        if (objCtor != othCtor &&
15462            ('constructor' in object && 'constructor' in other) &&
15463            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
15464              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
15465          result = false;
15466        }
15467      }
15468      stack['delete'](object);
15469      return result;
15470    }
15471
15472    /**
15473     * Creates an array of own enumerable property names and symbols of `object`.
15474     *
15475     * @private
15476     * @param {Object} object The object to query.
15477     * @returns {Array} Returns the array of property names and symbols.
15478     */
15479    function getAllKeys(object) {
15480      return baseGetAllKeys(object, keys, getSymbols);
15481    }
15482
15483    /**
15484     * Creates an array of own and inherited enumerable property names and
15485     * symbols of `object`.
15486     *
15487     * @private
15488     * @param {Object} object The object to query.
15489     * @returns {Array} Returns the array of property names and symbols.
15490     */
15491    function getAllKeysIn(object) {
15492      return baseGetAllKeys(object, keysIn, getSymbolsIn);
15493    }
15494
15495    /**
15496     * Gets metadata for `func`.
15497     *
15498     * @private
15499     * @param {Function} func The function to query.
15500     * @returns {*} Returns the metadata for `func`.
15501     */
15502    var getData = !metaMap ? noop : function(func) {
15503      return metaMap.get(func);
15504    };
15505
15506    /**
15507     * Gets the name of `func`.
15508     *
15509     * @private
15510     * @param {Function} func The function to query.
15511     * @returns {string} Returns the function name.
15512     */
15513    function getFuncName(func) {
15514      var result = (func.name + ''),
15515          array = realNames[result],
15516          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
15517
15518      while (length--) {
15519        var data = array[length],
15520            otherFunc = data.func;
15521        if (otherFunc == null || otherFunc == func) {
15522          return data.name;
15523        }
15524      }
15525      return result;
15526    }
15527
15528    /**
15529     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
15530     * this function returns the custom method, otherwise it returns `baseIteratee`.
15531     * If arguments are provided, the chosen function is invoked with them and
15532     * its result is returned.
15533     *
15534     * @private
15535     * @param {*} [value] The value to convert to an iteratee.
15536     * @param {number} [arity] The arity of the created iteratee.
15537     * @returns {Function} Returns the chosen function or its result.
15538     */
15539    function getIteratee() {
15540      var result = lodash.iteratee || iteratee;
15541      result = result === iteratee ? baseIteratee : result;
15542      return arguments.length ? result(arguments[0], arguments[1]) : result;
15543    }
15544
15545    /**
15546     * Gets the "length" property value of `object`.
15547     *
15548     * **Note:** This function is used to avoid a
15549     * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
15550     * Safari on at least iOS 8.1-8.3 ARM64.
15551     *
15552     * @private
15553     * @param {Object} object The object to query.
15554     * @returns {*} Returns the "length" value.
15555     */
15556    var getLength = baseProperty('length');
15557
15558    /**
15559     * Gets the property names, values, and compare flags of `object`.
15560     *
15561     * @private
15562     * @param {Object} object The object to query.
15563     * @returns {Array} Returns the match data of `object`.
15564     */
15565    function getMatchData(object) {
15566      var result = toPairs(object),
15567          length = result.length;
15568
15569      while (length--) {
15570        result[length][2] = isStrictComparable(result[length][1]);
15571      }
15572      return result;
15573    }
15574
15575    /**
15576     * Gets the native function at `key` of `object`.
15577     *
15578     * @private
15579     * @param {Object} object The object to query.
15580     * @param {string} key The key of the method to get.
15581     * @returns {*} Returns the function if it's native, else `undefined`.
15582     */
15583    function getNative(object, key) {
15584      var value = object[key];
15585      return isNative(value) ? value : undefined;
15586    }
15587
15588    /**
15589     * Gets the argument placeholder value for `func`.
15590     *
15591     * @private
15592     * @param {Function} func The function to inspect.
15593     * @returns {*} Returns the placeholder value.
15594     */
15595    function getPlaceholder(func) {
15596      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
15597      return object.placeholder;
15598    }
15599
15600    /**
15601     * Gets the `[[Prototype]]` of `value`.
15602     *
15603     * @private
15604     * @param {*} value The value to query.
15605     * @returns {null|Object} Returns the `[[Prototype]]`.
15606     */
15607    function getPrototype(value) {
15608      return nativeGetPrototype(Object(value));
15609    }
15610
15611    /**
15612     * Creates an array of the own enumerable symbol properties of `object`.
15613     *
15614     * @private
15615     * @param {Object} object The object to query.
15616     * @returns {Array} Returns the array of symbols.
15617     */
15618    function getSymbols(object) {
15619      // Coerce `object` to an object to avoid non-object errors in V8.
15620      // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.
15621      return getOwnPropertySymbols(Object(object));
15622    }
15623
15624    // Fallback for IE < 11.
15625    if (!getOwnPropertySymbols) {
15626      getSymbols = function() {
15627        return [];
15628      };
15629    }
15630
15631    /**
15632     * Creates an array of the own and inherited enumerable symbol properties
15633     * of `object`.
15634     *
15635     * @private
15636     * @param {Object} object The object to query.
15637     * @returns {Array} Returns the array of symbols.
15638     */
15639    var getSymbolsIn = !getOwnPropertySymbols ? getSymbols : function(object) {
15640      var result = [];
15641      while (object) {
vendor: 1,705 bytes, lines 15642-15691
15642        arrayPush(result, getSymbols(object));
15643        object = getPrototype(object);
15644      }
15645      return result;
15646    };
15647
15648    /**
15649     * Gets the `toStringTag` of `value`.
15650     *
15651     * @private
15652     * @param {*} value The value to query.
15653     * @returns {string} Returns the `toStringTag`.
15654     */
15655    function getTag(value) {
15656      return objectToString.call(value);
15657    }
15658
15659    // Fallback for data views, maps, sets, and weak maps in IE 11,
15660    // for data views in Edge, and promises in Node.js.
15661    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
15662        (Map && getTag(new Map) != mapTag) ||
15663        (Promise && getTag(Promise.resolve()) != promiseTag) ||
15664        (Set && getTag(new Set) != setTag) ||
15665        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
15666      getTag = function(value) {
15667        var result = objectToString.call(value),
15668            Ctor = result == objectTag ? value.constructor : undefined,
15669            ctorString = Ctor ? toSource(Ctor) : undefined;
15670
15671        if (ctorString) {
15672          switch (ctorString) {
15673            case dataViewCtorString: return dataViewTag;
15674            case mapCtorString: return mapTag;
15675            case promiseCtorString: return promiseTag;
15676            case setCtorString: return setTag;
15677            case weakMapCtorString: return weakMapTag;
15678          }
15679        }
15680        return result;
15681      };
15682    }
15683
15684    /**
15685     * Gets the view, applying any `transforms` to the `start` and `end` positions.
15686     *
15687     * @private
15688     * @param {number} start The start of the view.
15689     * @param {number} end The end of the view.
15690     * @param {Array} transforms The transformations to apply to the view.
15691     * @returns {Object}
15691 Returns an object containing the `start` and `end`
15692     *  positions of the view.
15693     */
15694    function getView(start, end, transforms) {
15695      var index = -1,
15696          length = transforms.length;
15697
15698      while (++index < length) {
15699        var data = transforms[index],
15700            size = data.size;
15701
15702        switch (data.type) {
15703          case 'drop':      start += size; break;
15704          case 'dropRight': end -= size; break;
15705          case 'take':      end = nativeMin(end, start + size); break;
15706          case 'takeRight': start = nativeMax(start, end - size); break;
15707        }
15708      }
15709      return { 'start': start, 'end': end };
15710    }
15711
15712    /**
15713     * Checks if `path` exists on `object`.
15714     *
15715     * @private
15716     * @param {Object} object The object to query.
15717     * @param {Array|string} path The path to check.
15718     * @param {Function} hasFunc The function to check properties.
15719     * @returns {boolean} Returns `true` if `path` exists, else `false`.
15720     */
15721    function hasPath(object, path, hasFunc) {
15722      path = isKey(path, object) ? [path] : baseCastPath(path);
15723
15724      var result,
15725          index = -1,
15726          length = path.length;
15727
15728      while (++index < length) {
15729        var key = path[index];
15730        if (!(result = object != null && hasFunc(object, key))) {
15731          break;
15732        }
15733        object = object[key];
15734      }
15735      if (result) {
15736        return result;
15737      }
15738      var length = object ? object.length : 0;
15739      return !!length && isLength(length) && isIndex(key, length) &&
15740        (isArray(object) || isString(object) || isArguments(object));
15741    }
15742
15743    /**
15744     * Initializes an array clone.
15745     *
15746     * @private
15747     * @param {Array} array The array to clone.
15748     * @returns {Array} Returns the initialized clone.
15749     */
15750    function initCloneArray(array) {
15751      var length = array.length,
15752          result = array.constructor(length);
15753
15754      // Add properties assigned by `RegExp#exec`.
15755      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
15756        result.index = array.index;
15757        result.input = array.input;
15758      }
15759      return result;
15760    }
15761
15762    /**
15763     * Initializes an object clone.
15764     *
15765     * @private
15766     * @param {Object} object The object to clone.
15767     * @returns {Object} Returns the initialized clone.
15768     */
15769    function initCloneObject(object) {
15770      return (typeof object.constructor == 'function' && !isPrototype(object))
15771        ? baseCreate(getPrototype(object))
15772        : {};
15773    }
15774
15775    /**
15776     * Initializes an object clone based on its `toStringTag`.
15777     *
15778     * **Note:** This function only supports cloning values with tags of
15779     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
15780     *
15781     * @private
15782     * @param {Object} object The object to clone.
15783     * @param {string} tag The `toStringTag` of the object to clone.
15784     * @param {Function} cloneFunc The function to clone values.
15785     * @param {boolean} [isDeep] Specify a deep clone.
15786     * @returns {Object} Returns the initialized clone.
15787     */
15788    function initCloneByTag(object, tag, cloneFunc, isDeep) {
15789      var Ctor = object.constructor;
15790      switch (tag) {
15791        case arrayBufferTag:
15792          return cloneArrayBuffer(object);
15793
15794        case boolTag:
15795        case dateTag:
15796          return new Ctor(+object);
15797
15798        case dataViewTag:
15799          return cloneDataView(object, isDeep);
15800
15801        case float32Tag: case float64Tag:
15802        case int8Tag: case int16Tag: case int32Tag:
15803        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
15804          return cloneTypedArray(object, isDeep);
15805
15806        case mapTag:
15807          return cloneMap(object, isDeep, cloneFunc);
15808
15809        case numberTag:
15810        case stringTag:
15811          return new Ctor(object);
15812
15813        case regexpTag:
15814          return cloneRegExp(object);
15815
15816        case setTag:
15817          return cloneSet(object, isDeep, cloneFunc);
15818
15819        case symbolTag:
15820          return cloneSymbol(object);
15821      }
15822    }
15823
15824    /**
15825     * Creates an array of index keys for `object` values of arrays,
15826     * `arguments` objects, and strings, otherwise `null` is returned.
15827     *
15828     * @private
15829     * @param {Object} object The object to query.
15830     * @returns {Array|null} Returns index keys, else `null`.
15831     */
15832    function indexKeys(object) {
15833      var length = object ? object.length : undefined;
15834      if (isLength(length) &&
15835          (isArray(object) || isString(object) || isArguments(object))) {
15836        return baseTimes(length, String);
15837      }
15838      return null;
15839    }
15840
15841    /**
15842     * Checks if `value` is a flattenable `arguments` object or array.
15843     *
15844     * @private
15845     * @param {*} value The value to check.
15846     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
15847     */
15848    function isFlattenable(value) {
15849      return isArrayLikeObject(value) && (isArray(value) || isArguments(value));
15850    }
15851
15852    /**
15853     * Checks if `value` is a flattenable array and not a `_.matchesProperty`
15854     * iteratee shorthand.
15855     *
15856     * @private
15857     * @param {*} value The value to check.
15858     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
15859     */
15860    function isFlattenableIteratee(value) {
15861      return isArray(value) && !(value.length == 2 && !isFunction(value[0]));
15862    }
15863
15864    /**
15865     * Checks if the given arguments are from an iteratee call.
15866     *
15867     * @private
15868     * @param {*} value The potential iteratee value argument.
15869     * @param {*} index The potential iteratee index or key argument.
15870     * @param {*} object The potential iteratee object argument.
15871     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
15872     *  else `false`.
15873     */
15874    function isIterateeCall(value, index, object) {
15875      if (!isObject(object)) {
15876        return false;
15877      }
15878      var type = typeof index;
15879      if (type == 'number'
15880            ? (isArrayLike(object) && isIndex(index, object.length))
15881            : (type == 'string' && index in object)
15882          ) {
15883        return eq(object[index], value);
15884      }
15885      return false;
15886    }
15887
15888    /**
15889     * Checks if `value` is a property name and not a property path.
15890     *
15891     * @private
15892     * @param {*} value The value to check.
15893     * @param {Object} [object] The object to query keys on.
15894     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
15895     */
15896    function isKey(value, object) {
15897      var type = typeof value;
15898      if (type == 'number' || type == 'symbol') {
15899        return true;
15900      }
15901      return !isArray(value) &&
15902        (isSymbol(value) || reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
15903          (object != null && value in Object(object)));
15904    }
15905
15906    /**
15907     * Checks if `value` is suitable for use as unique object key.
15908     *
15909     * @private
15910     * @param {*} value The value to check.
15911     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
15912     */
15913    function isKeyable(value) {
15914      var type = typeof value;
15915      return type == 'number' || type == 'boolean' ||
15916        (type == 'string' && value != '__proto__') || value == null;
15917    }
15918
15919    /**
15920     * Checks if `func` has a lazy counterpart.
15921     *
15922     * @private
15923     * @param {Function} func The function to check.
15924     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
15925     *  else `false`.
15926     */
15927    function isLaziable(func) {
15928      var funcName = getFuncName(func),
15929          other = lodash[funcName];
15930
15931      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
15932        return false;
15933      }
15934      if (func === other) {
15935        return true;
15936      }
15937      var data = getData(other);
15938      return !!data && func === data[0];
15939    }
15940
15941    /**
15942     * Checks if `value` is likely a prototype object.
15943     *
15944     * @private
15945     * @param {*} value The value to check.
15946     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
15947     */
15948    function isPrototype(value) {
15949      var Ctor = value && value.constructor,
15950          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
15951
15952      return value === proto;
15953    }
15954
15955    /**
15956     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
15957     *
15958     * @private
15959     * @param {*} value The value to check.
15960     * @returns {boolean} Returns `true` if `value` if suitable for strict
15961     *  equality comparisons, else `false`.
15962     */
15963    function isStrictComparable(value) {
15964      return value === value && !isObject(value);
15965    }
15966
15967    /**
15968     * A specialized version of `matchesProperty` for source values suitable
15969     * for strict equality comparisons, i.e. `===`.
15970     *
15971     * @private
15972     * @param {string} key The key of the property to get.
15973     * @param {*} srcValue The value to match.
15974     * @returns {Function} Returns the new function.
15975     */
15976    function matchesStrictComparable(key, srcValue) {
15977      return function(object) {
15978        if (object == null) {
15979          return false;
15980        }
15981        return object[key] === srcValue &&
15982          (srcValue !== undefined || (key in Object(object)));
15983      };
15984    }
15985
15986    /**
15987     * Merges the function metadata of `source` into `data`.
15988     *
15989     * Merging metadata reduces the number of wrappers used to invoke a function.
15990     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
15991     * may be applied regardless of execution order. Methods like `_.ary` and
15992     * `_.rearg` modify function arguments, making the order in which they are
15993     * executed important, preventing the merging of metadata. However, we make
15994     * an exception for a safe combined case where curried functions have `_.ary`
15995     * and or `_.rearg` applied.
15996     *
15997     * @private
15998     * @param {Array} data The destination metadata.
15999     * @param {Array} source The source metadata.
16000     * @returns {Array} Returns `data`.
16001     */
16002    function mergeData(data, source) {
16003      var bitmask = data[1],
16004          srcBitmask = source[1],
16005          newBitmask = bitmask | srcBitmask,
16006          isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
16007
16008      var isCombo =
16009        ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
16010        ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
16011        ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
16012
16013      // Exit early if metadata can't be merged.
16014      if (!(isCommon || isCombo)) {
16015        return data;
16016      }
16017      // Use source `thisArg` if available.
16018      if (srcBitmask & BIND_FLAG) {
16019        data[2] = source[2];
16020        // Set when currying a bound function.
16021        newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG;
16022      }
16023      // Compose partial arguments.
16024      var value = source[3];
16025      if (value) {
16026        var partials = data[3];
16027        data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
16028        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
16029      }
16030      // Compose partial right arguments.
16031      value = source[5];
16032      if (value) {
16033        partials = data[5];
16034        data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
16035        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
16036      }
16037      // Use source `argPos` if available.
16038      value = source[7];
16039      if (value) {
16040        data[7] = copyArray(value);
16041      }
16042      // Use source `ary` if it's smaller.
16043      if (srcBitmask & ARY_FLAG) {
16044        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
16045      }
16046      // Use source `arity` if one is not provided.
16047      if (data[9] == null) {
16048        data[9] = source[9];
16049      }
16050      // Use source `func` and merge bitmasks.
16051      data[0] = source[0];
16052      data[1] = newBitmask;
16053
16054      return data;
16055    }
16056
16057    /**
16058     * Used by `_.defaultsDeep` to customize its `_.merge` use.
16059     *
16060     * @private
16061     * @param {*} objValue The destination value.
16062     * @param {*} srcValue The source value.
16063     * @param {string} key The key of the property to merge.
16064     * @param {Object} object The parent object of `objValue`.
16065     * @param {Object} source The parent object of `srcValue`.
16066     * @param {Object} [stack] Tracks traversed source values and their merged
16067     *  counterparts.
16068     * @returns {*} Returns the value to assign.
16069     */
16070    function mergeDefaults(objValue, srcValue, key, object, source, stack) {
16071      if (isObject(objValue) && isObject(srcValue)) {
16072        baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue));
16073      }
16074      return objValue;
16075    }
16076
16077    /**
16078     * Gets the parent value at `path` of `object`.
16079     *
16080     * @private
16081     * @param {Object} object The object to query.
16082     * @param {Array} path The path to get the parent value of.
16083     * @returns {*} Returns the parent value.
16084     */
16085    function parent(object, path) {
16086      return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
16087    }
16088
16089    /**
16090     * Reorder `array` according to the specified indexes where the element at
16091     * the first index is assigned as the first element, the element at
16092     * the second index is assigned as the second element, and so on.
16093     *
16094     * @private
16095     * @param {Array} array The array to reorder.
16096     * @param {Array} indexes The arranged array indexes.
16097     * @returns {Array} Returns `array`.
16098     */
16099    function reorder(array, indexes) {
16100      var arrLength = array.length,
16101          length = nativeMin(indexes.length, arrLength),
16102          oldArray = copyArray(array);
16103
16104      while (length--) {
16105        var index = indexes[length];
16106        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
16107      }
16108      return array;
16109    }
16110
16111    /**
16112     * Sets metadata for `func`.
16113     *
16114     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
16115     * period of time, it will trip its breaker and transition to an identity
16116     * function to avoid garbage collection pauses in V8. See
16117     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
16118     * for more details.
16119     *
16120     * @private
16121     * @param {Function} func The function to associate metadata with.
16122     * @param {*} data The metadata.
16123     * @returns {Function} Returns `func`.
16124     */
16125    var setData = (function() {
16126      var count = 0,
16127          lastCalled = 0;
16128
16129      return function(key, value) {
16130        var stamp = now(),
16131            remaining = HOT_SPAN - (stamp - lastCalled);
16132
16133        lastCalled = stamp;
16134        if (remaining > 0) {
16135          if (++count >= HOT_COUNT) {
16136            return key;
16137          }
16138        } else {
16139          count = 0;
16140        }
16141        return baseSetData(key, value);
16142      };
16143    }());
16144
16145    /**
16146     * Converts `string` to a property path array.
16147     *
16148     * @private
16149     * @param {string} string The string to convert.
16150     * @returns {Array} Returns the property path array.
16151     */
16152    var stringToPath = memoize(function(string) {
16153      var result = [];
16154      toString(string).replace(rePropName, function(match, number, quote, string) {
16155        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
16156      });
16157      return result;
16158    });
16159
16160    /**
16161     * Converts `func` to its source code.
16162     *
16163     * @private
16164     * @param {Function} func The function to process.
16165     * @returns {string} Returns the source code.
16166     */
16167    function toSource(func) {
16168      if (func != null) {
16169        try {
16170          return funcToString.call(func);
16171        } catch (e) {}
16172        try {
16173          return (func + '');
16174        } catch (e) {}
16175      }
16176      return '';
16177    }
16178
16179    /**
16180     * Creates a clone of `wrapper`.
16181     *
16182     * @private
16183     * @param {Object} wrapper The wrapper to clone.
16184     * @returns {Object} Returns the cloned wrapper.
16185     */
16186    function wrapperClone(wrapper) {
16187      if (wrapper instanceof LazyWrapper) {
16188        return wrapper.clone();
16189      }
16190      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
16191      result.__actions__ = copyArray(wrapper.__actions__);
16192      result.__index__  = wrapper.__index__;
16193      result.__values__ = wrapper.__values__;
16194      return result;
16195    }
16196
16197    /*------------------------------------------------------------------------*/
16198
16199    /**
16200     * Creates an array of elements split into groups the length of `size`.
16201     * If `array` can't be split evenly, the final chunk will be the remaining
16202     * elements.
16203     *
16204     * @static
16205     * @memberOf _
16206     * @since 3.0.0
16207     * @category Array
16208     * @param {Array} array The array to process.
16209     * @param {number} [size=1] The length of each chunk
16210     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16211     * @returns {Array} Returns the new array containing chunks.
16212     * @example
16213     *
16214     * _.chunk(['a', 'b', 'c', 'd'], 2);
16215     * // => [['a', 'b'], ['c', 'd']]
16216     *
16217     * _.chunk(['a', 'b', 'c', 'd'], 3);
16218     * // => [['a', 'b', 'c'], ['d']]
16219     */
16220    function chunk(array, size, guard) {
16221      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
16222        size = 1;
16223      } else {
16224        size = nativeMax(toInteger(size), 0);
16225      }
16226      var length = array ? array.length : 0;
16227      if (!length || size < 1) {
16228        return [];
16229      }
16230      var index = 0,
16231          resIndex = 0,
16232          result = Array(nativeCeil(length / size));
16233
16234      while (index < length) {
16235        result[resIndex++] = baseSlice(array, index, (index += size));
16236      }
16237      return result;
16238    }
16239
16240    /**
16241     * Creates an array with all falsey values removed. The values `false`, `null`,
16242     * `0`, `""`, `undefined`, and `NaN` are falsey.
16243     *
16244     * @static
16245     * @memberOf _
16246     * @since 0.1.0
16247     * @category Array
16248     * @param {Array} array The array to compact.
16249     * @returns {Array} Returns the new array of filtered values.
16250     * @example
16251     *
16252     * _.compact([0, 1, false, 2, '', 3]);
16253     * // => [1, 2, 3]
16254     */
16255    function compact(array) {
16256      var index = -1,
16257          length = array ? array.length : 0,
16258          resIndex = 0,
16259          result = [];
16260
16261      while (++index < length) {
16262        var value = array[index];
16263        if (value) {
16264          result[resIndex++] = value;
16265        }
16266      }
16267      return result;
16268    }
16269
16270    /**
16271     * Creates a new array concatenating `array` with any additional arrays
16272     * and/or values.
16273     *
16274     * @static
16275     * @memberOf _
16276     * @since 4.0.0
16277     * @category Array
16278     * @param {Array} array The array to concatenate.
16279     * @param {...*} [values] The values to concatenate.
16280     * @returns {Array} Returns the new concatenated array.
16281     * @example
16282     *
16283     * var array = [1];
16284     * var other = _.concat(array, 2, [3], [[4]]);
16285     *
16286     * console.log(other);
16287     * // => [1, 2, 3, [4]]
16288     *
16289     * console.log(array);
16290     * // => [1]
16291     */
16292    function concat() {
16293      var length = arguments.length,
16294          array = castArray(arguments[0]);
16295
16296      if (length < 2) {
16297        return length ? copyArray(array) : [];
16298      }
16299      var args = Array(length - 1);
16300      while (length--) {
16301        args[length - 1] = arguments[length];
16302      }
16303      return arrayConcat(array, baseFlatten(args, 1));
16304    }
16305
16306    /**
16307     * Creates an array of unique `array` values not included in the other given
16308     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
16309     * for equality comparisons. The order of result values is determined by the
16310     * order they occur in the first array.
16311     *
16312     * @static
16313     * @memberOf _
16314     * @since 0.1.0
16315     * @category Array
16316     * @param {Array} array The array to inspect.
16317     * @param {...Array} [values] The values to exclude.
16318     * @returns {Array} Returns the new array of filtered values.
16319     * @example
16320     *
16321     * _.difference([3, 2, 1], [4, 2]);
16322     * // => [3, 1]
16323     */
16324    var difference = rest(function(array, values) {
16325      return isArrayLikeObject(array)
16326        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
16327        : [];
16328    });
16329
16330    /**
16331     * This method is like `_.difference` except that it accepts `iteratee` which
16332     * is invoked for each element of `array` and `values` to generate the criterion
16333     * by which they're compared. Result values are chosen from the first array.
16334     * The iteratee is invoked with one argument: (value).
16335     *
16336     * @static
16337     * @memberOf _
16338     * @since 4.0.0
16339     * @category Array
16340     * @param {Array} array The array to inspect.
16341     * @param {...Array} [values] The values to exclude.
16342     * @param {Array|Function|Object|string} [iteratee=_.identity]
16343     *  The iteratee invoked per element.
16344     * @returns {Array} Returns the new array of filtered values.
16345     * @example
16346     *
16347     * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
16348     * // => [3.1, 1.3]
16349     *
16350     * // The `_.property` iteratee shorthand.
16351     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
16352     * // => [{ 'x': 2 }]
16353     */
16354    var differenceBy = rest(function(array, values) {
16355      var iteratee = last(values);
16356      if (isArrayLikeObject(iteratee)) {
16357        iteratee = undefined;
16358      }
16359      return isArrayLikeObject(array)
16360        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee))
16361        : [];
16362    });
16363
16364    /**
16365     * This method is like `_.difference` except that it accepts `comparator`
16366     * which is invoked to compare elements of `array` to `values`. Result values
16367     * are chosen from the first array. The comparator is invoked with two arguments:
16368     * (arrVal, othVal).
16369     *
16370     * @static
16371     * @memberOf _
16372     * @since 4.0.0
16373     * @category Array
16374     * @param {Array} array The array to inspect.
16375     * @param {...Array} [values] The values to exclude.
16376     * @param {Function} [comparator] The comparator invoked per element.
16377     * @returns {Array} Returns the new array of filtered values.
16378     * @example
16379     *
16380     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
16381     *
16382     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
16383     * // => [{ 'x': 2, 'y': 1 }]
16384     */
16385    var differenceWith = rest(function(array, values) {
16386      var comparator = last(values);
16387      if (isArrayLikeObject(comparator)) {
16388        comparator = undefined;
16389      }
16390      return isArrayLikeObject(array)
16391        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
16392        : [];
16393    });
16394
16395    /**
16396     * Creates a slice of `array` with `n` elements dropped from the beginning.
16397     *
16398     * @static
16399     * @memberOf _
16400     * @since 0.5.0
16401     * @category Array
16402     * @param {Array} array The array to query.
16403     * @param {number} [n=1] The number of elements to drop.
16404     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16405     * @returns {Array} Returns the slice of `array`.
16406     * @example
16407     *
16408     * _.drop([1, 2, 3]);
16409     * // => [2, 3]
16410     *
16411     * _.drop([1, 2, 3], 2);
16412     * // => [3]
16413     *
16414     * _.drop([1, 2, 3], 5);
16415     * // => []
16416     *
16417     * _.drop([1, 2, 3], 0);
16418     * // => [1, 2, 3]
16419     */
16420    function drop(array, n, guard) {
16421      var length = array ? array.length : 0;
16422      if (!length) {
16423        return [];
16424      }
16425      n = (guard || n === undefined) ? 1 : toInteger(n);
16426      return baseSlice(array, n < 0 ? 0 : n, length);
16427    }
16428
16429    /**
16430     * Creates a slice of `array` with `n` elements dropped from the end.
16431     *
16432     * @static
16433     * @memberOf _
16434     * @since 3.0.0
16435     * @category Array
16436     * @param {Array} array The array to query.
16437     * @param {number} [n=1] The number of elements to drop.
16438     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16439     * @returns {Array} Returns the slice of `array`.
16440     * @example
16441     *
16442     * _.dropRight([1, 2, 3]);
16443     * // => [1, 2]
16444     *
16445     * _.dropRight([1, 2, 3], 2);
16446     * // => [1]
16447     *
16448     * _.dropRight([1, 2, 3], 5);
16449     * // => []
16450     *
16451     * _.dropRight([1, 2, 3], 0);
16452     * // => [1, 2, 3]
16453     */
16454    function dropRight(array, n, guard) {
16455      var length = array ? array.length : 0;
16456      if (!length) {
16457        return [];
16458      }
16459      n = (guard || n === undefined) ? 1 : toInteger(n);
16460      n = length - n;
16461      return baseSlice(array, 0, n < 0 ? 0 : n);
16462    }
16463
16464    /**
16465     * Creates a slice of `array` excluding elements dropped from the end.
16466     * Elements are dropped until `predicate` returns falsey. The predicate is
16467     * invoked with three arguments: (value, index, array).
16468     *
16469     * @static
16470     * @memberOf _
16471     * @since 3.0.0
16472     * @category Array
16473     * @param {Array} array The array to query.
16474     * @param {Array|Function|Object|string} [predicate=_.identity]
16475     *  The function invoked per iteration.
16476     * @returns {Array} Returns the slice of `array`.
16477     * @example
16478     *
16479     * var users = [
16480     *   { 'user': 'barney',  'active': true },
16481     *   { 'user': 'fred',    'active': false },
16482     *   { 'user': 'pebbles', 'active': false }
16483     * ];
16484     *
16485     * _.dropRightWhile(users, function(o) { return !o.active; });
16486     * // => objects for ['barney']
16487     *
16488     * // The `_.matches` iteratee shorthand.
16489     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
16490     * // => objects for ['barney', 'fred']
16491     *
16492     * // The `_.matchesProperty` iteratee shorthand.
16493     * _.dropRightWhile(users, ['active', false]);
16494     * // => objects for ['barney']
16495     *
16496     * // The `_.property` iteratee shorthand.
16497     * _.dropRightWhile(users, 'active');
16498     * // => objects for ['barney', 'fred', 'pebbles']
16499     */
16500    function dropRightWhile(array, predicate) {
16501      return (array && array.length)
16502        ? baseWhile(array, getIteratee(predicate, 3), true, true)
16503        : [];
16504    }
16505
16506    /**
16507     * Creates a slice of `array` excluding elements dropped from the beginning.
16508     * Elements are dropped until `predicate` returns falsey. The predicate is
16509     * invoked with three arguments: (value, index, array).
16510     *
16511     * @static
16512     * @memberOf _
16513     * @since 3.0.0
16514     * @category Array
16515     * @param {Array} array The array to query.
16516     * @param {Array|Function|Object|string} [predicate=_.identity]
16517     *  The function invoked per iteration.
16518     * @returns {Array} Returns the slice of `array`.
16519     * @example
16520     *
16521     * var users = [
16522     *   { 'user': 'barney',  'active': false },
16523     *   { 'user': 'fred',    'active': false },
16524     *   { 'user': 'pebbles', 'active': true }
16525     * ];
16526     *
16527     * _.dropWhile(users, function(o) { return !o.active; });
16528     * // => objects for ['pebbles']
16529     *
16530     * // The `_.matches` iteratee shorthand.
16531     * _.dropWhile(users, { 'user': 'barney', 'active': false });
16532     * // => objects for ['fred', 'pebbles']
16533     *
16534     * // The `_.matchesProperty` iteratee shorthand.
16535     * _.dropWhile(users, ['active', false]);
16536     * // => objects for ['pebbles']
16537     *
16538     * // The `_.property` iteratee shorthand.
16539     * _.dropWhile(users, 'active');
16540     * // => objects for ['barney', 'fred', 'pebbles']
16541     */
16542    function dropWhile(array, predicate) {
16543      return (array && array.length)
16544        ? baseWhile(array, getIteratee(predicate, 3), true)
16545        : [];
16546    }
16547
16548    /**
16549     * Fills elements of `array` with `value` from `start` up to, but not
16550     * including, `end`.
16551     *
16552     * **Note:** This method mutates `array`.
16553     *
16554     * @static
16555     * @memberOf _
16556     * @since 3.2.0
16557     * @category Array
16558     * @param {Array} array The array to fill.
16559     * @param {*} value The value to fill `array` with.
16560     * @param {number} [start=0] The start position.
16561     * @param {number} [end=array.length] The end position.
16562     * @returns {Array} Returns `array`.
16563     * @example
16564     *
16565     * var array = [1, 2, 3];
16566     *
16567     * _.fill(array, 'a');
16568     * console.log(array);
16569     * // => ['a', 'a', 'a']
16570     *
16571     * _.fill(Array(3), 2);
16572     * // => [2, 2, 2]
16573     *
16574     * _.fill([4, 6, 8, 10], '*', 1, 3);
16575     * // => [4, '*', '*', 10]
16576     */
16577    function fill(array, value, start, end) {
16578      var length = array ? array.length : 0;
16579      if (!length) {
16580        return [];
16581      }
16582      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
16583        start = 0;
16584        end = length;
16585      }
16586      return baseFill(array, value, start, end);
16587    }
16588
16589    /**
16590     * This method is like `_.find` except that it returns the index of the first
16591     * element `predicate` returns truthy for instead of the element itself.
16592     *
16593     * @static
16594     * @memberOf _
16595     * @since 1.1.0
16596     * @category Array
16597     * @param {Array} array The array to search.
16598     * @param {Array|Function|Object|string} [predicate=_.identity]
16599     *  The function invoked per iteration.
16600     * @returns {number} Returns the index of the found element, else `-1`.
16601     * @example
16602     *
16603     * var users = [
16604     *   { 'user': 'barney',  'active': false },
16605     *   { 'user': 'fred',    'active': false },
16606     *   { 'user': 'pebbles', 'active': true }
16607     * ];
16608     *
16609     * _.findIndex(users, function(o) { return o.user == 'barney'; });
16610     * // => 0
16611     *
16612     * // The `_.matches` iteratee shorthand.
16613     * _.findIndex(users, { 'user': 'fred', 'active': false });
16614     * // => 1
16615     *
16616     * // The `_.matchesProperty` iteratee shorthand.
16617     * _.findIndex(users, ['active', false]);
16618     * // => 0
16619     *
16620     * // The `_.property` iteratee shorthand.
16621     * _.findIndex(users, 'active');
16622     * // => 2
16623     */
16624    function findIndex(array, predicate) {
16625      return (array && array.length)
16626        ? baseFindIndex(array, getIteratee(predicate, 3))
16627        : -1;
16628    }
16629
16630    /**
16631     * This method is like `_.findIndex` except that it iterates over elements
16632     * of `collection` from right to left.
16633     *
16634     * @static
16635     * @memberOf _
16636     * @since 2.0.0
16637     * @category Array
16638     * @param {Array} array The array to search.
16639     * @param {Array|Function|Object|string} [predicate=_.identity]
16640     *  The function invoked per iteration.
16641     * @returns {number} Returns the index of the found element, else `-1`.
16642     * @example
16643     *
16644     * var users = [
16645     *   { 'user': 'barney',  'active': true },
16646     *   { 'user': 'fred',    'active': false },
16647     *   { 'user': 'pebbles', 'active': false }
16648     * ];
16649     *
16650     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
16651     * // => 2
16652     *
16653     * // The `_.matches` iteratee shorthand.
16654     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
16655     * // => 0
16656     *
16657     * // The `_.matchesProperty` iteratee shorthand.
16658     * _.findLastIndex(users, ['active', false]);
16659     * // => 2
16660     *
16661     * // The `_.property` iteratee shorthand.
16662     * _.findLastIndex(users, 'active');
16663     * // => 0
16664     */
16665    function findLastIndex(array, predicate) {
16666      return (array && array.length)
16667        ? baseFindIndex(array, getIteratee(predicate, 3), true)
16668        : -1;
16669    }
16670
16671    /**
16672     * Flattens `array` a single level deep.
16673     *
16674     * @static
16675     * @memberOf _
16676     * @since 0.1.0
16677     * @category Array
16678     * @param {Array} array The array to flatten.
16679     * @returns {Array} Returns the new flattened array.
16680     * @example
16681     *
16682     * _.flatten([1, [2, [3, [4]], 5]]);
16683     * // => [1, 2, [3, [4]], 5]
16684     */
16685    function flatten(array) {
16686      var length = array ? array.length : 0;
16687      return length ? baseFlatten(array, 1) : [];
16688    }
16689
16690    /**
16691     * Recursively flattens `array`.
16692     *
16693     * @static
16694     * @memberOf _
16695     * @since 3.0.0
16696     * @category Array
16697     * @param {Array} array The array to flatten.
16698     * @returns {Array} Returns the new flattened array.
16699     * @example
16700     *
16701     * _.flattenDeep([1, [2, [3, [4]], 5]]);
16702     * // => [1, 2, 3, 4, 5]
16703     */
16704    function flattenDeep(array) {
16705      var length = array ? array.length : 0;
16706      return length ? baseFlatten(array, INFINITY) : [];
16707    }
16708
16709    /**
16710     * Recursively flatten `array` up to `depth` times.
16711     *
16712     * @static
16713     * @memberOf _
16714     * @since 4.4.0
16715     * @category Array
16716     * @param {Array} array The array to flatten.
16717     * @param {number} [depth=1] The maximum recursion depth.
16718     * @returns {Array} Returns the new flattened array.
16719     * @example
16720     *
16721     * var array = [1, [2, [3, [4]], 5]];
16722     *
16723     * _.flattenDepth(array, 1);
16724     * // => [1, 2, [3, [4]], 5]
16725     *
16726     * _.flattenDepth(array, 2);
16727     * // => [1, 2, 3, [4], 5]
16728     */
16729    function flattenDepth(array, depth) {
16730      var length = array ? array.length : 0;
16731      if (!length) {
16732        return [];
16733      }
16734      depth = depth === undefined ? 1 : toInteger(depth);
16735      return baseFlatten(array, depth);
16736    }
16737
16738    /**
16739     * The inverse of `_.toPairs`;
16739 this method returns an object composed
16740     * from key-value `pairs`.
16741     *
16742     * @static
16743     * @memberOf _
16744     * @since 4.0.0
16745     * @category Array
16746     * @param {Array} pairs The key-value pairs.
16747     * @returns {Object} Returns the new object.
16748     * @example
16749     *
16750     * _.fromPairs([['fred', 30], ['barney', 40]]);
16751     * // => { 'fred': 30, 'barney': 40 }
16752     */
16753    function fromPairs(pairs) {
16754      var index = -1,
16755          length = pairs ? pairs.length : 0,
16756          result = {};
16757
16758      while (++index < length) {
16759        var pair = pairs[index];
16760        result[pair[0]] = pair[1];
16761      }
16762      return result;
16763    }
16764
16765    /**
16766     * Gets the first element of `array`.
16767     *
16768     * @static
16769     * @memberOf _
16770     * @since 0.1.0
16771     * @alias first
16772     * @category Array
16773     * @param {Array} array The array to query.
16774     * @returns {*} Returns the first element of `array`.
16775     * @example
16776     *
16777     * _.head([1, 2, 3]);
16778     * // => 1
16779     *
16780     * _.head([]);
16781     * // => undefined
16782     */
16783    function head(array) {
16784      return array ? array[0] : undefined;
16785    }
16786
16787    /**
16788     * Gets the index at which the first occurrence of `value` is found in `array`
16789     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
16790     * for equality comparisons. If `fromIndex` is negative, it's used as the
16791     * offset from the end of `array`.
16792     *
16793     * @static
16794     * @memberOf _
16795     * @since 0.1.0
16796     * @category Array
16797     * @param {Array} array The array to search.
16798     * @param {*} value The value to search for.
16799     * @param {number} [fromIndex=0] The index to search from.
16800     * @returns {number} Returns the index of the matched value, else `-1`.
16801     * @example
16802     *
16803     * _.indexOf([1, 2, 1, 2], 2);
16804     * // => 1
16805     *
16806     * // Search from the `fromIndex`.
16807     * _.indexOf([1, 2, 1, 2], 2, 2);
16808     * // => 3
16809     */
16810    function indexOf(array, value, fromIndex) {
16811      var length = array ? array.length : 0;
16812      if (!length) {
16813        return -1;
16814      }
16815      fromIndex = toInteger(fromIndex);
16816      if (fromIndex < 0) {
16817        fromIndex = nativeMax(length + fromIndex, 0);
16818      }
16819      return baseIndexOf(array, value, fromIndex);
16820    }
16821
16822    /**
16823     * Gets all but the last element of `array`.
16824     *
16825     * @static
16826     * @memberOf _
16827     * @since 0.1.0
16828     * @category Array
16829     * @param {Array} array The array to query.
16830     * @returns {Array} Returns the slice of `array`.
16831     * @example
16832     *
16833     * _.initial([1, 2, 3]);
16834     * // => [1, 2]
16835     */
16836    function initial(array) {
16837      return dropRight(array, 1);
16838    }
16839
16840    /**
16841     * Creates an array of unique values that are included in all given arrays
16842     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
16843     * for equality comparisons. The order of result values is determined by the
16844     * order they occur in the first array.
16845     *
16846     * @static
16847     * @memberOf _
16848     * @since 0.1.0
16849     * @category Array
16850     * @param {...Array} [arrays] The arrays to inspect.
16851     * @returns {Array} Returns the new array of intersecting values.
16852     * @example
16853     *
16854     * _.intersection([2, 1], [4, 2], [1, 2]);
16855     * // => [2]
16856     */
16857    var intersection = rest(function(arrays) {
16858      var mapped = arrayMap(arrays, baseCastArrayLikeObject);
16859      return (mapped.length && mapped[0] === arrays[0])
16860        ? baseIntersection(mapped)
16861        : [];
16862    });
16863
16864    /**
16865     * This method is like `_.intersection` except that it accepts `iteratee`
16866     * which is invoked for each element of each `arrays` to generate the criterion
16867     * by which they're compared. Result values are chosen from the first array.
16868     * The iteratee is invoked with one argument: (value).
16869     *
16870     * @static
16871     * @memberOf _
16872     * @since 4.0.0
16873     * @category Array
16874     * @param {...Array} [arrays] The arrays to inspect.
16875     * @param {Array|Function|Object|string} [iteratee=_.identity]
16876     *  The iteratee invoked per element.
16877     * @returns {Array} Returns the new array of intersecting values.
16878     * @example
16879     *
16880     * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
16881     * // => [2.1]
16882     *
16883     * // The `_.property` iteratee shorthand.
16884     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
16885     * // => [{ 'x': 1 }]
16886     */
16887    var intersectionBy = rest(function(arrays) {
16888      var iteratee = last(arrays),
16889          mapped = arrayMap(arrays, baseCastArrayLikeObject);
16890
16891      if (iteratee === last(mapped)) {
16892        iteratee = undefined;
16893      } else {
16894        mapped.pop();
16895      }
16896      return (mapped.length && mapped[0] === arrays[0])
16897        ? baseIntersection(mapped, getIteratee(iteratee))
16898        : [];
16899    });
16900
16901    /**
16902     * This method is like `_.intersection` except that it accepts `comparator`
16903     * which is invoked to compare elements of `arrays`. Result values are chosen
16904     * from the first array. The comparator is invoked with two arguments:
16905     * (arrVal, othVal).
16906     *
16907     * @static
16908     * @memberOf _
16909     * @since 4.0.0
16910     * @category Array
16911     * @param {...Array} [arrays] The arrays to inspect.
16912     * @param {Function} [comparator] The comparator invoked per element.
16913     * @returns {Array} Returns the new array of intersecting values.
16914     * @example
16915     *
16916     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
16917     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
16918     *
16919     * _.intersectionWith(objects, others, _.isEqual);
16920     * // => [{ 'x': 1, 'y': 2 }]
16921     */
16922    var intersectionWith = rest(function(arrays) {
16923      var comparator = last(arrays),
16924          mapped = arrayMap(arrays, baseCastArrayLikeObject);
16925
16926      if (comparator === last(mapped)) {
16927        comparator = undefined;
16928      } else {
16929        mapped.pop();
16930      }
16931      return (mapped.length && mapped[0] === arrays[0])
16932        ? baseIntersection(mapped, undefined, comparator)
16933        : [];
16934    });
16935
16936    /**
16937     * Converts all elements in `array` into a string separated by `separator`.
16938     *
16939     * @static
16940     * @memberOf _
16941     * @since 4.0.0
16942     * @category Array
16943     * @param {Array} array The array to convert.
16944     * @param {string} [separator=','] The element separator.
16945     * @returns {string} Returns the joined string.
16946     * @example
16947     *
16948     * _.join(['a', 'b', 'c'], '~');
16949     * // => 'a~b~c'
16950     */
16951    function join(array, separator) {
16952      return array ? nativeJoin.call(array, separator) : '';
16953    }
16954
16955    /**
16956     * Gets the last element of `array`.
16957     *
16958     * @static
16959     * @memberOf _
16960     * @since 0.1.0
16961     * @category Array
16962     * @param {Array} array The array to query.
16963     * @returns {*} Returns the last element of `array`.
16964     * @example
16965     *
16966     * _.last([1, 2, 3]);
16967     * // => 3
16968     */
16969    function last(array) {
16970      var length = array ? array.length : 0;
16971      return length ? array[length - 1] : undefined;
16972    }
16973
16974    /**
16975     * This method is like `_.indexOf` except that it iterates over elements of
16976     * `array` from right to left.
16977     *
16978     * @static
16979     * @memberOf _
16980     * @since 0.1.0
16981     * @category Array
16982     * @param {Array} array The array to search.
16983     * @param {*} value The value to search for.
16984     * @param {number} [fromIndex=array.length-1] The index to search from.
16985     * @returns {number} Returns the index of the matched value, else `-1`.
16986     * @example
16987     *
16988     * _.lastIndexOf([1, 2, 1, 2], 2);
16989     * // => 3
16990     *
16991     * // Search from the `fromIndex`.
16992     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
16993     * // => 1
16994     */
16995    function lastIndexOf(array, value, fromIndex) {
16996      var length = array ? array.length : 0;
16997      if (!length) {
16998        return -1;
16999      }
17000      var index = length;
17001      if (fromIndex !== undefined) {
17002        index = toInteger(fromIndex);
17003        index = (
17004          index < 0
17005            ? nativeMax(length + index, 0)
17006            : nativeMin(index, length - 1)
17007        ) + 1;
17008      }
17009      if (value !== value) {
17010        return indexOfNaN(array, index, true);
17011      }
17012      while (index--) {
17013        if (array[index] === value) {
17014          return index;
17015        }
17016      }
17017      return -1;
17018    }
17019
17020    /**
17021     * Removes all given values from `array` using
17022     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
17023     * for equality comparisons.
17024     *
17025     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
17026     * to remove elements from an array by predicate.
17027     *
17028     * @static
17029     * @memberOf _
17030     * @since 2.0.0
17031     * @category Array
17032     * @param {Array} array The array to modify.
17033     * @param {...*} [values] The values to remove.
17034     * @returns {Array} Returns `array`.
17035     * @example
17036     *
17037     * var array = [1, 2, 3, 1, 2, 3];
17038     *
17039     * _.pull(array, 2, 3);
17040     * console.log(array);
17041     * // => [1, 1]
17042     */
17043    var pull = rest(pullAll);
17044
17045    /**
17046     * This method is like `_.pull` except that it accepts an array of values to remove.
17047     *
17048     * **Note:** Unlike `_.difference`, this method mutates `array`.
17049     *
17050     * @static
17051     * @memberOf _
17052     * @since 4.0.0
17053     * @category Array
17054     * @param {Array} array The array to modify.
17055     * @param {Array} values The values to remove.
17056     * @returns {Array} Returns `array`.
17057     * @example
17058     *
17059     * var array = [1, 2, 3, 1, 2, 3];
17060     *
17061     * _.pullAll(array, [2, 3]);
17062     * console.log(array);
17063     * // => [1, 1]
17064     */
17065    function pullAll(array, values) {
17066      return (array && array.length && values && values.length)
17067        ? basePullAll(array, values)
17068        : array;
17069    }
17070
17071    /**
17072     * This method is like `_.pullAll` except that it accepts `iteratee` which is
17073     * invoked for each element of `array` and `values` to generate the criterion
17074     * by which they're compared. The iteratee is invoked with one argument: (value).
17075     *
17076     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
17077     *
17078     * @static
17079     * @memberOf _
17080     * @since 4.0.0
17081     * @category Array
17082     * @param {Array} array The array to modify.
17083     * @param {Array} values The values to remove.
17084     * @param {Array|Function|Object|string} [iteratee=_.identity]
17085     *  The iteratee invoked per element.
17086     * @returns {Array} Returns `array`.
17087     * @example
17088     *
17089     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
17090     *
17091     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
17092     * console.log(array);
17093     * // => [{ 'x': 2 }]
17094     */
17095    function pullAllBy(array, values, iteratee) {
17096      return (array && array.length && values && values.length)
17097        ? basePullAll(array, values, getIteratee(iteratee))
17098        : array;
17099    }
17100
17101    /**
17102     * This method is like `_.pullAll` except that it accepts `comparator` which
17103     * is invoked to compare elements of `array` to `values`. The comparator is
17104     * invoked with two arguments: (arrVal, othVal).
17105     *
17106     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
17107     *
17108     * @static
17109     * @memberOf _
17110     * @since 4.6.0
17111     * @category Array
17112     * @param {Array} array The array to modify.
17113     * @param {Array} values The values to remove.
17114     * @param {Function} [comparator] The comparator invoked per element.
17115     * @returns {Array} Returns `array`.
17116     * @example
17117     *
17118     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
17119     *
17120     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
17121     * console.log(array);
17122     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
17123     */
17124    function pullAllWith(array, values, comparator) {
17125      return (array && array.length && values && values.length)
vendor: 16,384 bytes, lines 17126-17672
17126        ? basePullAll(array, values, undefined, comparator)
17127        : array;
17128    }
17129
17130    /**
17131     * Removes elements from `array` corresponding to `indexes` and returns an
17132     * array of removed elements.
17133     *
17134     * **Note:** Unlike `_.at`, this method mutates `array`.
17135     *
17136     * @static
17137     * @memberOf _
17138     * @since 3.0.0
17139     * @category Array
17140     * @param {Array} array The array to modify.
17141     * @param {...(number|number[])} [indexes] The indexes of elements to remove,
17142     *  specified individually or in arrays.
17143     * @returns {Array} Returns the new array of removed elements.
17144     * @example
17145     *
17146     * var array = [5, 10, 15, 20];
17147     * var evens = _.pullAt(array, 1, 3);
17148     *
17149     * console.log(array);
17150     * // => [5, 15]
17151     *
17152     * console.log(evens);
17153     * // => [10, 20]
17154     */
17155    var pullAt = rest(function(array, indexes) {
17156      indexes = arrayMap(baseFlatten(indexes, 1), String);
17157
17158      var result = baseAt(array, indexes);
17159      basePullAt(array, indexes.sort(compareAscending));
17160      return result;
17161    });
17162
17163    /**
17164     * Removes all elements from `array` that `predicate` returns truthy for
17165     * and returns an array of the removed elements. The predicate is invoked
17166     * with three arguments: (value, index, array).
17167     *
17168     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
17169     * to pull elements from an array by value.
17170     *
17171     * @static
17172     * @memberOf _
17173     * @since 2.0.0
17174     * @category Array
17175     * @param {Array} array The array to modify.
17176     * @param {Array|Function|Object|string} [predicate=_.identity]
17177     *  The function invoked per iteration.
17178     * @returns {Array} Returns the new array of removed elements.
17179     * @example
17180     *
17181     * var array = [1, 2, 3, 4];
17182     * var evens = _.remove(array, function(n) {
17183     *   return n % 2 == 0;
17184     * });
17185     *
17186     * console.log(array);
17187     * // => [1, 3]
17188     *
17189     * console.log(evens);
17190     * // => [2, 4]
17191     */
17192    function remove(array, predicate) {
17193      var result = [];
17194      if (!(array && array.length)) {
17195        return result;
17196      }
17197      var index = -1,
17198          indexes = [],
17199          length = array.length;
17200
17201      predicate = getIteratee(predicate, 3);
17202      while (++index < length) {
17203        var value = array[index];
17204        if (predicate(value, index, array)) {
17205          result.push(value);
17206          indexes.push(index);
17207        }
17208      }
17209      basePullAt(array, indexes);
17210      return result;
17211    }
17212
17213    /**
17214     * Reverses `array` so that the first element becomes the last, the second
17215     * element becomes the second to last, and so on.
17216     *
17217     * **Note:** This method mutates `array` and is based on
17218     * [`Array#reverse`](https://mdn.io/Array/reverse).
17219     *
17220     * @static
17221     * @memberOf _
17222     * @since 4.0.0
17223     * @category Array
17224     * @param {Array} array The array to modify.
17225     * @returns {Array} Returns `array`.
17226     * @example
17227     *
17228     * var array = [1, 2, 3];
17229     *
17230     * _.reverse(array);
17231     * // => [3, 2, 1]
17232     *
17233     * console.log(array);
17234     * // => [3, 2, 1]
17235     */
17236    function reverse(array) {
17237      return array ? nativeReverse.call(array) : array;
17238    }
17239
17240    /**
17241     * Creates a slice of `array` from `start` up to, but not including, `end`.
17242     *
17243     * **Note:** This method is used instead of
17244     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
17245     * returned.
17246     *
17247     * @static
17248     * @memberOf _
17249     * @since 3.0.0
17250     * @category Array
17251     * @param {Array} array The array to slice.
17252     * @param {number} [start=0] The start position.
17253     * @param {number} [end=array.length] The end position.
17254     * @returns {Array} Returns the slice of `array`.
17255     */
17256    function slice(array, start, end) {
17257      var length = array ? array.length : 0;
17258      if (!length) {
17259        return [];
17260      }
17261      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
17262        start = 0;
17263        end = length;
17264      }
17265      else {
17266        start = start == null ? 0 : toInteger(start);
17267        end = end === undefined ? length : toInteger(end);
17268      }
17269      return baseSlice(array, start, end);
17270    }
17271
17272    /**
17273     * Uses a binary search to determine the lowest index at which `value`
17274     * should be inserted into `array` in order to maintain its sort order.
17275     *
17276     * @static
17277     * @memberOf _
17278     * @since 0.1.0
17279     * @category Array
17280     * @param {Array} array The sorted array to inspect.
17281     * @param {*} value The value to evaluate.
17282     * @returns {number} Returns the index at which `value` should be inserted
17283     *  into `array`.
17284     * @example
17285     *
17286     * _.sortedIndex([30, 50], 40);
17287     * // => 1
17288     *
17289     * _.sortedIndex([4, 5], 4);
17290     * // => 0
17291     */
17292    function sortedIndex(array, value) {
17293      return baseSortedIndex(array, value);
17294    }
17295
17296    /**
17297     * This method is like `_.sortedIndex` except that it accepts `iteratee`
17298     * which is invoked for `value` and each element of `array` to compute their
17299     * sort ranking. The iteratee is invoked with one argument: (value).
17300     *
17301     * @static
17302     * @memberOf _
17303     * @since 4.0.0
17304     * @category Array
17305     * @param {Array} array The sorted array to inspect.
17306     * @param {*} value The value to evaluate.
17307     * @param {Array|Function|Object|string} [iteratee=_.identity]
17308     *  The iteratee invoked per element.
17309     * @returns {number} Returns the index at which `value` should be inserted
17310     *  into `array`.
17311     * @example
17312     *
17313     * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
17314     *
17315     * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
17316     * // => 1
17317     *
17318     * // The `_.property` iteratee shorthand.
17319     * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
17320     * // => 0
17321     */
17322    function sortedIndexBy(array, value, iteratee) {
17323      return baseSortedIndexBy(array, value, getIteratee(iteratee));
17324    }
17325
17326    /**
17327     * This method is like `_.indexOf` except that it performs a binary
17328     * search on a sorted `array`.
17329     *
17330     * @static
17331     * @memberOf _
17332     * @since 4.0.0
17333     * @category Array
17334     * @param {Array} array The array to search.
17335     * @param {*} value The value to search for.
17336     * @returns {number} Returns the index of the matched value, else `-1`.
17337     * @example
17338     *
17339     * _.sortedIndexOf([1, 1, 2, 2], 2);
17340     * // => 2
17341     */
17342    function sortedIndexOf(array, value) {
17343      var length = array ? array.length : 0;
17344      if (length) {
17345        var index = baseSortedIndex(array, value);
17346        if (index < length && eq(array[index], value)) {
17347          return index;
17348        }
17349      }
17350      return -1;
17351    }
17352
17353    /**
17354     * This method is like `_.sortedIndex` except that it returns the highest
17355     * index at which `value` should be inserted into `array` in order to
17356     * maintain its sort order.
17357     *
17358     * @static
17359     * @memberOf _
17360     * @since 3.0.0
17361     * @category Array
17362     * @param {Array} array The sorted array to inspect.
17363     * @param {*} value The value to evaluate.
17364     * @returns {number} Returns the index at which `value` should be inserted
17365     *  into `array`.
17366     * @example
17367     *
17368     * _.sortedLastIndex([4, 5], 4);
17369     * // => 1
17370     */
17371    function sortedLastIndex(array, value) {
17372      return baseSortedIndex(array, value, true);
17373    }
17374
17375    /**
17376     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
17377     * which is invoked for `value` and each element of `array` to compute their
17378     * sort ranking. The iteratee is invoked with one argument: (value).
17379     *
17380     * @static
17381     * @memberOf _
17382     * @since 4.0.0
17383     * @category Array
17384     * @param {Array} array The sorted array to inspect.
17385     * @param {*} value The value to evaluate.
17386     * @param {Array|Function|Object|string} [iteratee=_.identity]
17387     *  The iteratee invoked per element.
17388     * @returns {number} Returns the index at which `value` should be inserted
17389     *  into `array`.
17390     * @example
17391     *
17392     * // The `_.property` iteratee shorthand.
17393     * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
17394     * // => 1
17395     */
17396    function sortedLastIndexBy(array, value, iteratee) {
17397      return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
17398    }
17399
17400    /**
17401     * This method is like `_.lastIndexOf` except that it performs a binary
17402     * search on a sorted `array`.
17403     *
17404     * @static
17405     * @memberOf _
17406     * @since 4.0.0
17407     * @category Array
17408     * @param {Array} array The array to search.
17409     * @param {*} value The value to search for.
17410     * @returns {number} Returns the index of the matched value, else `-1`.
17411     * @example
17412     *
17413     * _.sortedLastIndexOf([1, 1, 2, 2], 2);
17414     * // => 3
17415     */
17416    function sortedLastIndexOf(array, value) {
17417      var length = array ? array.length : 0;
17418      if (length) {
17419        var index = baseSortedIndex(array, value, true) - 1;
17420        if (eq(array[index], value)) {
17421          return index;
17422        }
17423      }
17424      return -1;
17425    }
17426
17427    /**
17428     * This method is like `_.uniq` except that it's designed and optimized
17429     * for sorted arrays.
17430     *
17431     * @static
17432     * @memberOf _
17433     * @since 4.0.0
17434     * @category Array
17435     * @param {Array} array The array to inspect.
17436     * @returns {Array} Returns the new duplicate free array.
17437     * @example
17438     *
17439     * _.sortedUniq([1, 1, 2]);
17440     * // => [1, 2]
17441     */
17442    function sortedUniq(array) {
17443      return (array && array.length)
17444        ? baseSortedUniq(array)
17445        : [];
17446    }
17447
17448    /**
17449     * This method is like `_.uniqBy` except that it's designed and optimized
17450     * for sorted arrays.
17451     *
17452     * @static
17453     * @memberOf _
17454     * @since 4.0.0
17455     * @category Array
17456     * @param {Array} array The array to inspect.
17457     * @param {Function} [iteratee] The iteratee invoked per element.
17458     * @returns {Array} Returns the new duplicate free array.
17459     * @example
17460     *
17461     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
17462     * // => [1.1, 2.3]
17463     */
17464    function sortedUniqBy(array, iteratee) {
17465      return (array && array.length)
17466        ? baseSortedUniqBy(array, getIteratee(iteratee))
17467        : [];
17468    }
17469
17470    /**
17471     * Gets all but the first element of `array`.
17472     *
17473     * @static
17474     * @memberOf _
17475     * @since 4.0.0
17476     * @category Array
17477     * @param {Array} array The array to query.
17478     * @returns {Array} Returns the slice of `array`.
17479     * @example
17480     *
17481     * _.tail([1, 2, 3]);
17482     * // => [2, 3]
17483     */
17484    function tail(array) {
17485      return drop(array, 1);
17486    }
17487
17488    /**
17489     * Creates a slice of `array` with `n` elements taken from the beginning.
17490     *
17491     * @static
17492     * @memberOf _
17493     * @since 0.1.0
17494     * @category Array
17495     * @param {Array} array The array to query.
17496     * @param {number} [n=1] The number of elements to take.
17497     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
17498     * @returns {Array} Returns the slice of `array`.
17499     * @example
17500     *
17501     * _.take([1, 2, 3]);
17502     * // => [1]
17503     *
17504     * _.take([1, 2, 3], 2);
17505     * // => [1, 2]
17506     *
17507     * _.take([1, 2, 3], 5);
17508     * // => [1, 2, 3]
17509     *
17510     * _.take([1, 2, 3], 0);
17511     * // => []
17512     */
17513    function take(array, n, guard) {
17514      if (!(array && array.length)) {
17515        return [];
17516      }
17517      n = (guard || n === undefined) ? 1 : toInteger(n);
17518      return baseSlice(array, 0, n < 0 ? 0 : n);
17519    }
17520
17521    /**
17522     * Creates a slice of `array` with `n` elements taken from the end.
17523     *
17524     * @static
17525     * @memberOf _
17526     * @since 3.0.0
17527     * @category Array
17528     * @param {Array} array The array to query.
17529     * @param {number} [n=1] The number of elements to take.
17530     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
17531     * @returns {Array} Returns the slice of `array`.
17532     * @example
17533     *
17534     * _.takeRight([1, 2, 3]);
17535     * // => [3]
17536     *
17537     * _.takeRight([1, 2, 3], 2);
17538     * // => [2, 3]
17539     *
17540     * _.takeRight([1, 2, 3], 5);
17541     * // => [1, 2, 3]
17542     *
17543     * _.takeRight([1, 2, 3], 0);
17544     * // => []
17545     */
17546    function takeRight(array, n, guard) {
17547      var length = array ? array.length : 0;
17548      if (!length) {
17549        return [];
17550      }
17551      n = (guard || n === undefined) ? 1 : toInteger(n);
17552      n = length - n;
17553      return baseSlice(array, n < 0 ? 0 : n, length);
17554    }
17555
17556    /**
17557     * Creates a slice of `array` with elements taken from the end. Elements are
17558     * taken until `predicate` returns falsey. The predicate is invoked with
17559     * three arguments: (value, index, array).
17560     *
17561     * @static
17562     * @memberOf _
17563     * @since 3.0.0
17564     * @category Array
17565     * @param {Array} array The array to query.
17566     * @param {Array|Function|Object|string} [predicate=_.identity]
17567     *  The function invoked per iteration.
17568     * @returns {Array} Returns the slice of `array`.
17569     * @example
17570     *
17571     * var users = [
17572     *   { 'user': 'barney',  'active': true },
17573     *   { 'user': 'fred',    'active': false },
17574     *   { 'user': 'pebbles', 'active': false }
17575     * ];
17576     *
17577     * _.takeRightWhile(users, function(o) { return !o.active; });
17578     * // => objects for ['fred', 'pebbles']
17579     *
17580     * // The `_.matches` iteratee shorthand.
17581     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
17582     * // => objects for ['pebbles']
17583     *
17584     * // The `_.matchesProperty` iteratee shorthand.
17585     * _.takeRightWhile(users, ['active', false]);
17586     * // => objects for ['fred', 'pebbles']
17587     *
17588     * // The `_.property` iteratee shorthand.
17589     * _.takeRightWhile(users, 'active');
17590     * // => []
17591     */
17592    function takeRightWhile(array, predicate) {
17593      return (array && array.length)
17594        ? baseWhile(array, getIteratee(predicate, 3), false, true)
17595        : [];
17596    }
17597
17598    /**
17599     * Creates a slice of `array` with elements taken from the beginning. Elements
17600     * are taken until `predicate` returns falsey. The predicate is invoked with
17601     * three arguments: (value, index, array).
17602     *
17603     * @static
17604     * @memberOf _
17605     * @since 3.0.0
17606     * @category Array
17607     * @param {Array} array The array to query.
17608     * @param {Array|Function|Object|string} [predicate=_.identity]
17609     *  The function invoked per iteration.
17610     * @returns {Array} Returns the slice of `array`.
17611     * @example
17612     *
17613     * var users = [
17614     *   { 'user': 'barney',  'active': false },
17615     *   { 'user': 'fred',    'active': false},
17616     *   { 'user': 'pebbles', 'active': true }
17617     * ];
17618     *
17619     * _.takeWhile(users, function(o) { return !o.active; });
17620     * // => objects for ['barney', 'fred']
17621     *
17622     * // The `_.matches` iteratee shorthand.
17623     * _.takeWhile(users, { 'user': 'barney', 'active': false });
17624     * // => objects for ['barney']
17625     *
17626     * // The `_.matchesProperty` iteratee shorthand.
17627     * _.takeWhile(users, ['active', false]);
17628     * // => objects for ['barney', 'fred']
17629     *
17630     * // The `_.property` iteratee shorthand.
17631     * _.takeWhile(users, 'active');
17632     * // => []
17633     */
17634    function takeWhile(array, predicate) {
17635      return (array && array.length)
17636        ? baseWhile(array, getIteratee(predicate, 3))
17637        : [];
17638    }
17639
17640    /**
17641     * Creates an array of unique values, in order, from all given arrays using
17642     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
17643     * for equality comparisons.
17644     *
17645     * @static
17646     * @memberOf _
17647     * @since 0.1.0
17648     * @category Array
17649     * @param {...Array} [arrays] The arrays to inspect.
17650     * @returns {Array} Returns the new array of combined values.
17651     * @example
17652     *
17653     * _.union([2, 1], [4, 2], [1, 2]);
17654     * // => [2, 1, 4]
17655     */
17656    var union = rest(function(arrays) {
17657      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
17658    });
17659
17660    /**
17661     * This method is like `_.union` except that it accepts `iteratee` which is
17662     * invoked for each element of each `arrays` to generate the criterion by
17663     * which uniqueness is computed. The iteratee is invoked with one argument:
17664     * (value).
17665     *
17666     * @static
17667     * @memberOf _
17668     * @since 4.0.0
17669     * @category Array
17670     * @param {...Array} [arrays] The arrays to inspect.
17671     * @param {Array|Function|Object|string} [iteratee=_.identity]
17672     *  The iterat
17672ee invoked per element.
17673     * @returns {Array} Returns the new array of combined values.
17674     * @example
17675     *
17676     * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
17677     * // => [2.1, 1.2, 4.3]
17678     *
17679     * // The `_.property` iteratee shorthand.
17680     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
17681     * // => [{ 'x': 1 }, { 'x': 2 }]
17682     */
17683    var unionBy = rest(function(arrays) {
17684      var iteratee = last(arrays);
17685      if (isArrayLikeObject(iteratee)) {
17686        iteratee = undefined;
17687      }
17688      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee));
17689    });
17690
17691    /**
17692     * This method is like `_.union` except that it accepts `comparator` which
17693     * is invoked to compare elements of `arrays`. The comparator is invoked
17694     * with two arguments: (arrVal, othVal).
17695     *
17696     * @static
17697     * @memberOf _
17698     * @since 4.0.0
17699     * @category Array
17700     * @param {...Array} [arrays] The arrays to inspect.
17701     * @param {Function} [comparator] The comparator invoked per element.
17702     * @returns {Array} Returns the new array of combined values.
17703     * @example
17704     *
17705     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
17706     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
17707     *
17708     * _.unionWith(objects, others, _.isEqual);
17709     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
17710     */
17711    var unionWith = rest(function(arrays) {
17712      var comparator = last(arrays);
17713      if (isArrayLikeObject(comparator)) {
17714        comparator = undefined;
17715      }
17716      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
17717    });
17718
17719    /**
17720     * Creates a duplicate-free version of an array, using
17721     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
17722     * for equality comparisons, in which only the first occurrence of each
17723     * element is kept.
17724     *
17725     * @static
17726     * @memberOf _
17727     * @since 0.1.0
17728     * @category Array
17729     * @param {Array} array The array to inspect.
17730     * @returns {Array} Returns the new duplicate free array.
17731     * @example
17732     *
17733     * _.uniq([2, 1, 2]);
17734     * // => [2, 1]
17735     */
17736    function uniq(array) {
17737      return (array && array.length)
17738        ? baseUniq(array)
17739        : [];
17740    }
17741
17742    /**
17743     * This method is like `_.uniq` except that it accepts `iteratee` which is
17744     * invoked for each element in `array` to generate the criterion by which
17745     * uniqueness is computed. The iteratee is invoked with one argument: (value).
17746     *
17747     * @static
17748     * @memberOf _
17749     * @since 4.0.0
17750     * @category Array
17751     * @param {Array} array The array to inspect.
17752     * @param {Array|Function|Object|string} [iteratee=_.identity]
17753     *  The iteratee invoked per element.
17754     * @returns {Array} Returns the new duplicate free array.
17755     * @example
17756     *
17757     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
17758     * // => [2.1, 1.2]
17759     *
17760     * // The `_.property` iteratee shorthand.
17761     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
17762     * // => [{ 'x': 1 }, { 'x': 2 }]
17763     */
17764    function uniqBy(array, iteratee) {
17765      return (array && array.length)
17766        ? baseUniq(array, getIteratee(iteratee))
17767        : [];
17768    }
17769
17770    /**
17771     * This method is like `_.uniq` except that it accepts `comparator` which
17772     * is invoked to compare elements of `array`. The comparator is invoked with
17773     * two arguments: (arrVal, othVal).
17774     *
17775     * @static
17776     * @memberOf _
17777     * @since 4.0.0
17778     * @category Array
17779     * @param {Array} array The array to inspect.
17780     * @param {Function} [comparator] The comparator invoked per element.
17781     * @returns {Array} Returns the new duplicate free array.
17782     * @example
17783     *
17784     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
17785     *
17786     * _.uniqWith(objects, _.isEqual);
17787     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
17788     */
17789    function uniqWith(array, comparator) {
17790      return (array && array.length)
17791        ? baseUniq(array, undefined, comparator)
17792        : [];
17793    }
17794
17795    /**
17796     * This method is like `_.zip` except that it accepts an array of grouped
17797     * elements and creates an array regrouping the elements to their pre-zip
17798     * configuration.
17799     *
17800     * @static
17801     * @memberOf _
17802     * @since 1.2.0
17803     * @category Array
17804     * @param {Array} array The array of grouped elements to process.
17805     * @returns {Array} Returns the new array of regrouped elements.
17806     * @example
17807     *
17808     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
17809     * // => [['fred', 30, true], ['barney', 40, false]]
17810     *
17811     * _.unzip(zipped);
17812     * // => [['fred', 'barney'], [30, 40], [true, false]]
17813     */
17814    function unzip(array) {
17815      if (!(array && array.length)) {
17816        return [];
17817      }
17818      var length = 0;
17819      array = arrayFilter(array, function(group) {
17820        if (isArrayLikeObject(group)) {
17821          length = nativeMax(group.length, length);
17822          return true;
17823        }
17824      });
17825      return baseTimes(length, function(index) {
17826        return arrayMap(array, baseProperty(index));
17827      });
17828    }
17829
17830    /**
17831     * This method is like `_.unzip` except that it accepts `iteratee` to specify
17832     * how regrouped values should be combined. The iteratee is invoked with the
17833     * elements of each group: (...group).
17834     *
17835     * @static
17836     * @memberOf _
17837     * @since 3.8.0
17838     * @category Array
17839     * @param {Array} array The array of grouped elements to process.
17840     * @param {Function} [iteratee=_.identity] The function to combine
17841     *  regrouped values.
17842     * @returns {Array} Returns the new array of regrouped elements.
17843     * @example
17844     *
17845     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
17846     * // => [[1, 10, 100], [2, 20, 200]]
17847     *
17848     * _.unzipWith(zipped, _.add);
17849     * // => [3, 30, 300]
17850     */
17851    function unzipWith(array, iteratee) {
17852      if (!(array && array.length)) {
17853        return [];
17854      }
17855      var result = unzip(array);
17856      if (iteratee == null) {
17857        return result;
17858      }
17859      return arrayMap(result, function(group) {
17860        return apply(iteratee, undefined, group);
17861      });
17862    }
17863
17864    /**
17865     * Creates an array excluding all given values using
17866     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
17867     * for equality comparisons.
17868     *
17869     * @static
17870     * @memberOf _
17871     * @since 0.1.0
17872     * @category Array
17873     * @param {Array} array The array to filter.
17874     * @param {...*} [values] The values to exclude.
17875     * @returns {Array} Returns the new array of filtered values.
17876     * @example
17877     *
17878     * _.without([1, 2, 1, 3], 1, 2);
17879     * // => [3]
17880     */
17881    var without = rest(function(array, values) {
17882      return isArrayLikeObject(array)
17883        ? baseDifference(array, values)
17884        : [];
17885    });
17886
17887    /**
17888     * Creates an array of unique values that is the
17889     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
17890     * of the given arrays. The order of result values is determined by the order
17891     * they occur in the arrays.
17892     *
17893     * @static
17894     * @memberOf _
17895     * @since 2.4.0
17896     * @category Array
17897     * @param {...Array} [arrays] The arrays to inspect.
17898     * @returns {Array} Returns the new array of values.
17899     * @example
17900     *
17901     * _.xor([2, 1], [4, 2]);
17902     * // => [1, 4]
17903     */
17904    var xor = rest(function(arrays) {
17905      return baseXor(arrayFilter(arrays, isArrayLikeObject));
17906    });
17907
17908    /**
17909     * This method is like `_.xor` except that it accepts `iteratee` which is
17910     * invoked for each element of each `arrays` to generate the criterion by
17911     * which by which they're compared. The iteratee is invoked with one argument:
17912     * (value).
17913     *
17914     * @static
17915     * @memberOf _
17916     * @since 4.0.0
17917     * @category Array
17918     * @param {...Array} [arrays] The arrays to inspect.
17919     * @param {Array|Function|Object|string} [iteratee=_.identity]
17920     *  The iteratee invoked per element.
17921     * @returns {Array} Returns the new array of values.
17922     * @example
17923     *
17924     * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
17925     * // => [1.2, 4.3]
17926     *
17927     * // The `_.property` iteratee shorthand.
17928     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
17929     * // => [{ 'x': 2 }]
17930     */
17931    var xorBy = rest(function(arrays) {
17932      var iteratee = last(arrays);
17933      if (isArrayLikeObject(iteratee)) {
17934        iteratee = undefined;
17935      }
17936      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
17937    });
17938
17939    /**
17940     * This method is like `_.xor` except that it accepts `comparator` which is
17941     * invoked to compare elements of `arrays`. The comparator is invoked with
17942     * two arguments: (arrVal, othVal).
17943     *
17944     * @static
17945     * @memberOf _
17946     * @since 4.0.0
17947     * @category Array
17948     * @param {...Array} [arrays] The arrays to inspect.
17949     * @param {Function} [comparator] The comparator invoked per element.
17950     * @returns {Array} Returns the new array of values.
17951     * @example
17952     *
17953     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
17954     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
17955     *
17956     * _.xorWith(objects, others, _.isEqual);
17957     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
17958     */
17959    var xorWith = rest(function(arrays) {
17960      var comparator = last(arrays);
17961      if (isArrayLikeObject(comparator)) {
17962        comparator = undefined;
17963      }
17964      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, c
vendor: 5,753 bytes, lines 17964-18156
17964omparator);
17965    });
17966
17967    /**
17968     * Creates an array of grouped elements, the first of which contains the
17969     * first elements of the given arrays, the second of which contains the
17970     * second elements of the given arrays, and so on.
17971     *
17972     * @static
17973     * @memberOf _
17974     * @since 0.1.0
17975     * @category Array
17976     * @param {...Array} [arrays] The arrays to process.
17977     * @returns {Array} Returns the new array of grouped elements.
17978     * @example
17979     *
17980     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
17981     * // => [['fred', 30, true], ['barney', 40, false]]
17982     */
17983    var zip = rest(unzip);
17984
17985    /**
17986     * This method is like `_.fromPairs` except that it accepts two arrays,
17987     * one of property identifiers and one of corresponding values.
17988     *
17989     * @static
17990     * @memberOf _
17991     * @since 0.4.0
17992     * @category Array
17993     * @param {Array} [props=[]] The property identifiers.
17994     * @param {Array} [values=[]] The property values.
17995     * @returns {Object} Returns the new object.
17996     * @example
17997     *
17998     * _.zipObject(['a', 'b'], [1, 2]);
17999     * // => { 'a': 1, 'b': 2 }
18000     */
18001    function zipObject(props, values) {
18002      return baseZipObject(props || [], values || [], assignValue);
18003    }
18004
18005    /**
18006     * This method is like `_.zipObject` except that it supports property paths.
18007     *
18008     * @static
18009     * @memberOf _
18010     * @since 4.1.0
18011     * @category Array
18012     * @param {Array} [props=[]] The property identifiers.
18013     * @param {Array} [values=[]] The property values.
18014     * @returns {Object} Returns the new object.
18015     * @example
18016     *
18017     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
18018     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
18019     */
18020    function zipObjectDeep(props, values) {
18021      return baseZipObject(props || [], values || [], baseSet);
18022    }
18023
18024    /**
18025     * This method is like `_.zip` except that it accepts `iteratee` to specify
18026     * how grouped values should be combined. The iteratee is invoked with the
18027     * elements of each group: (...group).
18028     *
18029     * @static
18030     * @memberOf _
18031     * @since 3.8.0
18032     * @category Array
18033     * @param {...Array} [arrays] The arrays to process.
18034     * @param {Function} [iteratee=_.identity] The function to combine grouped values.
18035     * @returns {Array} Returns the new array of grouped elements.
18036     * @example
18037     *
18038     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
18039     *   return a + b + c;
18040     * });
18041     * // => [111, 222]
18042     */
18043    var zipWith = rest(function(arrays) {
18044      var length = arrays.length,
18045          iteratee = length > 1 ? arrays[length - 1] : undefined;
18046
18047      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
18048      return unzipWith(arrays, iteratee);
18049    });
18050
18051    /*------------------------------------------------------------------------*/
18052
18053    /**
18054     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
18055     * chain sequences enabled. The result of such sequences must be unwrapped
18056     * with `_#value`.
18057     *
18058     * @static
18059     * @memberOf _
18060     * @since 1.3.0
18061     * @category Seq
18062     * @param {*} value The value to wrap.
18063     * @returns {Object} Returns the new `lodash` wrapper instance.
18064     * @example
18065     *
18066     * var users = [
18067     *   { 'user': 'barney',  'age': 36 },
18068     *   { 'user': 'fred',    'age': 40 },
18069     *   { 'user': 'pebbles', 'age': 1 }
18070     * ];
18071     *
18072     * var youngest = _
18073     *   .chain(users)
18074     *   .sortBy('age')
18075     *   .map(function(o) {
18076     *     return o.user + ' is ' + o.age;
18077     *   })
18078     *   .head()
18079     *   .value();
18080     * // => 'pebbles is 1'
18081     */
18082    function chain(value) {
18083      var result = lodash(value);
18084      result.__chain__ = true;
18085      return result;
18086    }
18087
18088    /**
18089     * This method invokes `interceptor` and returns `value`. The interceptor
18090     * is invoked with one argument; (value). The purpose of this method is to
18091     * "tap into" a method chain sequence in order to modify intermediate results.
18092     *
18093     * @static
18094     * @memberOf _
18095     * @since 0.1.0
18096     * @category Seq
18097     * @param {*} value The value to provide to `interceptor`.
18098     * @param {Function} interceptor The function to invoke.
18099     * @returns {*} Returns `value`.
18100     * @example
18101     *
18102     * _([1, 2, 3])
18103     *  .tap(function(array) {
18104     *    // Mutate input array.
18105     *    array.pop();
18106     *  })
18107     *  .reverse()
18108     *  .value();
18109     * // => [2, 1]
18110     */
18111    function tap(value, interceptor) {
18112      interceptor(value);
18113      return value;
18114    }
18115
18116    /**
18117     * This method is like `_.tap` except that it returns the result of `interceptor`.
18118     * The purpose of this method is to "pass thru" values replacing intermediate
18119     * results in a method chain sequence.
18120     *
18121     * @static
18122     * @memberOf _
18123     * @since 3.0.0
18124     * @category Seq
18125     * @param {*} value The value to provide to `interceptor`.
18126     * @param {Function} interceptor The function to invoke.
18127     * @returns {*} Returns the result of `interceptor`.
18128     * @example
18129     *
18130     * _('  abc  ')
18131     *  .chain()
18132     *  .trim()
18133     *  .thru(function(value) {
18134     *    return [value];
18135     *  })
18136     *  .value();
18137     * // => ['abc']
18138     */
18139    function thru(value, interceptor) {
18140      return interceptor(value);
18141    }
18142
18143    /**
18144     * This method is the wrapper version of `_.at`.
18145     *
18146     * @name at
18147     * @memberOf _
18148     * @since 1.0.0
18149     * @category Seq
18150     * @param {...(string|string[])} [paths] The property paths of elements to pick,
18151     *  specified individually or in arrays.
18152     * @returns {Object} Returns the new `lodash` wrapper instance.
18153     * @example
18154     *
18155     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
18156     *
18157     * _(object).at(['a[0].b.c', 'a[1]']).value();
18158     * // => [3, 4]
18159     *
18160     * _(['a', 'b', 'c']).at(0, 2).value();
18161     * // => ['a', 'c']
18162     */
18163    var wrapperAt = rest(function(paths) {
18164      paths = baseFlatten(paths, 1);
vendor: 6,542 bytes, lines 18164-18416
18164
18165      var length = paths.length,
18166          start = length ? paths[0] : 0,
18167          value = this.__wrapped__,
18168          interceptor = function(object) { return baseAt(object, paths); };
18169
18170      if (length > 1 || this.__actions__.length ||
18171          !(value instanceof LazyWrapper) || !isIndex(start)) {
18172        return this.thru(interceptor);
18173      }
18174      value = value.slice(start, +start + (length ? 1 : 0));
18175      value.__actions__.push({
18176        'func': thru,
18177        'args': [interceptor],
18178        'thisArg': undefined
18179      });
18180      return new LodashWrapper(value, this.__chain__).thru(function(array) {
18181        if (length && !array.length) {
18182          array.push(undefined);
18183        }
18184        return array;
18185      });
18186    });
18187
18188    /**
18189     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
18190     *
18191     * @name chain
18192     * @memberOf _
18193     * @since 0.1.0
18194     * @category Seq
18195     * @returns {Object} Returns the new `lodash` wrapper instance.
18196     * @example
18197     *
18198     * var users = [
18199     *   { 'user': 'barney', 'age': 36 },
18200     *   { 'user': 'fred',   'age': 40 }
18201     * ];
18202     *
18203     * // A sequence without explicit chaining.
18204     * _(users).head();
18205     * // => { 'user': 'barney', 'age': 36 }
18206     *
18207     * // A sequence with explicit chaining.
18208     * _(users)
18209     *   .chain()
18210     *   .head()
18211     *   .pick('user')
18212     *   .value();
18213     * // => { 'user': 'barney' }
18214     */
18215    function wrapperChain() {
18216      return chain(this);
18217    }
18218
18219    /**
18220     * Executes the chain sequence and returns the wrapped result.
18221     *
18222     * @name commit
18223     * @memberOf _
18224     * @since 3.2.0
18225     * @category Seq
18226     * @returns {Object} Returns the new `lodash` wrapper instance.
18227     * @example
18228     *
18229     * var array = [1, 2];
18230     * var wrapped = _(array).push(3);
18231     *
18232     * console.log(array);
18233     * // => [1, 2]
18234     *
18235     * wrapped = wrapped.commit();
18236     * console.log(array);
18237     * // => [1, 2, 3]
18238     *
18239     * wrapped.last();
18240     * // => 3
18241     *
18242     * console.log(array);
18243     * // => [1, 2, 3]
18244     */
18245    function wrapperCommit() {
18246      return new LodashWrapper(this.value(), this.__chain__);
18247    }
18248
18249    /**
18250     * Gets the next value on a wrapped object following the
18251     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
18252     *
18253     * @name next
18254     * @memberOf _
18255     * @since 4.0.0
18256     * @category Seq
18257     * @returns {Object} Returns the next iterator value.
18258     * @example
18259     *
18260     * var wrapped = _([1, 2]);
18261     *
18262     * wrapped.next();
18263     * // => { 'done': false, 'value': 1 }
18264     *
18265     * wrapped.next();
18266     * // => { 'done': false, 'value': 2 }
18267     *
18268     * wrapped.next();
18269     * // => { 'done': true, 'value': undefined }
18270     */
18271    function wrapperNext() {
18272      if (this.__values__ === undefined) {
18273        this.__values__ = toArray(this.value());
18274      }
18275      var done = this.__index__ >= this.__values__.length,
18276          value = done ? undefined : this.__values__[this.__index__++];
18277
18278      return { 'done': done, 'value': value };
18279    }
18280
18281    /**
18282     * Enables the wrapper to be iterable.
18283     *
18284     * @name Symbol.iterator
18285     * @memberOf _
18286     * @since 4.0.0
18287     * @category Seq
18288     * @returns {Object} Returns the wrapper object.
18289     * @example
18290     *
18291     * var wrapped = _([1, 2]);
18292     *
18293     * wrapped[Symbol.iterator]() === wrapped;
18294     * // => true
18295     *
18296     * Array.from(wrapped);
18297     * // => [1, 2]
18298     */
18299    function wrapperToIterator() {
18300      return this;
18301    }
18302
18303    /**
18304     * Creates a clone of the chain sequence planting `value` as the wrapped value.
18305     *
18306     * @name plant
18307     * @memberOf _
18308     * @since 3.2.0
18309     * @category Seq
18310     * @param {*} value The value to plant.
18311     * @returns {Object} Returns the new `lodash` wrapper instance.
18312     * @example
18313     *
18314     * function square(n) {
18315     *   return n * n;
18316     * }
18317     *
18318     * var wrapped = _([1, 2]).map(square);
18319     * var other = wrapped.plant([3, 4]);
18320     *
18321     * other.value();
18322     * // => [9, 16]
18323     *
18324     * wrapped.value();
18325     * // => [1, 4]
18326     */
18327    function wrapperPlant(value) {
18328      var result,
18329          parent = this;
18330
18331      while (parent instanceof baseLodash) {
18332        var clone = wrapperClone(parent);
18333        clone.__index__ = 0;
18334        clone.__values__ = undefined;
18335        if (result) {
18336          previous.__wrapped__ = clone;
18337        } else {
18338          result = clone;
18339        }
18340        var previous = clone;
18341        parent = parent.__wrapped__;
18342      }
18343      previous.__wrapped__ = value;
18344      return result;
18345    }
18346
18347    /**
18348     * This method is the wrapper version of `_.reverse`.
18349     *
18350     * **Note:** This method mutates the wrapped array.
18351     *
18352     * @name reverse
18353     * @memberOf _
18354     * @since 0.1.0
18355     * @category Seq
18356     * @returns {Object} Returns the new `lodash` wrapper instance.
18357     * @example
18358     *
18359     * var array = [1, 2, 3];
18360     *
18361     * _(array).reverse().value()
18362     * // => [3, 2, 1]
18363     *
18364     * console.log(array);
18365     * // => [3, 2, 1]
18366     */
18367    function wrapperReverse() {
18368      var value = this.__wrapped__;
18369      if (value instanceof LazyWrapper) {
18370        var wrapped = value;
18371        if (this.__actions__.length) {
18372          wrapped = new LazyWrapper(this);
18373        }
18374        wrapped = wrapped.reverse();
18375        wrapped.__actions__.push({
18376          'func': thru,
18377          'args': [reverse],
18378          'thisArg': undefined
18379        });
18380        return new LodashWrapper(wrapped, this.__chain__);
18381      }
18382      return this.thru(reverse);
18383    }
18384
18385    /**
18386     * Executes the chain sequence to resolve the unwrapped value.
18387     *
18388     * @name value
18389     * @memberOf _
18390     * @since 0.1.0
18391     * @alias toJSON, valueOf
18392     * @category Seq
18393     * @returns {*} Returns the resolved unwrapped value.
18394     * @example
18395     *
18396     * _([1, 2, 3]).value();
18397     * // => [1, 2, 3]
18398     */
18399    function wrapperValue() {
18400      return baseWrapperValue(this.__wrapped__, this.__actions__);
18401    }
18402
18403    /*------------------------------------------------------------------------*/
18404
18405    /**
18406     * Creates an object composed of keys generated from the results of running
18407     * each element of `collection` thru `iteratee`. The corresponding value of
18408     * each key is the number of times the key was returned by `iteratee`. The
18409     * iteratee is invoked with one argument: (value).
18410     *
18411     * @static
18412     * @memberOf _
18413     * @since 0.5.0
18414     * @category Collection
18415     * @param {Array|Object} collection The collection to iterate over.
18416     * @param {
18416Array|Function|Object|string} [iteratee=_.identity]
18417     *  The iteratee to transform keys.
18418     * @returns {Object} Returns the composed aggregate object.
18419     * @example
18420     *
18421     * _.countBy([6.1, 4.2, 6.3], Math.floor);
18422     * // => { '4': 1, '6': 2 }
18423     *
18424     * _.countBy(['one', 'two', 'three'], 'length');
18425     * // => { '3': 2, '5': 1 }
18426     */
18427    var countBy = createAggregator(function(result, value, key) {
18428      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
18429    });
18430
18431    /**
18432     * Checks if `predicate` returns truthy for **all** elements of `collection`.
18433     * Iteration is stopped once `predicate` returns falsey. The predicate is
18434     * invoked with three arguments: (value, index|key, collection).
18435     *
18436     * @static
18437     * @memberOf _
18438     * @since 0.1.0
18439     * @category Collection
18440     * @param {Array|Object} collection The collection to iterate over.
18441     * @param {Array|Function|Object|string} [predicate=_.identity]
18442     *  The function invoked per iteration.
18443     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
18444     * @returns {boolean} Returns `true` if all elements pass the predicate check,
18445     *  else `false`.
18446     * @example
18447     *
18448     * _.every([true, 1, null, 'yes'], Boolean);
18449     * // => false
18450     *
18451     * var users = [
18452     *   { 'user': 'barney', 'age': 36, 'active': false },
18453     *   { 'user': 'fred',   'age': 40, 'active': false }
18454     * ];
18455     *
18456     * // The `_.matches` iteratee shorthand.
18457     * _.every(users, { 'user': 'barney', 'active': false });
18458     * // => false
18459     *
18460     * // The `_.matchesProperty` iteratee shorthand.
18461     * _.every(users, ['active', false]);
18462     * // => true
18463     *
18464     * // The `_.property` iteratee shorthand.
18465     * _.every(users, 'active');
18466     * // => false
18467     */
18468    function every(collection, predicate, guard) {
18469      var func = isArray(collection) ? arrayEvery : baseEvery;
18470      if (guard && isIterateeCall(collection, predicate, guard)) {
18471        predicate = undefined;
18472      }
18473      return func(collection, getIteratee(predicate, 3));
18474    }
18475
18476    /**
18477     * Iterates over elements of `collection`, returning an array of all elements
18478     * `predicate` returns truthy for. The predicate is invoked with three
18479     * arguments: (value, index|key, collection).
18480     *
18481     * @static
18482     * @memberOf _
18483     * @since 0.1.0
18484     * @category Collection
18485     * @param {Array|Object} collection The collection to iterate over.
18486     * @param {Array|Function|Object|string} [predicate=_.identity]
18487     *  The function invoked per iteration.
18488     * @returns {Array} Returns the new filtered array.
18489     * @example
18490     *
18491     * var users = [
18492     *   { 'user': 'barney', 'age': 36, 'active': true },
18493     *   { 'user': 'fred',   'age': 40, 'active': false }
18494     * ];
18495     *
18496     * _.filter(users, function(o) { return !o.active; });
18497     * // => objects for ['fred']
18498     *
18499     * // The `_.matches` iteratee shorthand.
18500     * _.filter(users, { 'age': 36, 'active': true });
18501     * // => objects for ['barney']
18502     *
18503     * // The `_.matchesProperty` iteratee shorthand.
18504     * _.filter(users, ['active', false]);
18505     * // => objects for ['fred']
18506     *
18507     * // The `_.property` iteratee shorthand.
18508     * _.filter(users, 'active');
18509     * // => objects for ['barney']
18510     */
18511    function filter(collection, predicate) {
18512      var func = isArray(collection) ? arrayFilter : baseFilter;
18513      return func(collection, getIteratee(predicate, 3));
18514    }
18515
18516    /**
18517     * Iterates over elements of `collection`, returning the first element
18518     * `predicate` returns truthy for. The predicate is invoked with three
18519     * arguments: (value, index|key, collection).
18520     *
18521     * @static
18522     * @memberOf _
18523     * @since 0.1.0
18524     * @category Collection
18525     * @param {Array|Object} collection The collection to search.
18526     * @param {Array|Function|Object|string} [predicate=_.identity]
18527     *  The function invoked per iteration.
18528     * @returns {*} Returns the matched element, else `undefined`.
18529     * @example
18530     *
18531     * var users = [
18532     *   { 'user': 'barney',  'age': 36, 'active': true },
18533     *   { 'user': 'fred',    'age': 40, 'active': false },
18534     *   { 'user': 'pebbles', 'age': 1,  'active': true }
18535     * ];
18536     *
18537     * _.find(users, function(o) { return o.age < 40; });
18538     * // => object for 'barney'
18539     *
18540     * // The `_.matches` iteratee shorthand.
18541     * _.find(users, { 'age': 1, 'active': true });
18542     * // => object for 'pebbles'
18543     *
18544     * // The `_.matchesProperty` iteratee shorthand.
18545     * _.find(users, ['active', false]);
18546     * // => object for 'fred'
18547     *
18548     * // The `_.property` iteratee shorthand.
18549     * _.find(users, 'active');
18550     * // => object for 'barney'
18551     */
18552    function find(collection, predicate) {
18553      predicate = getIteratee(predicate, 3);
18554      if (isArray(collection)) {
18555        var index = baseFindIndex(collection, predicate);
18556        return index > -1 ? collection[index] : undefined;
18557      }
18558      return baseFind(collection, predicate, baseEach);
18559    }
18560
18561    /**
18562     * This method is like `_.find` except that it iterates over elements of
18563     * `collection` from right to left.
18564     *
18565     * @static
18566     * @memberOf _
18567     * @since 2.0.0
18568     * @category Collection
18569     * @param {Array|Object} collection The collection to search.
18570     * @param {Array|Function|Object|string} [predicate=_.identity]
18571     *  The function invoked per iteration.
18572     * @returns {*} Returns the matched element, else `undefined`.
18573     * @example
18574     *
18575     * _.findLast([1, 2, 3, 4], function(n) {
18576     *   return n % 2 == 1;
18577     * });
18578     * // => 3
18579     */
18580    function findLast(collection, predicate) {
18581      predicate = getIteratee(predicate, 3);
18582      if (isArray(collection)) {
18583        var index = baseFindIndex(collection, predicate, true);
18584        return index > -1 ? collection[index] : undefined;
18585      }
18586      return baseFind(collection, predicate, baseEachRight);
18587    }
18588
18589    /**
18590     * Creates a flattened array of values by running each element in `collection`
18591     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
18592     * with three arguments: (value, index|key, collection).
18593     *
18594     * @static
18595     * @memberOf _
18596     * @since 4.0.0
18597     * @category Collection
18598     * @param {Array|Object} collection The collection to iterate over.
18599     * @param {Array|Function|Object|string} [iteratee=_.identity]
18600     *  The function invoked per iteration.
18601     * @returns {Array} Returns the new flattened array.
18602     * @example
18603     *
18604     * function duplicate(n) {
18605     *   return [n, n];
18606     * }
18607     *
18608     * _.flatMap([1, 2], duplicate);
18609     * // => [1, 1, 2, 2]
18610     */
18611    function flatMap(collection, iteratee) {
18612      return baseFlatten(map(collection, iteratee), 1);
18613    }
18614
18615    /**
18616     * This method is like `_.flatMap` except that it recursively flattens the
18617     * mapped results.
18618     *
18619     * @static
18620     * @memberOf _
18621     * @since 4.7.0
18622     * @category Collection
18623     * @param {Array|Object} collection The collection to iterate over.
18624     * @param {Array|Function|Object|string} [iteratee=_.identity]
18625     *  The function invoked per iteration.
18626     * @returns {Array} Returns the new flattened array.
18627     * @example
18628     *
18629     * function duplicate(n) {
18630     *   return [[[n, n]]];
18631     * }
18632     *
18633     * _.flatMapDeep([1, 2], duplicate);
18634     * // => [1, 1, 2, 2]
18635     */
18636    function flatMapDeep(collection, iteratee) {
18637      return baseFlatten(map(collection, iteratee), INFINITY);
18638    }
18639
18640    /**
18641     * This method is like `_.flatMap` except that it recursively flattens the
18642     * mapped results up to `depth` times.
18643     *
18644     * @static
18645     * @memberOf _
18646     * @since 4.7.0
18647     * @category Collection
18648     * @param {Array|Object} collection The collection to iterate over.
18649     * @param {Array|Function|Object|string} [iteratee=_.identity]
18650     *  The function invoked per iteration.
18651     * @param {number} [depth=1] The maximum recursion depth.
18652     * @returns {Array} Returns the new flattened array.
18653     * @example
18654     *
18655     * function duplicate(n) {
18656     *   return [[[n, n]]];
18657     * }
18658     *
18659     * _.flatMapDepth([1, 2], duplicate, 2);
18660     * // => [[1, 1], [2, 2]]
18661     */
18662    function flatMapDepth(collection, iteratee, depth) {
18663      depth = depth === undefined ? 1 : toInteger(depth);
18664      return baseFlatten(map(collection, iteratee), depth);
18665    }
18666
18667    /**
18668     * Iterates over elements of `collection` invoking `iteratee` for each element.
18669     * The iteratee is invoked with three arguments: (value, index|key, collection).
18670     * Iteratee functions may exit iteration early by explicitly returning `false`.
18671     *
18672     * **Note:** As with other "Collections" methods, objects with a "length"
18673     * property are iterated like arrays. To avoid this behavior use `_.forIn`
18674     * or `_.forOwn` for object iteration.
18675     *
18676     * @static
18677     * @memberOf _
18678     * @since 0.1.0
18679     * @alias each
18680     * @category Collection
18681     * @param {Array|Object} collection The collection to iterate over.
18682     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
18683     * @returns {Array|Object} Returns `collection`.
18684     * @example
18685     *
18686     * _([1, 2]).forEach(function(value) {
18687     *   console.log(value);
18688     * });
18689     * // => Logs `1` then `2`.
18690     *
18691     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
18692     *   console.log(key);
18693     * });
18694     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
18695     */
18696    function forEach(collection, iteratee) {
18697      return (typeof iteratee == 'function' && isArray(collection))
18698        ? arrayEach(collection, iteratee)
18699        : baseEach(collection, getIteratee(iteratee));
18700    }
18701
18702    /**
18703     * This method is like `_.forEach` except that it iterates over elements of
18704     * `collection` from right to left.
18705     *
18706     * @static
18707     * @memberOf _
18708     * @since 2.0.0
18709     * @alias eachRight
18710     * @category Collection
18711     * @param {Array|Object} collection The collection to iterate over.
18712     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
18713     * @returns {Array|Object} Returns `collection`.
18714     * @example
18715     *
18716     * _.forEachRight([1, 2], function(value) {
18717     *   console.log(value);
18718     * });
18719     * // => Logs `2` then `1`.
18720     */
18721    function forEachRight(collection, iteratee) {
18722      return (typeof iteratee == 'function' && isArray(collection))
18723        ? arrayEachRight(collection, iteratee)
18724        : baseEachRight(collection, getIteratee(iteratee));
18725    }
18726
18727    /**
18728     * Creates an object composed of keys generated from the results of running
18729     * each element of `collection` thru `iteratee`. The order of grouped values
18730     * is determined by the order they occur in `collection`. The corresponding
18731     * value of each key is an array of elements responsible for generating the
18732     * key. The iteratee is invoked with one argument: (value).
18733     *
18734     * @static
18735     * @memberOf _
18736     * @since 0.1.0
18737     * @category Collection
18738     * @param {Array|Object} collection The collection to iterate over.
18739     * @param {Array|Function|Object|string} [iteratee=_.identity]
18740     *  The iteratee to transform keys.
18741     * @returns {Object} Returns the composed aggregate object.
18742     * @example
18743     *
18744     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
18745     * // => { '4': [4.2], '6': [6.1, 6.3] }
18746     *
18747     * // The `_.property` iteratee shorthand.
18748     * _.groupBy(['one', 'two', 'three'], 'length');
18749     * // => { '3': ['one', 'two'], '5': ['three'] }
18750     */
18751    var groupBy = createAggregator(function(result, value, key) {
18752      if (hasOwnProperty.call(result, key)) {
18753        result[key].push(value);
18754      } else {
18755        result[key] = [value];
18756      }
18757    });
18758
18759    /**
18760     * Checks if `value` is in `collection`. If `collection` is a string, it's
18761     * checked for a substring of `value`, otherwise
18762     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
18763     * is used for equality comparisons. If `fromIndex` is negative, it's used as
18764     * the offset from the end of `collection`.
18765     *
18766     * @static
18767     * @memberOf _
18768     * @since 0.1.0
18769     * @category Collection
18770     * @param {Array|Object|string} collection The collection to search.
18771     * @param {*} value The value to search for.
18772     * @param {number} [fromIndex=0] The index to search from.
18773     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
18774     * @returns {boolean} Returns `true` if `value` is found, else `false`.
18775     * @example
18776     *
18777     * _.includes([1, 2, 3], 1);
18778     * // => true
18779     *
18780     * _.includes([1, 2, 3], 1, 2);
18781     * // => false
18782     *
18783     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
18784     * // => true
18785     *
18786     * _.includes('pebbles', 'eb');
18787     * // => true
18788     */
18789    function includes(collection, value, fromIndex, guard) {
18790      collection = isArrayLike(collection) ? collection : values(collection);
18791      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
18792
18793      var length = collection.length;
18794      if (fromIndex < 0) {
18795        fromIndex = nativeMax(length + fromIndex, 0);
18796      }
18797      return isString(collection)
18798        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
18799        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
18800    }
18801
18802    /**
18803     * Invokes the method at `path` of each element in `collection`, returning
18804     * an array of the results of each invoked method. Any additional arguments
18805     * are provided to each invoked method. If `methodName` is a function, it's
18806     * invoked for and `this` bound to, each element in `collection`.
18807     *
18808     * @static
18809     * @memberOf _
18810     * @since 4.0.0
18811     * @category Collection
18812     * @param {Array|Object} collection The collection to iterate over.
18813     * @param {Array|Function|string} path The path of the method to invoke or
18814     *  the function invoked per iteration.
18815     * @param {...*} [args] The arguments to invoke each method with.
18816     * @returns {Array} Returns the array of results.
18817     * @example
18818     *
18819     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
18820     * // => [[1, 5, 7], [1, 2, 3]]
18821     *
18822     * _.invokeMap([123, 456], String.prototype.split, '');
18823     * // => [['1', '2', '3'], ['4', '5', '6']]
18824     */
18825    var invokeMap = rest(function(collection, path, args) {
18826      var index = -1,
18827          isFunc = typeof path == 'function',
18828          isProp = isKey(path),
18829          result = isArrayLike(collection) ? Array(collection.length) : [];
18830
18831      baseEach(collection, function(value) {
18832        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
vendor: 9,436 bytes, lines 18833-19085
18833        result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
18834      });
18835      return result;
18836    });
18837
18838    /**
18839     * Creates an object composed of keys generated from the results of running
18840     * each element of `collection` thru `iteratee`. The corresponding value of
18841     * each key is the last element responsible for generating the key. The
18842     * iteratee is invoked with one argument: (value).
18843     *
18844     * @static
18845     * @memberOf _
18846     * @since 4.0.0
18847     * @category Collection
18848     * @param {Array|Object} collection The collection to iterate over.
18849     * @param {Array|Function|Object|string} [iteratee=_.identity]
18850     *  The iteratee to transform keys.
18851     * @returns {Object} Returns the composed aggregate object.
18852     * @example
18853     *
18854     * var array = [
18855     *   { 'dir': 'left', 'code': 97 },
18856     *   { 'dir': 'right', 'code': 100 }
18857     * ];
18858     *
18859     * _.keyBy(array, function(o) {
18860     *   return String.fromCharCode(o.code);
18861     * });
18862     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
18863     *
18864     * _.keyBy(array, 'dir');
18865     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
18866     */
18867    var keyBy = createAggregator(function(result, value, key) {
18868      result[key] = value;
18869    });
18870
18871    /**
18872     * Creates an array of values by running each element in `collection` thru
18873     * `iteratee`. The iteratee is invoked with three arguments:
18874     * (value, index|key, collection).
18875     *
18876     * Many lodash methods are guarded to work as iteratees for methods like
18877     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
18878     *
18879     * The guarded methods are:
18880     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
18881     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
18882     * `sampleSize`, `slice`, `some`, `sortBy`, `take`, `takeRight`, `template`,
18883     * `trim`, `trimEnd`, `trimStart`, and `words`
18884     *
18885     * @static
18886     * @memberOf _
18887     * @since 0.1.0
18888     * @category Collection
18889     * @param {Array|Object} collection The collection to iterate over.
18890     * @param {Array|Function|Object|string} [iteratee=_.identity]
18891     *  The function invoked per iteration.
18892     * @returns {Array} Returns the new mapped array.
18893     * @example
18894     *
18895     * function square(n) {
18896     *   return n * n;
18897     * }
18898     *
18899     * _.map([4, 8], square);
18900     * // => [16, 64]
18901     *
18902     * _.map({ 'a': 4, 'b': 8 }, square);
18903     * // => [16, 64] (iteration order is not guaranteed)
18904     *
18905     * var users = [
18906     *   { 'user': 'barney' },
18907     *   { 'user': 'fred' }
18908     * ];
18909     *
18910     * // The `_.property` iteratee shorthand.
18911     * _.map(users, 'user');
18912     * // => ['barney', 'fred']
18913     */
18914    function map(collection, iteratee) {
18915      var func = isArray(collection) ? arrayMap : baseMap;
18916      return func(collection, getIteratee(iteratee, 3));
18917    }
18918
18919    /**
18920     * This method is like `_.sortBy` except that it allows specifying the sort
18921     * orders of the iteratees to sort by. If `orders` is unspecified, all values
18922     * are sorted in ascending order. Otherwise, specify an order of "desc" for
18923     * descending or "asc" for ascending sort order of corresponding values.
18924     *
18925     * @static
18926     * @memberOf _
18927     * @since 4.0.0
18928     * @category Collection
18929     * @param {Array|Object} collection The collection to iterate over.
18930     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
18931     *  The iteratees to sort by.
18932     * @param {string[]} [orders] The sort orders of `iteratees`.
18933     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
18934     * @returns {Array} Returns the new sorted array.
18935     * @example
18936     *
18937     * var users = [
18938     *   { 'user': 'fred',   'age': 48 },
18939     *   { 'user': 'barney', 'age': 34 },
18940     *   { 'user': 'fred',   'age': 40 },
18941     *   { 'user': 'barney', 'age': 36 }
18942     * ];
18943     *
18944     * // Sort by `user` in ascending order and by `age` in descending order.
18945     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
18946     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
18947     */
18948    function orderBy(collection, iteratees, orders, guard) {
18949      if (collection == null) {
18950        return [];
18951      }
18952      if (!isArray(iteratees)) {
18953        iteratees = iteratees == null ? [] : [iteratees];
18954      }
18955      orders = guard ? undefined : orders;
18956      if (!isArray(orders)) {
18957        orders = orders == null ? [] : [orders];
18958      }
18959      return baseOrderBy(collection, iteratees, orders);
18960    }
18961
18962    /**
18963     * Creates an array of elements split into two groups, the first of which
18964     * contains elements `predicate` returns truthy for, the second of which
18965     * contains elements `predicate` returns falsey for. The predicate is
18966     * invoked with one argument: (value).
18967     *
18968     * @static
18969     * @memberOf _
18970     * @since 3.0.0
18971     * @category Collection
18972     * @param {Array|Object} collection The collection to iterate over.
18973     * @param {Array|Function|Object|string} [predicate=_.identity]
18974     *  The function invoked per iteration.
18975     * @returns {Array} Returns the array of grouped elements.
18976     * @example
18977     *
18978     * var users = [
18979     *   { 'user': 'barney',  'age': 36, 'active': false },
18980     *   { 'user': 'fred',    'age': 40, 'active': true },
18981     *   { 'user': 'pebbles', 'age': 1,  'active': false }
18982     * ];
18983     *
18984     * _.partition(users, function(o) { return o.active; });
18985     * // => objects for [['fred'], ['barney', 'pebbles']]
18986     *
18987     * // The `_.matches` iteratee shorthand.
18988     * _.partition(users, { 'age': 1, 'active': false });
18989     * // => objects for [['pebbles'], ['barney', 'fred']]
18990     *
18991     * // The `_.matchesProperty` iteratee shorthand.
18992     * _.partition(users, ['active', false]);
18993     * // => objects for [['barney', 'pebbles'], ['fred']]
18994     *
18995     * // The `_.property` iteratee shorthand.
18996     * _.partition(users, 'active');
18997     * // => objects for [['fred'], ['barney', 'pebbles']]
18998     */
18999    var partition = createAggregator(function(result, value, key) {
19000      result[key ? 0 : 1].push(value);
19001    }, function() { return [[], []]; });
19002
19003    /**
19004     * Reduces `collection` to a value which is the accumulated result of running
19005     * each element in `collection` thru `iteratee`, where each successive
19006     * invocation is supplied the return value of the previous. If `accumulator`
19007     * is not given, the first element of `collection` is used as the initial
19008     * value. The iteratee is invoked with four arguments:
19009     * (accumulator, value, index|key, collection).
19010     *
19011     * Many lodash methods are guarded to work as iteratees for methods like
19012     * `_.reduce`, `_.reduceRight`, and `_.transform`.
19013     *
19014     * The guarded methods are:
19015     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
19016     * and `sortBy`
19017     *
19018     * @static
19019     * @memberOf _
19020     * @since 0.1.0
19021     * @category Collection
19022     * @param {Array|Object} collection The collection to iterate over.
19023     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
19024     * @param {*} [accumulator] The initial value.
19025     * @returns {*} Returns the accumulated value.
19026     * @example
19027     *
19028     * _.reduce([1, 2], function(sum, n) {
19029     *   return sum + n;
19030     * }, 0);
19031     * // => 3
19032     *
19033     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
19034     *   (result[value] || (result[value] = [])).push(key);
19035     *   return result;
19036     * }, {});
19037     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
19038     */
19039    function reduce(collection, iteratee, accumulator) {
19040      var func = isArray(collection) ? arrayReduce : baseReduce,
19041          initAccum = arguments.length < 3;
19042
19043      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
19044    }
19045
19046    /**
19047     * This method is like `_.reduce` except that it iterates over elements of
19048     * `collection` from right to left.
19049     *
19050     * @static
19051     * @memberOf _
19052     * @since 0.1.0
19053     * @category Collection
19054     * @param {Array|Object} collection The collection to iterate over.
19055     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
19056     * @param {*} [accumulator] The initial value.
19057     * @returns {*} Returns the accumulated value.
19058     * @example
19059     *
19060     * var array = [[0, 1], [2, 3], [4, 5]];
19061     *
19062     * _.reduceRight(array, function(flattened, other) {
19063     *   return flattened.concat(other);
19064     * }, []);
19065     * // => [4, 5, 2, 3, 0, 1]
19066     */
19067    function reduceRight(collection, iteratee, accumulator) {
19068      var func = isArray(collection) ? arrayReduceRight : baseReduce,
19069          initAccum = arguments.length < 3;
19070
19071      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
19072    }
19073
19074    /**
19075     * The opposite of `_.filter`; this method returns the elements of `collection`
19076     * that `predicate` does **not** return truthy for.
19077     *
19078     * @static
19079     * @memberOf _
19080     * @since 0.1.0
19081     * @category Collection
19082     * @param {Array|Object} collection The collection to iterate over.
19083     * @param {Array|Function|Object|string} [predicate=_.identity]
19084     *  The function invoked per iteration.
19085     * @returns {Array} Returns the new filtered array.
19086     * @example
19087     *
19088     * var users = [
19089     *   { 'user': 'barney', 'age': 36, 'active': false },
19090     *   { 'user': 'fred',   'age': 40, 'active': true }
19091     * ];
19092     *
19093     * _.reject(users, function(o) { return !o.active; });
19094     * // => objects for ['fred']
19095     *
19096     * // The `_.matches` iteratee shorthand.
19097     * _.reject(users, { 'age': 40, 'active': true });
19098     * // => objects for ['barney']
19099     *
19100     * // The `_.matchesProperty` iteratee shorthand.
19101     * _.reject(users, ['active', false]);
19102     * // => objects for ['fred']
19103     *
19104     * // The `_.property` iteratee shorthand.
19105     * _.reject(users, 'active');
19106     * // => objects for ['barney']
19107     */
19108    function reject(collection, predicate) {
19109      var func = isArray(collection) ? arrayFilter : baseFilter;
19110      predicate = getIteratee(predicate, 3);
19111      return func(collection, function(value, index, collection) {
19112        return !predicate(value, index, collection);
19113      });
19114    }
19115
19116    /**
19117     * Gets a random element from `collection`.
19118     *
19119     * @static
19120     * @memberOf _
19121     * @since 2.0.0
19122     * @category Collection
19123     * @param {Array|Object} collection The collection to sample.
19124     * @returns {*} Returns the random element.
19125     * @example
19126     *
19127     * _.sample([1, 2, 3, 4]);
19128     * // => 2
19129     */
19130    function sample(collection) {
19131      var array = isArrayLike(collection) ? collection : values(collection),
19132          length = array.length;
19133
19134      return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
19135    }
19136
19137    /**
19138     * Gets `n` random elements at unique keys from `collection` up to the
19139     * size of `collection`.
19140     *
19141     * @static
19142     * @memberOf _
19143     * @since 4.0.0
19144     * @category Collection
19145     * @param {Array|Object} collection The collection to sample.
19146     * @param {number} [n=1] The number of elements to sample.
19147     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
19148     * @returns {Array} Returns the random elements.
19149     * @example
19150     *
19151     * _.sampleSize([1, 2, 3], 2);
19152     * // => [3, 1]
19153     *
19154     * _.sampleSize([1, 2, 3], 4);
19155     * // => [2, 3, 1]
19156     */
19157    function sampleSize(collection, n, guard) {
19158      var index = -1,
19159          result = toArray(collection),
19160          length = result.length,
19161          lastIndex = length - 1;
19162
19163      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
19164        n = 1;
19165      } else {
19166        n = baseClamp(toInteger(n), 0, length);
19167      }
19168      while (++index < n) {
19169        var rand = baseRandom(index, lastIndex),
19170            value = result[rand];
19171
19172        result[rand] = result[index];
19173        result[index] = value;
19174      }
19175      result.length = n;
19176      return result;
19177    }
19178
19179    /**
19180     * Creates an array of shuffled values, using a version of the
19181     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
19182     *
19183     * @static
19184     * @memberOf _
19185     * @since 0.1.0
19186     * @category Collection
19187     * @param {Array|Object} collection The collection to shuffle.
19188     * @returns {Array} Returns the new shuffled array.
19189     * @example
19190     *
19191     * _.shuffle([1, 2, 3, 4]);
19192     * // => [4, 1, 3, 2]
19193     */
19194    function shuffle(collection) {
19195      return sampleSize(collection, MAX_ARRAY_LENGTH);
19196    }
19197
19198    /**
19199     * Gets the size of `collection` by returning its length for array-like
19200     * values or the number of own enumerable string keyed properties for objects.
19201     *
19202     * @static
19203     * @memberOf _
19204     * @since 0.1.0
19205     * @category Collection
19206     * @param {Array|Object} collection The collection to inspect.
19207     * @returns {number} Returns the collection size.
19208     * @example
19209     *
19210     * _.size([1, 2, 3]);
19211     * // => 3
19212     *
19213     * _.size({ 'a': 1, 'b': 2 });
19214     * // => 2
19215     *
19216     * _.size('pebbles');
19217     * // => 7
19218     */
19219    function size(collection) {
19220      if (collection == null) {
19221        return 0;
19222      }
19223      if (isArrayLike(collection)) {
19224        var result = collection.length;
19225        return (result && isString(collection)) ? stringSize(collection) : result;
19226      }
19227      if (isObjectLike(collection)) {
19228        var tag = getTag(collection);
19229        if (tag == mapTag || tag == setTag) {
19230          return collection.size;
19231        }
19232      }
19233      return keys(collection).length;
19234    }
19235
19236    /**
19237     * Checks if `predicate` returns truthy for **any** element of `collection`.
19238     * Iteration is stopped once `predicate` returns truthy. The predicate is
19239     * invoked with three arguments: (value, index|key, collection).
19240     *
19241     * @static
19242     * @memberOf _
19243     * @since 0.1.0
19244     * @category Collection
19245     * @param {Array|Object} collection The collection to iterate over.
19246     * @param {Array|Function|Object|string} [predicate=_.identity]
19247     *  The function invoked per iteration.
19248     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
19249     * @returns {boolean} Returns `true` if any element passes the predicate check,
19250     *  else `false`.
19251     * @example
19252     *
19253     * _.some([null, 0, 'yes', false], Boolean);
19254     * // => true
19255     *
19256     * var users = [
19257     *   { 'user': 'barney', 'active': true },
19258     *   { 'user': 'fred',   'active': false }
19259     * ];
19260     *
19261     * // The `_.matches` iteratee shorthand.
19262     * _.some(users, { 'user': 'barney', 'active': false });
19263     * // => false
19264     *
19265     * // The `_.matchesProperty` iteratee shorthand.
19266     * _.some(users, ['active', false]);
19267     * // => true
19268     *
19269     * // The `_.property` iteratee shorthand.
19270     * _.some(users, 'active');
19271     * // => true
19272     */
19273    function some(collection, predicate, guard) {
19274      var func = isArray(collection) ? arraySome : baseSome;
19275      if (guard && isIterateeCall(collection, predicate, guard)) {
19276        predicate = undefined;
19277      }
19278      return func(collection, getIteratee(predicate, 3));
19279    }
19280
19281    /**
19282     * Creates an array of elements, sorted in ascending order by the results of
19283     * running each element in a collection thru each iteratee. This method
19284     * performs a stable sort, that is, it preserves the original sort order of
19285     * equal elements. The iteratees are invoked with one argument: (value).
19286     *
19287     * @static
19288     * @memberOf _
19289     * @since 0.1.0
19290     * @category Collection
19291     * @param {Array|Object} collection The collection to iterate over.
19292     * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
19293     *  [iteratees=[_.identity]] The iteratees to sort by, specified individually
19294     *  or in arrays.
19295     * @returns {Array} Returns the new sorted array.
19296     * @example
19297     *
19298     * var users = [
19299     *   { 'user': 'fred',   'age': 48 },
19300     *   { 'user': 'barney', 'age': 36 },
19301     *   { 'user': 'fred',   'age': 40 },
19302     *   { 'user': 'barney', 'age': 34 }
19303     * ];
19304     *
19305     * _.sortBy(users, function(o) { return o.user; });
19306     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
19307     *
19308     * _.sortBy(users, ['user', 'age']);
19309     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
19310     *
19311     * _.sortBy(users, 'user', function(o) {
19312     *   return Math.floor(o.age / 10);
19313     * });
19314     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
19315     */
19316    var sortBy = rest(function(collection, iteratees) {
19317      if (collection == null) {
19318        return [];
19319      }
19320      var length = iteratees.length;
19321      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
19322        iteratees = [];
19323      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
19324        iteratees.length = 1;
19325      }
19326      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
19327    });
19328
19329    /*------------------------------------------------------------------------*/
19330
19331    /**
19332     * Gets the timestamp of the number of milliseconds that have elapsed since
19333     * the Unix epoch (1 January 1970 00:00:00 UTC).
19334     *
19335     * @static
19336     * @memberOf _
19337     * @since 2.4.0
19338     * @type {Function}
19339     * @category Date
19340     * @returns {number} Returns the timestamp.
19341     * @example
19342     *
19343     * _.defer(function(stamp) {
19344     *   console.log(_.now() - stamp);
19345     * }, _.now());
19346     * // => Logs the number of milliseconds it took for the deferred function to be invoked.
19347     */
19348    var now = Date.now;
19349
19350    /*------------------------------------------------------------------------*/
19351
19352    /**
19353     * The opposite of `_.before`; this method creates a function that invokes
19354     * `func` once it's called `n` or more times.
19355     *
19356     * @static
19357     * @memberOf _
19358     * @since 0.1.0
19359     * @category Function
19360     * @param {number} n The number of calls before `func` is invoked.
19361     * @param {Function} func The function to restrict.
19362     * @returns {Function} Returns the new restricted function.
19363     * @example
19364     *
19365     * var saves = ['profile', 'settings'];
19366     *
19367     * var done = _.after(saves.length, function() {
19368     *   console.log('done saving!');
19369     * });
19370     *
19371     * _.forEach(saves, function(type) {
19372     *   asyncSave({ 'type': type, 'complete': done });
19373     * });
19374     * // => Logs 'done saving!' after the two async saves have completed.
19375     */
19376    function after(n, func) {
19377      if (typeof func != 'function') {
19378        throw new TypeError(FUNC_ERROR_TEXT);
19379      }
19380      n = toInteger(n);
19381      return function() {
19382        if (--n < 1) {
19383          return func.apply(this, arguments);
19384        }
19385      };
19386    }
19387
19388    /**
19389     * Creates a function that invokes `func`, with up to `n` arguments,
19390     * ignoring any additional arguments.
19391     *
19392     * @static
19393     * @memberOf _
19394     * @since 3.0.0
19395     * @category Function
19396     * @param {Function} func The function to cap arguments for.
19397     * @param {number} [n=func.length] The arity cap.
19398     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
19399     * @returns {Function} Returns the new function.
19400     * @example
19401     *
19402     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
19403     * // => [6, 8, 10]
19404     */
19405    function ary(func, n, guard) {
19406      n = guard ? undefined : n;
19407      n = (func && n == null) ? func.length : n;
19408      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
19409    }
19410
19411    /**
19412     * Creates a function that invokes `func`, with the `this` binding and arguments
19413     * of the created function, while it's called less than `n` times. Subsequent
19414     * calls to the created function return the result of the last `func` invocation.
19415     *
19416     * @static
19417     * @memberOf _
19418     * @since 3.0.0
19419     * @category Function
19420     * @param {number} n The number of calls at which `func` is no longer invoked.
19421     * @param {Function} func The function to restrict.
19422     * @returns {Function} Returns the new restricted function.
19423     * @example
19424     *
19425     * jQuery(element).on('click', _.before(5, addContactToList));
19426     * // => allows adding up to 4 contacts to the list
19427     */
19428    function before(n, func) {
19429      var result;
19430      if (typeof func != 'function') {
19431        throw new TypeError(FUNC_ERROR_TEXT);
19432      }
19433      n = toInteger(n);
19434      return function() {
19435        if (--n > 0) {
19436          result = func.apply(this, arguments);
19437        }
19438        if (n <= 1) {
19439          func = undefined;
19440        }
19441        return result;
19442      };
19443    }
19444
19445    /**
19446     * Creates a function that invokes `func` with the `this` binding of `thisArg`
19447     * and `partials` prepended to the arguments it receives.
19448     *
19449     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
19450     * may be used as a placeholder for partially applied arguments.
19451     *
19452     * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
19453     * property of bound functions.
19454     *
19455     * @static
19456     * @memberOf _
19457     * @since 0.1.0
19458     * @category Function
19459     * @param {Function} func The function to bind.
19460     * @param {*} thisArg The `this` binding of `func`.
19461     * @param {...*} [partials] The arguments to be partially applied.
19462     * @returns {Function} Returns the new bound function.
19463     * @example
19464     *
19465     * var greet = function(greeting, punctuation) {
19466     *   return greeting + ' ' + this.user + punctuation;
19467     * };
19468     *
19469     * var object = { 'user': 'fred' };
19470     *
19471     * var bound = _.bind(greet, object, 'hi');
19472     * bound('!');
19473     * // => 'hi fred!'
19474     *
19475     * // Bound with placeholders.
19476     * var bound = _.bind(greet, object, _, '!');
19477     * bound('hi');
19478     * // => 'hi fred!'
19479     */
19480    var bind = rest(function(func, thisArg, partials) {
19481      var bitmask = BIND_FLAG;
19482      if (partials.length) {
19483        var holders = replaceHolders(partials, getPlaceholder(bind));
19484        bitmask |= PARTIAL_FLAG;
19485      }
19486      return createWrapper(func, bitmask, thisArg, partials, holders);
19487    });
19488
19489    /**
19490     * Creates a function that invokes the method at `object[key]` with `partials`
19491     * prepended to the arguments it receives.
19492     *
19493     * This method differs from `_.bind` by allowing bound functions to reference
19494     * methods that may be redefined or don't yet exist. See
19495     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
19496     * for more details.
19497     *
19498     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
19499     * builds, may be used as a placeholder for partially applied arguments.
19500     *
19501     * @static
19502     * @memberOf _
19503     * @since 0.10.0
19504     * @category Function
19505     * @param {Object} object The object to invoke the method on.
19506     * @param {string} key The key of the method.
19507     * @param {...*} [partials] The arguments to be partially applied.
19508     * @returns {Function} Returns the new bound function.
19509     * @example
19510     *
19511     * var object = {
19512     *   'user': 'fred',
19513     *   'greet': function(greeting, punctuation) {
19514     *     return greeting + ' ' + this.user + punctuation;
19515     *   }
19516     * };
19517     *
19518     * var bound = _.bindKey(object, 'greet', 'hi');
19519     * bound('!');
19520     * // => 'hi fred!'
19521     *
19522     * object.greet = function(greeting, punctuation) {
19523     *   return greeting + 'ya ' + this.user + punctuation;
19524     * };
19525     *
19526     * bound('!');
19527     * // => 'hiya fred!'
19528     *
19529     * // Bound with placeholders.
19530     * var bound = _.bindKey(object, 'greet', _, '!');
19531     * bound('hi');
19532     * // => 'hiya fred!'
19533     */
19534    var bindKey = rest(function(object, key, partials) {
19535      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
19536      if (partials.length) {
19537        var holders = replaceHolders(partials, getPlaceholder(bindKey));
19538        bitmask |= PARTIAL_FLAG;
19539      }
19540      return createWrapper(key, bitmask, object, partials, holders);
19541    });
19542
19543    /**
19544     * Creates a function that accepts arguments of `func` and either invokes
19545     * `func` returning its result, if at least `arity` number of arguments have
19546     * been provided, or returns a function that accepts the remaining `func`
19547     * arguments, and so on. The arity of `func` may be specified if `func.length`
19548     * is not sufficient.
19549     *
19550     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
19551     * may be used as a placeholder for provided arguments.
19552     *
19553     * **Note:** This method doesn't set the "length" property of curried functions.
19554     *
19555     * @static
19556     * @memberOf _
19557     * @since 2.0.0
19558     * @category Function
19559     * @param {Function} func The function to curry.
19560     * @param {number} [arity=func.length] The arity of `func`.
19561     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
19562     * @returns {Function} Returns the new curried function.
19563     * @example
19564     *
19565     * var abc = function(a, b, c) {
19566     *   return [a, b, c];
19567     * };
19568     *
19569     * var curried = _.curry(abc);
19570     *
19571     * curried(1)(2)(3);
19572     * // => [1, 2, 3]
19573     *
19574     * curried(1, 2)(3);
19575     * // => [1, 2, 3]
19576     *
19577     * curried(1, 2, 3);
19578     * // => [1, 2, 3]
19579     *
19580     * // Curried with placeholders.
19581     * curried(1)(_, 3)(2);
19582     * // => [1, 2, 3]
19583     */
19584    function curry(func, arity, guard) {
19585      arity = guard ? undefined : arity;
19586      var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
19587      result.placeholder = curry.placeholder;
19588      return result;
19589    }
19590
19591    /**
19592     * This method is like `_.curry` except that arguments are applied to `func`
19593     * in the manner of `_.partialRight` instead of `_.partial`.
19594     *
19595     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
19596     * builds, may be used as a placeholder for provided arguments.
19597     *
19598     * **Note:** This method doesn't set the "length" property of curried functions.
19599     *
19600     * @static
19601     * @memberOf _
19602     * @since 3.0.0
19603     * @category Function
19604     * @param {Function} func The function to curry.
19605     * @param {number} [arity=func.length] The arity of `func`.
19606     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
19607     * @returns {Function} Returns the new curried function.
19608     * @example
19609     *
19610     * var abc = function(a, b, c) {
19611     *   return [a, b, c];
19612     * };
19613     *
19614     * var curried = _.curryRight(abc);
19615     *
19616     * curried(3)(2)(1);
19617     * // => [1, 2, 3]
19618     *
19619     * curried(2, 3)(1);
19620     * // => [1, 2, 3]
19621     *
19622     * curried(1, 2, 3);
19623     * // => [1, 2, 3]
19624     *
19625     * // Curried with placeholders.
19626     * curried(3)(1, _)(2);
19627     * // => [1, 2, 3]
19628     */
19629    function curryRight(func, arity, guard) {
19630      arity = guard ? undefined : arity;
19631      var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
19632      result.placeholder = curryRight.placeholder;
19633      return result;
19634    }
19635
19636    /**
19637     * Creates a debounced function that delays invoking `func` until after `wait`
19638     * milliseconds have elapsed since the last time the debounced function was
19639     * invoked. The debounced function comes with a `cancel` method to cancel
19640     * delayed `func` invocations and a `flush` method to immediately invoke them.
19641     * Provide an options object to indicate whether `func` should be invoked on
19642     * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
19643     * with the last arguments provided to the debounced function. Subsequent calls
19644     * to the debounced function return the result of the last `func` invocation.
19645     *
19646     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
19647     * on the trailing edge of the timeout only if the debounced function is
19648     * invoked more than once during the `wait` timeout.
19649     *
19650     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
19651     * for details over the differences between `_.debounce` and `_.throttle`.
19652     *
19653     * @static
19654     * @memberOf _
19655     * @since 0.1.0
19656     * @category Function
19657     * @param {Function} func The function to debounce.
19658     * @param {number} [wait=0] The number of milliseconds to delay.
19659     * @param {Object} [options={}] The options object.
19660     * @param {boolean} [options.leading=false]
19661     *  Specify invoking on the leading edge of the timeout.
19662     * @param {number} [options.maxWait]
19663     *  The maximum time `func` is allowed to be delayed before it's invoked.
19664     * @param {boolean} [options.trailing=true]
19665     *  Specify invoking on the trailing edge of the timeout.
19666     * @returns {Function} Returns the new debounced function.
19667     * @example
19668     *
19669     * // Avoid costly calculations while the window size is in flux.
19670     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
19671     *
19672     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
19673     * jQuery(element).on('click', _.debounce(sendMail, 300, {
19674     *   'leading': true,
19675     *   'trailing': false
19676     * }));
19677     *
19678     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
19679     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
19680     * var source = new EventSource('/stream');
19681     * jQuery(source).on('message', debounced);
19682     *
19683     * // Cancel the trailing debounced invocation.
19684     * jQuery(window).on('popstate', debounced.cancel);
19685     */
19686    function debounce(func, wait, options) {
19687      var lastArgs,
19688          lastThis,
19689          result,
19690          timerId,
19691          lastCallTime = 0,
19692          lastInvokeTime = 0,
19693          leading = false,
19694          maxWait = false,
19695          trailing = true;
19696
19697      if (typeof func != 'function') {
19698        throw new TypeError(FUNC_ERROR_TEXT);
19699      }
19700      wait = toNumber(wait) || 0;
19701      if (isObject(options)) {
19702        leading = !!options.leading;
19703        maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
19704        trailing = 'trailing' in options ? !!options.trailing : trailing;
19705      }
19706
19707      function invokeFunc(time) {
19708        var args = lastArgs,
19709            thisArg = lastThis;
19710
19711        lastArgs = lastThis = undefined;
19712        lastInvokeTime = time;
19713        result = func.apply(thisArg, args);
19714        return result;
19715      }
19716
19717      function leadingEdge(time) {
19718        // Reset any `maxWait` timer.
19719        lastInvokeTime = time;
19720        // Start the timer for the trailing edge.
19721        timerId = setTimeout(timerExpired, wait);
19722        // Invoke the leading edge.
19723        return leading ? invokeFunc(time) : result;
19724      }
19725
19726      function remainingWait(time) {
19727        var timeSinceLastCall = time - lastCallTime,
19728            timeSinceLastInvoke = time - lastInvokeTime,
19729            result = wait - timeSinceLastCall;
19730
19731        return maxWait === false ? result : nativeMin(result, maxWait - timeSinceLastInvoke);
19732      }
19733
19734      function shouldInvoke(time) {
19735        var timeSinceLastCall = time - lastCallTime,
19736            timeSinceLastInvoke = time - lastInvokeTime;
19737
19738        // Either this is the first call, activity has stopped and we're at the
19739        // trailing edge, the system time has gone backwards and we're treating
19740        // it as the trailing edge, or we've hit the `maxWait` limit.
19741        return (!lastCallTime || (timeSinceLastCall >= wait) ||
19742          (timeSinceLastCall < 0) || (maxWait !== false && timeSinceLastInvoke >= maxWait));
19743      }
19744
19745      function timerExpired() {
19746        var time = now();
19747        if (shouldInvoke(time)) {
19748          return trailingEdge(time);
19749        }
19750        // Restart the timer.
19751        timerId = setTimeout(timerExpired, remainingWait(time));
19752      }
19753
19754      function trailingEdge(time) {
19755        clearTimeout(timerId);
19756        timerId = undefined;
19757
19758        // Only invoke if we have `lastArgs` which means `func` has been
19759        // debounced at least once.
19760        if (trailing && lastArgs) {
19761          return invokeFunc(time);
19762        }
19763        lastArgs = lastThis = undefined;
19764        return result;
19765      }
19766
19767      function cancel() {
19768        if (timerId !== undefined) {
19769          clearTimeout(timerId);
19770        }
19771        lastCallTime = lastInvokeTime = 0;
19772        lastArgs = lastThis = timerId = undefined;
19773      }
19774
19775      function flush() {
19776        return timerId === undefined ? result : trailingEdge(now());
19777      }
19778
19779      function debounced() {
19780        var time = now(),
19781            isInvoking = shouldInvoke(time);
19782
19783        lastArgs = arguments;
19784        lastThis = this;
19785        lastCallTime = time;
19786
19787        if (isInvoking) {
19788          if (timerId === undefined) {
19789            return leadingEdge(lastCallTime);
19790          }
19791          // Handle invocations in a tight loop.
19792          clearTimeout(timerId);
19793          timerId = setTimeout(timerExpired, wait);
19794          return invokeFunc(lastCallTime);
19795        }
19796        return result;
19797      }
19798      debounced.cancel = cancel;
19799      debounced.flush = flush;
19800      return debounced;
19801    }
19802
19803    /**
19804     * Defers invoking the `func` until the current call stack has cleared. Any
19805     * additional arguments are provided to `func` when it's invoked.
19806     *
19807     * @static
19808     * @memberOf _
19809     * @since 0.1.0
19810     * @category Function
19811     * @param {Function} func The function to defer.
19812     * @param {...*} [args] The arguments to invoke `func` with.
19813     * @returns {number} Returns the timer id.
19814     * @example
19815     *
19816     * _.defer(function(text) {
19817     *   console.log(text);
19818     * }, 'deferred');
19819     * // => Logs 'deferred' after one or more milliseconds.
19820     */
19821    var defer = rest(function(func, args) {
19822      return baseDelay(func, 1, args);
19823    });
19824
19825    /**
19826     * Invokes `func` after `wait` milliseconds. Any additional arguments are
19827     * provided to `func` when it's invoked.
19828     *
19829     * @static
19830     * @memberOf _
19831     * @since 0.1.0
19832     * @category Function
19833     * @param {Function} func The function to delay.
19834     * @param {number} wait The number of milliseconds to delay invocation.
19835     * @param {...*} [args] The arguments to invoke `func` with.
19836     * @returns {number} Returns the timer id.
19837     * @example
19838     *
19839     * _.delay(function(text) {
19840     *   console.log(text);
19841     * }, 1000, 'later');
19842     * // => Logs 'later' after one second.
19843     */
vendor: 9,661 bytes, lines 19844-20139
19844    var delay = rest(function(func, wait, args) {
19845      return baseDelay(func, toNumber(wait) || 0, args);
19846    });
19847
19848    /**
19849     * Creates a function that invokes `func` with arguments reversed.
19850     *
19851     * @static
19852     * @memberOf _
19853     * @since 4.0.0
19854     * @category Function
19855     * @param {Function} func The function to flip arguments for.
19856     * @returns {Function} Returns the new function.
19857     * @example
19858     *
19859     * var flipped = _.flip(function() {
19860     *   return _.toArray(arguments);
19861     * });
19862     *
19863     * flipped('a', 'b', 'c', 'd');
19864     * // => ['d', 'c', 'b', 'a']
19865     */
19866    function flip(func) {
19867      return createWrapper(func, FLIP_FLAG);
19868    }
19869
19870    /**
19871     * Creates a function that memoizes the result of `func`. If `resolver` is
19872     * provided, it determines the cache key for storing the result based on the
19873     * arguments provided to the memoized function. By default, the first argument
19874     * provided to the memoized function is used as the map cache key. The `func`
19875     * is invoked with the `this` binding of the memoized function.
19876     *
19877     * **Note:** The cache is exposed as the `cache` property on the memoized
19878     * function. Its creation may be customized by replacing the `_.memoize.Cache`
19879     * constructor with one whose instances implement the
19880     * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
19881     * method interface of `delete`, `get`, `has`, and `set`.
19882     *
19883     * @static
19884     * @memberOf _
19885     * @since 0.1.0
19886     * @category Function
19887     * @param {Function} func The function to have its output memoized.
19888     * @param {Function} [resolver] The function to resolve the cache key.
19889     * @returns {Function} Returns the new memoizing function.
19890     * @example
19891     *
19892     * var object = { 'a': 1, 'b': 2 };
19893     * var other = { 'c': 3, 'd': 4 };
19894     *
19895     * var values = _.memoize(_.values);
19896     * values(object);
19897     * // => [1, 2]
19898     *
19899     * values(other);
19900     * // => [3, 4]
19901     *
19902     * object.a = 2;
19903     * values(object);
19904     * // => [1, 2]
19905     *
19906     * // Modify the result cache.
19907     * values.cache.set(object, ['a', 'b']);
19908     * values(object);
19909     * // => ['a', 'b']
19910     *
19911     * // Replace `_.memoize.Cache`.
19912     * _.memoize.Cache = WeakMap;
19913     */
19914    function memoize(func, resolver) {
19915      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
19916        throw new TypeError(FUNC_ERROR_TEXT);
19917      }
19918      var memoized = function() {
19919        var args = arguments,
19920            key = resolver ? resolver.apply(this, args) : args[0],
19921            cache = memoized.cache;
19922
19923        if (cache.has(key)) {
19924          return cache.get(key);
19925        }
19926        var result = func.apply(this, args);
19927        memoized.cache = cache.set(key, result);
19928        return result;
19929      };
19930      memoized.cache = new (memoize.Cache || MapCache);
19931      return memoized;
19932    }
19933
19934    // Assign cache to `_.memoize`.
19935    memoize.Cache = MapCache;
19936
19937    /**
19938     * Creates a function that negates the result of the predicate `func`. The
19939     * `func` predicate is invoked with the `this` binding and arguments of the
19940     * created function.
19941     *
19942     * @static
19943     * @memberOf _
19944     * @since 3.0.0
19945     * @category Function
19946     * @param {Function} predicate The predicate to negate.
19947     * @returns {Function} Returns the new function.
19948     * @example
19949     *
19950     * function isEven(n) {
19951     *   return n % 2 == 0;
19952     * }
19953     *
19954     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
19955     * // => [1, 3, 5]
19956     */
19957    function negate(predicate) {
19958      if (typeof predicate != 'function') {
19959        throw new TypeError(FUNC_ERROR_TEXT);
19960      }
19961      return function() {
19962        return !predicate.apply(this, arguments);
19963      };
19964    }
19965
19966    /**
19967     * Creates a function that is restricted to invoking `func` once. Repeat calls
19968     * to the function return the value of the first invocation. The `func` is
19969     * invoked with the `this` binding and arguments of the created function.
19970     *
19971     * @static
19972     * @memberOf _
19973     * @since 0.1.0
19974     * @category Function
19975     * @param {Function} func The function to restrict.
19976     * @returns {Function} Returns the new restricted function.
19977     * @example
19978     *
19979     * var initialize = _.once(createApplication);
19980     * initialize();
19981     * initialize();
19982     * // `initialize` invokes `createApplication` once
19983     */
19984    function once(func) {
19985      return before(2, func);
19986    }
19987
19988    /**
19989     * Creates a function that invokes `func` with arguments transformed by
19990     * corresponding `transforms`.
19991     *
19992     * @static
19993     * @since 4.0.0
19994     * @memberOf _
19995     * @category Function
19996     * @param {Function} func The function to wrap.
19997     * @param {...(Function|Function[])} [transforms] The functions to transform.
19998     * arguments, specified individually or in arrays.
19999     * @returns {Function} Returns the new function.
20000     * @example
20001     *
20002     * function doubled(n) {
20003     *   return n * 2;
20004     * }
20005     *
20006     * function square(n) {
20007     *   return n * n;
20008     * }
20009     *
20010     * var func = _.overArgs(function(x, y) {
20011     *   return [x, y];
20012     * }, square, doubled);
20013     *
20014     * func(9, 3);
20015     * // => [81, 6]
20016     *
20017     * func(10, 5);
20018     * // => [100, 10]
20019     */
20020    var overArgs = rest(function(func, transforms) {
20021      transforms = arrayMap(baseFlatten(transforms, 1, isFlattenableIteratee), getIteratee());
20022      var funcsLength = transforms.length;
20023      return rest(function(args) {
20024        var index = -1,
20025            length = nativeMin(args.length, funcsLength);
20026
20027        while (++index < length) {
20028          args[index] = transforms[index].call(this, args[index]);
20029        }
20030        return apply(func, this, args);
20031      });
20032    });
20033
20034    /**
20035     * Creates a function that invokes `func` with `partials` prepended to the
20036     * arguments it receives. This method is like `_.bind` except it does **not**
20037     * alter the `this` binding.
20038     *
20039     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
20040     * builds, may be used as a placeholder for partially applied arguments.
20041     *
20042     * **Note:** This method doesn't set the "length" property of partially
20043     * applied functions.
20044     *
20045     * @static
20046     * @memberOf _
20047     * @since 0.2.0
20048     * @category Function
20049     * @param {Function} func The function to partially apply arguments to.
20050     * @param {...*} [partials] The arguments to be partially applied.
20051     * @returns {Function} Returns the new partially applied function.
20052     * @example
20053     *
20054     * var greet = function(greeting, name) {
20055     *   return greeting + ' ' + name;
20056     * };
20057     *
20058     * var sayHelloTo = _.partial(greet, 'hello');
20059     * sayHelloTo('fred');
20060     * // => 'hello fred'
20061     *
20062     * // Partially applied with placeholders.
20063     * var greetFred = _.partial(greet, _, 'fred');
20064     * greetFred('hi');
20065     * // => 'hi fred'
20066     */
20067    var partial = rest(function(func, partials) {
20068      var holders = replaceHolders(partials, getPlaceholder(partial));
20069      return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
20070    });
20071
20072    /**
20073     * This method is like `_.partial` except that partially applied arguments
20074     * are appended to the arguments it receives.
20075     *
20076     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
20077     * builds, may be used as a placeholder for partially applied arguments.
20078     *
20079     * **Note:** This method doesn't set the "length" property of partially
20080     * applied functions.
20081     *
20082     * @static
20083     * @memberOf _
20084     * @since 1.0.0
20085     * @category Function
20086     * @param {Function} func The function to partially apply arguments to.
20087     * @param {...*} [partials] The arguments to be partially applied.
20088     * @returns {Function} Returns the new partially applied function.
20089     * @example
20090     *
20091     * var greet = function(greeting, name) {
20092     *   return greeting + ' ' + name;
20093     * };
20094     *
20095     * var greetFred = _.partialRight(greet, 'fred');
20096     * greetFred('hi');
20097     * // => 'hi fred'
20098     *
20099     * // Partially applied with placeholders.
20100     * var sayHelloTo = _.partialRight(greet, 'hello', _);
20101     * sayHelloTo('fred');
20102     * // => 'hello fred'
20103     */
20104    var partialRight = rest(function(func, partials) {
20105      var holders = replaceHolders(partials, getPlaceholder(partialRight));
20106      return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
20107    });
20108
20109    /**
20110     * Creates a function that invokes `func` with arguments arranged according
20111     * to the specified `indexes` where the argument value at the first index is
20112     * provided as the first argument, the argument value at the second index is
20113     * provided as the second argument, and so on.
20114     *
20115     * @static
20116     * @memberOf _
20117     * @since 3.0.0
20118     * @category Function
20119     * @param {Function} func The function to rearrange arguments for.
20120     * @param {...(number|number[])} indexes The arranged argument indexes,
20121     *  specified individually or in arrays.
20122     * @returns {Function} Returns the new function.
20123     * @example
20124     *
20125     * var rearged = _.rearg(function(a, b, c) {
20126     *   return [a, b, c];
20127     * }, 2, 0, 1);
20128     *
20129     * rearged('b', 'c', 'a')
20130     * // => ['a', 'b', 'c']
20131     */
20132    var rearg = rest(function(func, indexes) {
20133      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
20134    });
20135
20136    /**
20137     * Creates a function that invokes `func` with the `this` binding of the
20138     * created function and arguments from `start` and beyond provided as
20139     * an array.
20140     *
20141     * **Note:** This method is based on the
20142     * [rest parameter](https://mdn.io/rest_parameters).
20143     *
20144     * @static
20145     * @memberOf _
20146     * @since 4.0.0
20147     * @category Function
20148     * @param {Function} func The function to apply a rest parameter to.
20149     * @param {number} [start=func.length-1] The start position of the rest parameter.
20150     * @returns {Function} Returns the new function.
20151     * @example
20152     *
20153     * var say = _.rest(function(what, names) {
20154     *   return what + ' ' + _.initial(names).join(', ') +
20155     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
20156     * });
20157     *
20158     * say('hello', 'fred', 'barney', 'pebbles');
20159     * // => 'hello fred, barney, & pebbles'
20160     */
20161    function rest(func, start) {
20162      if (typeof func != 'function') {
20163        throw new TypeError(FUNC_ERROR_TEXT);
20164      }
20165      start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
20166      return function() {
20167        var args = arguments,
20168            index = -1,
20169            length = nativeMax(args.length - start, 0),
20170            array = Array(length);
20171
20172        while (++index < length) {
20173          array[index] = args[start + index];
20174        }
20175        switch (start) {
20176          case 0: return func.call(this, array);
20177          case 1: return func.call(this, args[0], array);
20178          case 2: return func.call(this, args[0], args[1], array);
20179        }
20180        var otherArgs = Array(start + 1);
20181        index = -1;
20182        while (++index < start) {
20183          otherArgs[index] = args[index];
20184        }
20185        otherArgs[start] = array;
20186        return apply(func, this, otherArgs);
20187      };
20188    }
20189
20190    /**
20191     * Creates a function that invokes `func` with the `this` binding of the
20192     * create function and an array of arguments much like
20193     * [`Function#apply`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply).
20194     *
20195     * **Note:** This method is based on the
20196     * [spread operator](https://mdn.io/spread_operator).
20197     *
20198     * @static
20199     * @memberOf _
20200     * @since 3.2.0
20201     * @category Function
20202     * @param {Function} func The function to spread arguments over.
20203     * @param {number} [start=0] The start position of the spread.
20204     * @returns {Function} Returns the new function.
20205     * @example
20206     *
20207     * var say = _.spread(function(who, what) {
20208     *   return who + ' says ' + what;
20209     * });
20210     *
20211     * say(['fred', 'hello']);
20212     * // => 'fred says hello'
20213     *
20214     * var numbers = Promise.all([
20215     *   Promise.resolve(40),
20216     *   Promise.resolve(36)
20217     * ]);
20218     *
20219     * numbers.then(_.spread(function(x, y) {
20220     *   return x + y;
20221     * }));
20222     * // => a Promise of 76
20223     */
20224    function spread(func, start) {
20225      if (typeof func != 'function') {
20226        throw new TypeError(FUNC_ERROR_TEXT);
20227      }
20228      start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
20229      return rest(function(args) {
20230        var array = args[start],
20231            otherArgs = args.slice(0, start);
20232
20233        if (array) {
20234          arrayPush(otherArgs, array);
20235        }
20236        return apply(func, this, otherArgs);
20237      });
20238    }
20239
20240    /**
20241     * Creates a throttled function that only invokes `func` at most once per
20242     * every `wait` milliseconds. The throttled function comes with a `cancel`
20243     * method to cancel delayed `func` invocations and a `flush` method to
20244     * immediately invoke them. Provide an options object to indicate whether
20245     * `func` should be invoked on the leading and/or trailing edge of the `wait`
20246     * timeout. The `func` is invoked with the last arguments provided to the
20247     * throttled function. Subsequent calls to the throttled function return the
20248     * result of the last `func` invocation.
20249     *
20250     * **Note:** If `leading` and `trailing` options are `true`, `func` is
20251     * invoked on the trailing edge of the timeout only if the throttled function
20252     * is invoked more than once during the `wait` timeout.
20253     *
20254     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
20255     * for details over the differences between `_.throttle` and `_.debounce`.
20256     *
20257     * @static
20258     * @memberOf _
20259     * @since 0.1.0
20260     * @category Function
20261     * @param {Function} func The function to throttle.
20262     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
20263     * @param {Object} [options={}] The options object.
20264     * @param {boolean} [options.leading=true]
20265     *  Specify invoking on the leading edge of the timeout.
20266     * @param {boolean} [options.trailing=true]
20267     *  Specify invoking on the trailing edge of the timeout.
20268     * @returns {Function} Returns the new throttled function.
20269     * @example
20270     *
20271     * // Avoid excessively updating the position while scrolling.
20272     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
20273     *
20274     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
20275     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
20276     * jQuery(element).on('click', throttled);
20277     *
20278     * // Cancel the trailing throttled invocation.
20279     * jQuery(window).on('popstate', throttled.cancel);
20280     */
20281    function throttle(func, wait, options) {
20282      var leading = true,
20283          trailing = true;
20284
20285      if (typeof func != 'function') {
20286        throw new TypeError(FUNC_ERROR_TEXT);
20287      }
20288      if (isObject(options)) {
20289        leading = 'leading' in options ? !!options.leading : leading;
20290        trailing = 'trailing' in options ? !!options.trailing : trailing;
20291      }
20292      return debounce(func, wait, {
20293        'leading': leading,
20294        'maxWait': wait,
20295        'trailing': trailing
20296      });
20297    }
20298
20299    /**
20300     * Creates a function that accepts up to one argument, ignoring any
20301     * additional arguments.
20302     *
20303     * @static
20304     * @memberOf _
20305     * @since 4.0.0
20306     * @category Function
20307     * @param {Function} func The function to cap arguments for.
20308     * @returns {Function} Returns the new function.
20309     * @example
20310     *
20311     * _.map(['6', '8', '10'], _.unary(parseInt));
20312     * // => [6, 8, 10]
20313     */
20314    function unary(func) {
20315      return ary(func, 1);
20316    }
20317
20318    /**
20319     * Creates a function that provides `value` to the wrapper function as its
20320     * first argument. Any additional arguments provided to the function are
20321     * appended to those provided to the wrapper function. The wrapper is invoked
20322     * with the `this` binding of the created function.
20323     *
20324     * @static
20325     * @memberOf _
20326     * @since 0.1.0
20327     * @category Function
20328     * @param {*} value The value to wrap.
20329     * @param {Function} [wrapper=identity] The wrapper function.
20330     * @returns {Function} Returns the new function.
20331     * @example
20332     *
20333     * var p = _.wrap(_.escape, function(func, text) {
20334     *   return '<p>' + func(text) + '</p>';
20335     * });
20336     *
20337     * p('fred, barney, & pebbles');
20338     * // => '<p>fred, barney, &amp; pebbles</p>'
20339     */
20340    function wrap(value, wrapper) {
20341      wrapper = wrapper == null ? identity : wrapper;
20342      return partial(wrapper, value);
20343    }
20344
20345    /*------------------------------------------------------------------------*/
20346
20347    /**
20348     * Casts `value` as an array if it's not one.
20349     *
20350     * @static
20351     * @memberOf _
20352     * @since 4.4.0
20353     * @category Lang
20354     * @param {*} value The value to inspect.
20355     * @returns {Array} Returns the cast array.
20356     * @example
20357     *
20358     * _.castArray(1);
20359     * // => [1]
20360     *
20361     * _.castArray({ 'a': 1 });
20362     * // => [{ 'a': 1 }]
20363     *
20364     * _.castArray('abc');
20365     * // => ['abc']
20366     *
20367     * _.castArray(null);
20368     * // => [null]
20369     *
20370     * _.castArray(undefined);
20371     * // => [undefined]
20372     *
20373     * _.castArray();
20374     * // => []
20375     *
20376     * var array = [1, 2, 3];
20377     * console.log(_.castArray(array) === array);
20378     * // => true
20379     */
20380    function castArray() {
20381      if (!arguments.length) {
20382        return [];
20383      }
20384      var value = arguments[0];
20385      return isArray(value) ? value : [value];
20386    }
20387
20388    /**
20389     * Creates a shallow clone of `value`.
20390     *
20391     * **Note:** This method is loosely based on the
20392     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
20393     * and supports cloning arrays, array buffers, booleans, date objects, maps,
20394     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
20395     * arrays. The own enumerable properties of `arguments` objects are cloned
20396     * as plain objects. An empty object is returned for uncloneable values such
20397     * as error objects, functions, DOM nodes, and WeakMaps.
20398     *
20399     * @static
20400     * @memberOf _
20401     * @since 0.1.0
20402     * @category Lang
20403     * @param {*} value The value to clone.
20404     * @returns {*} Returns the cloned value.
20405     * @example
20406     *
20407     * var objects = [{ 'a': 1 }, { 'b': 2 }];
20408     *
20409     * var shallow = _.clone(objects);
20410     * console.log(shallow[0] === objects[0]);
20411     * // => true
20412     */
20413    function clone(value) {
20414      return baseClone(value, false, true);
20415    }
20416
20417    /**
20418     * This method is like `_.clone` except that it accepts `customizer` which
20419     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
20420     * cloning is handled by the method instead. The `customizer` is invoked with
20421     * up to four arguments; (value [, index|key, object, stack]).
20422     *
20423     * @static
20424     * @memberOf _
20425     * @since 4.0.0
20426     * @category Lang
20427     * @param {*} value The value to clone.
20428     * @param {Function} [customizer] The function to customize cloning.
20429     * @returns {*} Returns the cloned value.
20430     * @example
20431     *
20432     * function customizer(value) {
20433     *   if (_.isElement(value)) {
20434     *     return value.cloneNode(false);
20435     *   }
20436     * }
20437     *
20438     * var el = _.cloneWith(document.body, customizer);
20439     *
20440     * console.log(el === document.body);
20441     * // => false
20442     * console.log(el.nodeName);
20443     * // => 'BODY'
20444     * console.log(el.childNodes.length);
20445     * // => 0
20446     */
20447    function cloneWith(value, customizer) {
20448      return baseClone(value, false, true, customizer);
20449    }
20450
20451    /**
20452     * This method is like `_.clone` except that it recursively clones `value`.
20453     *
20454     * @static
20455     * @memberOf _
20456     * @since 1.0.0
20457     * @category Lang
20458     * @param {*} value The value to recursively clone.
20459     * @returns {*} Returns the deep cloned value.
20460     * @example
20461     *
20462     * var objects = [{ 'a': 1 }, { 'b': 2 }];
20463     *
20464     * var deep = _.cloneDeep(objects);
20465     * console.log(deep[0] === objects[0]);
20466     * // => false
20467     */
20468    function cloneDeep(value) {
20469      return baseClone(value, true, true);
20470    }
20471
20472    /**
20473     * This method is like `_.cloneWith` except that it recursively clones `value`.
20474     *
20475     * @static
20476     * @memberOf _
20477     * @since 4.0.0
20478     * @category Lang
20479     * @param {*}
20479 value The value to recursively clone.
20480     * @param {Function} [customizer] The function to customize cloning.
20481     * @returns {*} Returns the deep cloned value.
20482     * @example
20483     *
20484     * function customizer(value) {
20485     *   if (_.isElement(value)) {
20486     *     return value.cloneNode(true);
20487     *   }
20488     * }
20489     *
20490     * var el = _.cloneDeepWith(document.body, customizer);
20491     *
20492     * console.log(el === document.body);
20493     * // => false
20494     * console.log(el.nodeName);
20495     * // => 'BODY'
20496     * console.log(el.childNodes.length);
20497     * // => 20
20498     */
20499    function cloneDeepWith(value, customizer) {
20500      return baseClone(value, true, true, customizer);
20501    }
20502
20503    /**
20504     * Performs a
20505     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
20506     * comparison between two values to determine if they are equivalent.
20507     *
20508     * @static
20509     * @memberOf _
20510     * @since 4.0.0
20511     * @category Lang
20512     * @param {*} value The value to compare.
20513     * @param {*} other The other value to compare.
20514     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
20515     * @example
20516     *
20517     * var object = { 'user': 'fred' };
20518     * var other = { 'user': 'fred' };
20519     *
20520     * _.eq(object, object);
20521     * // => true
20522     *
20523     * _.eq(object, other);
20524     * // => false
20525     *
20526     * _.eq('a', 'a');
20527     * // => true
20528     *
20529     * _.eq('a', Object('a'));
20530     * // => false
20531     *
20532     * _.eq(NaN, NaN);
20533     * // => true
20534     */
20535    function eq(value, other) {
20536      return value === other || (value !== value && other !== other);
20537    }
20538
20539    /**
20540     * Checks if `value` is greater than `other`.
20541     *
20542     * @static
20543     * @memberOf _
20544     * @since 3.9.0
20545     * @category Lang
20546     * @param {*} value The value to compare.
20547     * @param {*} other The other value to compare.
20548     * @returns {boolean} Returns `true` if `value` is greater than `other`,
20549     *  else `false`.
20550     * @example
20551     *
20552     * _.gt(3, 1);
20553     * // => true
20554     *
20555     * _.gt(3, 3);
20556     * // => false
20557     *
20558     * _.gt(1, 3);
20559     * // => false
20560     */
20561    function gt(value, other) {
20562      return value > other;
20563    }
20564
20565    /**
20566     * Checks if `value` is greater than or equal to `other`.
20567     *
20568     * @static
20569     * @memberOf _
20570     * @since 3.9.0
20571     * @category Lang
20572     * @param {*} value The value to compare.
20573     * @param {*} other The other value to compare.
20574     * @returns {boolean} Returns `true` if `value` is greater than or equal to
20575     *  `other`, else `false`.
20576     * @example
20577     *
20578     * _.gte(3, 1);
20579     * // => true
20580     *
20581     * _.gte(3, 3);
20582     * // => true
20583     *
20584     * _.gte(1, 3);
20585     * // => false
20586     */
20587    function gte(value, other) {
20588      return value >= other;
20589    }
20590
20591    /**
20592     * Checks if `value` is likely an `arguments` object.
20593     *
20594     * @static
20595     * @memberOf _
20596     * @since 0.1.0
20597     * @category Lang
20598     * @param {*} value The value to check.
20599     * @returns {boolean} Returns `true` if `value` is correctly classified,
20600     *  else `false`.
20601     * @example
20602     *
20603     * _.isArguments(function() { return arguments; }());
20604     * // => true
20605     *
20606     * _.isArguments([1, 2, 3]);
20607     * // => false
20608     */
20609    function isArguments(value) {
20610      // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
20611      return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
20612        (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
20613    }
20614
20615    /**
20616     * Checks if `value` is classified as an `Array` object.
20617     *
20618     * @static
20619     * @memberOf _
20620     * @since 0.1.0
20621     * @type {Function}
20622     * @category Lang
20623     * @param {*} value The value to check.
20624     * @returns {boolean} Returns `true` if `value` is correctly classified,
20625     *  else `false`.
20626     * @example
20627     *
20628     * _.isArray([1, 2, 3]);
20629     * // => true
20630     *
20631     * _.isArray(document.body.children);
20632     * // => false
20633     *
20634     * _.isArray('abc');
20635     * // => false
20636     *
20637     * _.isArray(_.noop);
20638     * // => false
20639     */
20640    var isArray = Array.isArray;
20641
20642    /**
20643     * Checks if `value` is classified as an `ArrayBuffer` object.
20644     *
20645     * @static
20646     * @memberOf _
20647     * @since 4.3.0
20648     * @category Lang
20649     * @param {*} value The value to check.
20650     * @returns {boolean} Returns `true` if `value` is correctly classified,
20651     *  else `false`.
20652     * @example
20653     *
20654     * _.isArrayBuffer(new ArrayBuffer(2));
20655     * // => true
20656     *
20657     * _.isArrayBuffer(new Array(2));
20658     * // => false
20659     */
20660    function isArrayBuffer(value) {
20661      return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
20662    }
20663
20664    /**
20665     * Checks if `value` is array-like. A value is considered array-like if it's
20666     * not a function and has a `value.length` that's an integer greater than or
20667     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
20668     *
20669     * @static
20670     * @memberOf _
20671     * @since 4.0.0
20672     * @category Lang
20673     * @param {*} value The value to check.
20674     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
20675     * @example
20676     *
20677     * _.isArrayLike([1, 2, 3]);
20678     * // => true
20679     *
20680     * _.isArrayLike(document.body.children);
20681     * // => true
20682     *
20683     * _.isArrayLike('abc');
20684     * // => true
20685     *
20686     * _.isArrayLike(_.noop);
20687     * // => false
20688     */
20689    function isArrayLike(value) {
20690      return value != null && isLength(getLength(value)) && !isFunction(value);
20691    }
20692
20693    /**
20694     * This method is like `_.isArrayLike` except that it also checks if `value`
20695     * is an object.
20696     *
20697     * @static
20698     * @memberOf _
20699     * @since 4.0.0
20700     * @category Lang
20701     * @param {*} value The value to check.
20702     * @returns {boolean} Returns `true` if `value` is an array-like object,
20703     *  else `false`.
20704     * @example
20705     *
20706     * _.isArrayLikeObject([1, 2, 3]);
20707     * // => true
20708     *
20709     * _.isArrayLikeObject(document.body.children);
20710     * // => true
20711     *
20712     * _.isArrayLikeObject('abc');
20713     * // => false
20714     *
20715     * _.isArrayLikeObject(_.noop);
20716     * // => false
20717     */
20718    function isArrayLikeObject(value) {
20719      return isObjectLike(value) && isArrayLike(value);
20720    }
20721
20722    /**
20723     * Checks if `value` is classified as a boolean primitive or object.
20724     *
20725     * @static
20726     * @memberOf _
20727     * @since 0.1.0
20728     * @category Lang
20729     * @param {*} value The value to check.
20730     * @returns {boolean} Returns `true` if `value` is correctly classified,
20731     *  else `false`.
20732     * @example
20733     *
20734     * _.isBoolean(false);
20735     * // => true
20736     *
20737     * _.isBoolean(null);
20738     * // => false
20739     */
20740    function isBoolean(value) {
20741      return value === true || value === false ||
20742        (isObjectLike(value) && objectToString.call(value) == boolTag);
20743    }
20744
20745    /**
20746     * Checks if `value` is a buffer.
20747     *
20748     * @static
20749     * @memberOf _
20750     * @since 4.3.0
20751     * @category Lang
20752     * @param {*} value The value to check.
20753     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
20754     * @example
20755     *
20756     * _.isBuffer(new Buffer(2));
20757     * // => true
20758     *
20759     * _.isBuffer(new Uint8Array(2));
20760     * // => false
20761     */
20762    var isBuffer = !Buffer ? constant(false) : function(value) {
20763      return value instanceof Buffer;
20764    };
20765
20766    /**
20767     * Checks if `value` is classified as a `Date` object.
20768     *
20769     * @static
20770     * @memberOf _
20771     * @since 0.1.0
20772     * @category Lang
20773     * @param {*} value The value to check.
20774     * @returns {boolean} Returns `true` if `value` is correctly classified,
20775     *  else `false`.
20776     * @example
20777     *
20778     * _.isDate(new Date);
20779     * // => true
20780     *
20781     * _.isDate('Mon April 23 2012');
20782     * // => false
20783     */
20784    function isDate(value) {
20785      return isObjectLike(value) && objectToString.call(value) == dateTag;
20786    }
20787
20788    /**
20789     * Checks if `value` is likely a DOM element.
20790     *
20791     * @static
20792     * @memberOf _
20793     * @since 0.1.0
20794     * @category Lang
20795     * @param {*} value The value to check.
20796     * @returns {boolean} Returns `true` if `value` is a DOM element,
20797     *  else `false`.
20798     * @example
20799     *
20800     * _.isElement(document.body);
20801     * // => true
20802     *
20803     * _.isElement('<body>');
20804     * // => false
20805     */
20806    function isElement(value) {
20807      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
20808    }
20809
20810    /**
20811     * Checks if `value` is an empty object, collection, map, or set.
20812     *
20813     * Objects are considered empty if they have no own enumerable str
20813ing keyed
20814     * properties.
20815     *
20816     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
20817     * jQuery-like collections are considered empty if they have a `length` of `0`.
20818     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
20819     *
20820     * @static
20821     * @memberOf _
20822     * @since 0.1.0
20823     * @category Lang
20824     * @param {*} value The value to check.
20825     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
20826     * @example
20827     *
20828     * _.isEmpty(null);
20829     * // => true
20830     *
20831     * _.isEmpty(true);
20832     * // => true
20833     *
20834     * _.isEmpty(1);
20835     * // => true
20836     *
20837     * _.isEmpty([1, 2, 3]);
20838     * // => false
20839     *
20840     * _.isEmpty({ 'a': 1 });
20841     * // => false
20842     */
20843    function isEmpty(value) {
20844      if (isArrayLike(value) &&
20845          (isArray(value) || isString(value) || isFunction(value.splice) ||
20846            isArguments(value) || isBuffer(value))) {
20847        return !value.length;
20848      }
20849      if (isObjectLike(value)) {
20850        var tag = getTag(value);
20851        if (tag == mapTag || tag == setTag) {
20852          return !value.size;
20853        }
20854      }
20855      for (var key in value) {
20856        if (hasOwnProperty.call(value, key)) {
20857          return false;
20858        }
20859      }
20860      return !(nonEnumShadows && keys(value).length);
20861    }
20862
20863    /**
20864     * Performs a deep comparison between two values to determine if they are
20865     * equivalent.
20866     *
20867     * **Note:** This method supports comparing arrays, array buffers, booleans,
20868     * date objects, error objects, maps, numbers, `Object` objects, regexes,
20869     * sets, strings, symbols, and typed arrays. `Object` objects are compared
20870     * by their own, not inherited, enumerable properties. Functions and DOM
20871     * nodes are **not** supported.
20872     *
20873     * @static
20874     * @memberOf _
20875     * @since 0.1.0
20876     * @category Lang
20877     * @param {*} value The value to compare.
20878     * @param {*} other The other value to compare.
20879     * @returns {boolean} Returns `true` if the values are equivalent,
20880     *  else `false`.
20881     * @example
20882     *
20883     * var object = { 'user': 'fred' };
20884     * var other = { 'user': 'fred' };
20885     *
20886     * _.isEqual(object, other);
20887     * // => true
20888     *
20889     * object === other;
20890     * // => false
20891     */
20892    function isEqual(value, other) {
20893      return baseIsEqual(value, other);
20894    }
20895
20896    /**
20897     * This method is like `_.isEqual` except that it accepts `customizer` which
20898     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
20899     * are handled by the method instead. The `customizer` is invoked with up to
20900     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
20901     *
20902     * @static
20903     * @memberOf _
20904     * @since 4.0.0
20905     * @category Lang
20906     * @param {*} value The value to compare.
20907     * @param {*} other The other value to compare.
20908     * @param {Function} [customizer] The function to customize comparisons.
20909     * @returns {boolean} Returns `true` if the values are equivalent,
20910     *  else `false`.
20911     * @example
20912     *
20913     * function isGreeting(value) {
20914     *   return /^h(?:i|ello)$/.test(value);
20915     * }
20916     *
20917     * function customizer(objValue, othValue) {
20918     *   if (isGreeting(objValue) && isGreeting(othValue)) {
20919     *     return true;
20920     *   }
20921     * }
20922     *
20923     * var array = ['hello', 'goodbye'];
20924     * var other = ['hi', 'goodbye'];
20925     *
20926     * _.isEqualWith(array, other, customizer);
20927     * // => true
20928     */
20929    function isEqualWith(value, other, customizer) {
20930      customizer = typeof customizer == 'function' ? customizer : undefined;
20931      var result = customizer ? customizer(value, other) : undefined;
20932      return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
20933    }
20934
20935    /**
20936     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
20937     * `SyntaxError`, `TypeError`, or `URIError` object.
20938     *
20939     * @static
20940     * @memberOf _
20941     * @since 3.0.0
20942     * @category Lang
20943     * @param {*} value The value to check.
20944     * @returns {boolean} Returns `true` if `value` is an error object,
20945     *  else `false`.
20946     * @example
20947     *
20948     * _.isError(new Error);
20949     * // => true
20950     *
20951     * _.isError(Error);
20952     * // => false
20953     */
20954    function isError(value) {
20955      if (!isObjectLike(value)) {
20956        return false;
vendor: 6,525 bytes, lines 20957-21193
20957      }
20958      return (objectToString.call(value) == errorTag) ||
20959        (typeof value.message == 'string' && typeof value.name == 'string');
20960    }
20961
20962    /**
20963     * Checks if `value` is a finite primitive number.
20964     *
20965     * **Note:** This method is based on
20966     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
20967     *
20968     * @static
20969     * @memberOf _
20970     * @since 0.1.0
20971     * @category Lang
20972     * @param {*} value The value to check.
20973     * @returns {boolean} Returns `true` if `value` is a finite number,
20974     *  else `false`.
20975     * @example
20976     *
20977     * _.isFinite(3);
20978     * // => true
20979     *
20980     * _.isFinite(Number.MAX_VALUE);
20981     * // => true
20982     *
20983     * _.isFinite(3.14);
20984     * // => true
20985     *
20986     * _.isFinite(Infinity);
20987     * // => false
20988     */
20989    function isFinite(value) {
20990      return typeof value == 'number' && nativeIsFinite(value);
20991    }
20992
20993    /**
20994     * Checks if `value` is classified as a `Function` object.
20995     *
20996     * @static
20997     * @memberOf _
20998     * @since 0.1.0
20999     * @category Lang
21000     * @param {*} value The value to check.
21001     * @returns {boolean} Returns `true` if `value` is correctly classified,
21002     *  else `false`.
21003     * @example
21004     *
21005     * _.isFunction(_);
21006     * // => true
21007     *
21008     * _.isFunction(/abc/);
21009     * // => false
21010     */
21011    function isFunction(value) {
21012      // The use of `Object#toString` avoids issues with the `typeof` operator
21013      // in Safari 8 which returns 'object' for typed array and weak map constructors,
21014      // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
21015      var tag = isObject(value) ? objectToString.call(value) : '';
21016      return tag == funcTag || tag == genTag;
21017    }
21018
21019    /**
21020     * Checks if `value` is an integer.
21021     *
21022     * **Note:** This method is based on
21023     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
21024     *
21025     * @static
21026     * @memberOf _
21027     * @since 4.0.0
21028     * @category Lang
21029     * @param {*} value The value to check.
21030     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
21031     * @example
21032     *
21033     * _.isInteger(3);
21034     * // => true
21035     *
21036     * _.isInteger(Number.MIN_VALUE);
21037     * // => false
21038     *
21039     * _.isInteger(Infinity);
21040     * // => false
21041     *
21042     * _.isInteger('3');
21043     * // => false
21044     */
21045    function isInteger(value) {
21046      return typeof value == 'number' && value == toInteger(value);
21047    }
21048
21049    /**
21050     * Checks if `value` is a valid array-like length.
21051     *
21052     * **Note:** This function is loosely based on
21053     * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
21054     *
21055     * @static
21056     * @memberOf _
21057     * @since 4.0.0
21058     * @category Lang
21059     * @param {*} value The value to check.
21060     * @returns {boolean} Returns `true` if `value` is a valid length,
21061     *  else `false`.
21062     * @example
21063     *
21064     * _.isLength(3);
21065     * // => true
21066     *
21067     * _.isLength(Number.MIN_VALUE);
21068     * // => false
21069     *
21070     * _.isLength(Infinity);
21071     * // => false
21072     *
21073     * _.isLength('3');
21074     * // => false
21075     */
21076    function isLength(value) {
21077      return typeof value == 'number' &&
21078        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
21079    }
21080
21081    /**
21082     * Checks if `value` is the
21083     * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
21084     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
21085     *
21086     * @static
21087     * @memberOf _
21088     * @since 0.1.0
21089     * @category Lang
21090     * @param {*} value The value to check.
21091     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
21092     * @example
21093     *
21094     * _.isObject({});
21095     * // => true
21096     *
21097     * _.isObject([1, 2, 3]);
21098     * // => true
21099     *
21100     * _.isObject(_.noop);
21101     * // => true
21102     *
21103     * _.isObject(null);
21104     * // => false
21105     */
21106    function isObject(value) {
21107      var type = typeof value;
21108      return !!value && (type == 'object' || type == 'function');
21109    }
21110
21111    /**
21112     * Checks if `value` is object-like. A value is object-like if it's not `null`
21113     * and has a `typeof` result of "object".
21114     *
21115     * @static
21116     * @memberOf _
21117     * @since 4.0.0
21118     * @category Lang
21119     * @param {*} value The value to check.
21120     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
21121     * @example
21122     *
21123     * _.isObjectLike({});
21124     * // => true
21125     *
21126     * _.isObjectLike([1, 2, 3]);
21127     * // => true
21128     *
21129     * _.isObjectLike(_.noop);
21130     * // => false
21131     *
21132     * _.isObjectLike(null);
21133     * // => false
21134     */
21135    function isObjectLike(value) {
21136      return !!value && typeof value == 'object';
21137    }
21138
21139    /**
21140     * Checks if `value` is classified as a `Map` object.
21141     *
21142     * @static
21143     * @memberOf _
21144     * @since 4.3.0
21145     * @category Lang
21146     * @param {*} value The value to check.
21147     * @returns {boolean} Returns `true` if `value` is correctly classified,
21148     *  else `false`.
21149     * @example
21150     *
21151     * _.isMap(new Map);
21152     * // => true
21153     *
21154     * _.isMap(new WeakMap);
21155     * // => false
21156     */
21157    function isMap(value) {
21158      return isObjectLike(value) && getTag(value) == mapTag;
21159    }
21160
21161    /**
21162     * Performs a partial deep comparison between `object` and `source` to
21163     * determine if `object` contains equivalent property values. This method is
21164     * equivalent to a `_.matches` function when `source` is partially applied.
21165     *
21166     * **Note:** This method supports comparing the same values as `_.isEqual`.
21167     *
21168     * @static
21169     * @memberOf _
21170     * @since 3.0.0
21171     * @category Lang
21172     * @param {Object} object The object to inspect.
21173     * @param {Object} source The object of property values to match.
21174     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
21175     * @example
21176     *
21177     * var object = { 'user': 'fred', 'age': 40 };
21178     *
21179     * _.isMatch(object, { 'age': 40 });
21180     * // => true
21181     *
21182     * _.isMatch(object, { 'age': 36 });
21183     * // => false
21184     */
21185    function isMatch(object, source) {
21186      return object === source || baseIsMatch(object, source, getMatchData(source));
21187    }
21188
21189    /**
21190     * This method is like `_.isMatch` except that it accepts `customizer` which
21191     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
21192     * are handled by the method instead. The `customizer` is invoked with five
21193     * arguments: (objValue, srcValue, index|key, object, source).
21194     *
21195     * @static
21196     * @memberOf _
21197     * @since 4.0.0
21198     * @category Lang
21199     * @param {Object} object The object to inspect.
21200     * @param {Object} source The object of property values to match.
21201     * @param {Function} [customizer] The function to customize comparisons.
21202     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
21203     * @example
21204     *
21205     * function isGreeting(value) {
21206     *   return /^h(?:i|ello)$/.test(value);
21207     * }
21208     *
21209     * function customizer(objValue, srcValue) {
21210     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
21211     *     return true;
21212     *   }
21213     * }
21214     *
21215     * var object = { 'greeting': 'hello' };
21216     * var source = { 'greeting': 'hi' };
21217     *
21218     * _.isMatchWith(object, source, customizer);
21219     * // => true
21220     */
21221    function isMatchWith(object, source, customizer) {
21222      customizer = typeof customizer == 'function' ? customizer : undefined;
21223      return baseIsMatch(object, source, getMatchData(source), customizer);
21224    }
21225
21226    /**
21227     * Checks if `value` is `NaN`.
21228     *
21229     * **Note:** This method is based on
21230     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
21231     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
21232     * `undefined` and other non-number values.
21233     *
21234     * @static
21235     * @memberOf _
21236     * @since 0.1.0
21237     * @category Lang
21238     * @param {*} value The value to check.
21239     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
21240     * @example
21241     *
21242     * _.isNaN(NaN);
21243     * // => true
21244     *
21245     * _.isNaN(new Number(NaN));
21246     * // => true
21247     *
21248     * isNaN(undefined);
21249     * // => true
21250     *
21251     * _.isNaN(undefined);
21252     * // => false
21253     */
21254    function isNaN(value) {
21255      // An `NaN` primitive is the only value that is not equal to itself.
21256      // Perform the `toStringTag` check first to avoid errors with some
21257      // ActiveX objects in IE.
21258      return isNumber(value) && value != +value;
21259    }
21260
21261    /**
21262     * Checks if `value` is a native function.
21263     *
21264     * @static
21265     * @memberOf _
21266     * @since 3.0.0
21267     * @category Lang
21268     * @param {*} value The value to check.
21269     * @returns {boolean} Returns `true` if `value` is a native function,
21270     *  else `false`.
21271     * @example
21272     *
21273     * _.isNative(Array.prototype.push);
21274     * // => true
21275     *
21276     * _.isNative(_);
21277     * // => false
21278     */
21279    function isNative(value) {
21280      if (!isObject(value)) {
21281        return false;
21282      }
21283      var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
21284      return pattern.test(toSource(value));
21285    }
21286
21287    /**
21288     * Checks if `value` is `null`.
21289     *
21290     * @static
21291     * @memberOf _
21292     * @since 0.1.0
21293     * @category Lang
21294     * @param {*} value The value to check.
21295     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
21296     * @example
21297     *
21298     * _.isNull(null);
21299     * // => true
21300     *
21301     * _.isNull(void 0);
21302     * // => false
21303     */
21304    function isNull(value) {
21305      return value === null;
21306    }
21307
21308    /**
21309     * Checks if `value` is `null` or `undefined`.
21310     *
21311     * @static
21312     * @memberOf _
21313     * @since 4.0.0
21314     * @category Lang
21315     * @param {*} value The value to check.
21316     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
21317     * @example
21318     *
21319     * _.isNil(null);
21320     * // => true
21321     *
21322     * _.isNil(void 0);
21323     * // => true
21324     *
21325     * _.isNil(NaN);
21326     * // => false
21327     */
21328    function isNil(value) {
21329      return value == null;
21330    }
21331
21332    /**
21333     * Checks if `value` is classified as a `Number` primitive or object.
21334     *
21335     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
21336     * classified as numbers, use the `_.isFinite` method.
21337     *
21338     * @static
21339     * @memberOf _
21340     * @since 0.1.0
21341     * @category Lang
21342     * @param {*} value The value to check.
21343     * @returns {boolean} Returns `true` if `value` is correctly classified,
21344     *  else `false`.
21345     * @example
21346     *
21347     * _.isNumber(3);
21348     * // => true
21349     *
21350     * _.isNumber(Number.MIN_VALUE);
21351     * // => true
21352     *
21353     * _.isNumber(Infinity);
21354     * // => true
21355     *
21356     * _.isNumber('3');
21357     * // => false
21358     */
21359    function isNumber(value) {
21360      return typeof value == 'number' ||
21361        (isObjectLike(value) && objectToString.call(value) == numberTag);
21362    }
21363
21364    /**
21365     * Checks if `value` is a plain object, that is, an object created by the
21366     * `Object` constructor or one with a `[[Prototype]]` of `null`.
21367     *
21368     * @static
21369     * @memberOf _
21370     * @since 0.8.0
21371     * @category Lang
21372     * @param {*} value The value to check.
21373     * @returns {boolean} Returns `true` if `value` is a plain object,
21374     *  else `false`.
21375     * @example
21376     *
21377     * function Foo() {
21378     *   this.a = 1;
21379     * }
21380     *
21381     * _.isPlainObject(new Foo);
21382     * // => false
21383     *
21384     * _.isPlainObject([1, 2, 3]);
21385     * // => false
21386     *
21387     * _.isPlainObject({ 'x': 0, 'y': 0 });
21388     * // => true
21389     *
21390     * _.isPlainObject(Object.create(null));
21391     * // => true
21392     */
21393    function isPlainObject(value) {
21394      if (!isObjectLike(value) ||
21395          objectToString.call(value) != objectTag || isHostObject(value)) {
21396        return false;
21397      }
21398      var proto = getPrototype(value);
21399      if (proto === null) {
21400        return true;
21401      }
21402      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
21403      return (typeof Ctor == 'function' &&
21404        Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
21405    }
21406
21407    /**
21408     * Checks if `value` is classified as a `RegExp` object.
21409     *
21410     * @static
21411     * @memberOf _
21412     * @since 0.1.0
21413     * @category Lang
21414     * @param {*} value The value to check.
21415     * @returns {boolean} Returns `true` if `value` is correctly classified,
21416     *  else `false`.
21417     * @example
21418     *
21419     * _.isRegExp(/abc/);
21420     * // => true
21421     *
21422     * _.isRegExp('/abc/');
21423     * // => false
21424     */
21425    function isRegExp(value) {
21426      return isObject(value) && objectToString.call(value) == regexpTag;
21427    }
21428
21429    /**
21430     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
21431     * double precision number which isn't the result of a rounded unsafe integer.
21432     *
21433     * **Note:** This method is based on
21434     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
21435     *
21436     * @static
21437     * @memberOf _
21438     * @since 4.0.0
21439     * @category Lang
21440     * @param {*} value The value to check.
21441     * @returns {boolean} Returns `true` if `value` is a safe integer,
21442     *  else `false`.
21443     * @example
21444     *
21445     * _.isSafeInteger(3);
21446     * // => true
21447     *
21448     * _.isSafeInteger(Number.MIN_VALUE);
21449     * // => false
21450     *
21451     * _.isSafeInteger(Infinity);
21452     * // => false
21453     *
21454     * _.isSafeInteger('3');
21455     * // => false
21456     */
21457    function isSafeInteger(value) {
21458      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
21459    }
21460
21461    /**
21462     * Checks if `value` is classified as a `Set` object.
21463     *
21464     * @static
21465     * @memberOf _
21466     * @since 4.3.0
21467     * @category Lang
21468     * @param {*} value The value to check.
21469     * @returns {boolean} Returns `true` if `value` is correctly classified,
21470     *  else `false`.
21471     * @example
21472     *
21473     * _.isSet(new Set);
21474     * // => true
21475     *
21476     * _.isSet(new WeakSet);
21477     * // => false
21478     */
21479    function isSet(value) {
21480      return isObjectLike(value) && getTag(value) == setTag;
21481    }
21482
21483    /**
21484     * Checks if `value` is classified as a `String` primitive or object.
21485     *
21486     * @static
21487     * @since 0.1.0
21488     * @memberOf _
21489     * @category Lang
21490     * @param {*} value The value to check.
21491     * @returns {boolean} Returns `true` if `value` is correctly classified,
21492     *  else `false`.
21493     * @example
21494     *
21495     * _.isString('abc');
21496     * // => true
21497     *
21498     * _.isString(1);
21499     * // => false
21500     */
21501    function isString(value) {
21502      return typeof value == 'string' ||
21503        (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
21504    }
21505
21506    /**
21507     * Checks if `value` is classified as a `Symbol` primitive or object.
21508     *
21509     * @static
21510     * @memberOf _
21511     * @since 4.0.0
21512     * @category Lang
21513     * @param {*} value The value to check.
21514     * @returns {boolean} Returns `true` if `value` is correctly classified,
21515     *  else `false`.
21516     * @example
21517     *
21518     * _.isSymbol(Symbol.iterator);
21519     * // => true
21520     *
21521     * _.isSymbol('abc');
21522     * // => false
21523     */
21524    function isSymbol(value) {
21525      return typeof value == 'symbol' ||
21526        (isObjectLike(value) && objectToString.call(value) == symbolTag);
21527    }
21528
21529    /**
21530     * Checks if `value` is classified as a typed array.
21531     *
21532     * @static
21533     * @memberOf _
21534     * @since 3.0.0
21535     * @category Lang
21536     * @param {*} value The value to check.
21537     * @returns {boolean} Returns `true` if `value` is correctly classified,
21538     *  else `false`.
21539     * @example
21540     *
21541     * _.isTypedArray(new Uint8Array);
21542     * // => true
21543     *
21544     * _.isTypedArray([]);
21545     * // => false
21546     */
21547    function isTypedArray(value) {
21548      return isObjectLike(value) &&
21549        isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
21550    }
21551
21552    /**
21553     * Checks if `value` is `undefined`.
21554     *
21555     * @static
21556     * @since 0.1.0
21557     * @memberOf _
21558     * @category Lang
21559     * @param {*} value The value to check.
21560     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
21561     * @example
21562     *
21563     * _.isUndefined(void 0);
21564     * // => true
21565     *
21566     * _.isUndefined(null);
21567     * // => false
21568     */
21569    function isUndefined(value) {
21570      return value === undefined;
21571    }
21572
21573    /**
21574     * Checks if `value` is classified as a `WeakMap` object.
21575     *
21576     * @static
21577     * @memberOf _
21578     * @since 4.3.0
21579     * @category Lang
21580     * @param {*} value The value to check.
21581     * @returns {boolean} Returns `true` if `value` is correctly classified,
21582     *  else `false`.
21583     * @example
21584     *
21585     * _.isWeakMap(new WeakMap);
21586     * // => true
21587     *
21588     * _.isWeakMap(new Map);
21589     * // => false
21590     */
21591    function isWeakMap(value) {
21592      return isObjectLike(value) && getTag(value) == weakMapTag;
21593    }
21594
21595    /**
21596     * Checks if `value` is classified as a `WeakSet` object.
21597     *
21598     * @static
21599     * @memberOf _
21600     * @since 4.3.0
21601     * @category Lang
21602     * @param {*} value The value to check.
21603     * @returns {boolean} Returns `true` if `value` is correctly classified,
21604     *  else `false`.
21605     * @example
21606     *
21607     * _.isWeakSet(new WeakSet);
21608     * // => true
21609     *
21610     * _.isWeakSet(new Set);
21611     * // => false
21612     */
21613    function isWeakSet(value) {
21614      return isObjectLike(value) && objectToString.call(value) == weakSetTag;
21615    }
21616
21617    /**
21618     * Checks if `value` is less than `other`.
21619     *
21620     * @static
21621     * @memberOf _
21622     * @since 3.9.0
21623     * @category Lang
21624     * @param {*} value The value to compare.
21625     * @param {*} other The other value to compare.
21626     * @returns {boolean} Returns `true` if `value` is less than `other`,
21627     *  else `false`.
21628     * @example
21629     *
21630     * _.lt(1, 3);
21631     * // => true
21632     *
21633     * _.lt(3, 3);
21634     * // => false
21635     *
21636     * _.lt(3, 1);
21637     * // => false
21638     */
21639    function lt(value, other) {
21640      return value < other;
21641    }
21642
21643    /**
21644     * Checks if `value` is less than or equal to `other`.
21645     *
21646     * @static
21647     * @memberOf _
21648     * @since 3.9.0
21649     * @category Lang
21650     * @param {*} value The value to compare.
21651     * @param {*} other The other value to compare.
21652     * @returns {boolean} Returns `true` if `value` is less than or equal to
21653     *  `other`, else `false`.
21654     * @example
21655     *
21656     * _.lte(1, 3);
21657     * // => true
21658     *
21659     * _.lte(3, 3);
21660     * // => true
21661     *
21662     * _.lte(3, 1);
21663     * // => false
21664     */
21665    function lte(value, other) {
21666      return value <= other;
21667    }
21668
21669    /**
21670     * Converts `value` to an array.
21671     *
21672     * @static
21673     * @since 0.1.0
21674     * @memberOf _
21675     * @category Lang
21676     * @param {*} value The value to convert.
21677     * @returns {Array} Returns the converted array.
21678     * @example
21679     *
21680     * _.toArray({ 'a': 1, 'b': 2 });
21681     * // => [1, 2]
21682     *
21683     * _.toArray('abc');
21684     * // => ['a', 'b', 'c']
21685     *
21686     * _.toArray(1);
21687     * // => []
21688     *
21689     * _.toArray(null);
21690     * // => []
21691     */
21692    function toArray(value) {
21693      if (!value) {
21694        return [];
21695      }
21696      if (isArrayLike(value)) {
21697        return isString(value) ? stringToArray(value) : copyArray(value);
21698      }
21699      if (iteratorSymbol && value[iteratorSymbol]) {
21700        return iteratorToArray(value[iteratorSymbol]());
21701      }
21702      var tag = getTag(value),
21703          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
21704
21705      return func(value);
21706    }
21707
21708    /**
21709     * Converts `value` to an integer.
21710     *
21711     * **Note:** This function is loosely based on
21712     * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
21713     *
21714     * @static
21715     * @memberOf _
21716     * @since 4.0.0
21717     * @category Lang
21718     * @param {*} value The value to convert.
21719     * @returns {number} Returns the converted integer.
21720     * @example
21721     *
21722     * _.toInteger(3);
21723     * // => 3
21724     *
21725     * _.toInteger(Number.MIN_VALUE);
21726     * // => 0
21727     *
21728     * _.toInteger(Infinity);
21729     * // => 1.7976931348623157e+308
21730     *
21731     * _.toInteger('3');
21732     * // => 3
21733     */
21734    function toInteger(value) {
21735      if (!value) {
21736        return value === 0 ? value : 0;
21737      }
21738      value = toNumber(value);
21739      if (value === INFINITY || value === -INFINITY) {
21740        var sign = (value < 0 ? -1 : 1);
21741        return sign * MAX_INTEGER;
21742      }
21743      var remainder = value % 1;
21744      return value === value ? (remainder ? value - remainder : value) : 0;
21745    }
21746
21747    /**
21748     * Converts `value` to an integer suitable for use as the length of an
21749     * array-like object.
21750     *
21751     * **Note:** This method is based on
21752     * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
21753     *
21754     * @static
21755     * @memberOf _
21756     * @since 4.0.0
21757     * @category Lang
21758     * @param {*} value The value to convert.
21759     * @returns {number} Returns the converted integer.
21760     * @example
21761     *
21762     * _.toLength(3);
21763     * // => 3
21764     *
21765     * _.toLength(Number.MIN_VALUE);
21766     * // => 0
21767     *
21768     * _.toLength(Infinity);
21769     * // => 4294967295
21770     *
21771     * _.toLength('3');
21772     * // => 3
21773     */
21774    function toLength(value) {
21775      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
21776    }
21777
21778    /**
21779     * Converts `value` to a number.
21780     *
21781     * @static
21782     * @memberOf _
21783     * @since 4.0.0
21784     * @category Lang
21785     * @param {*} value The value to process.
21786     * @returns {number} Returns the number.
21787     * @example
21788     *
21789     * _.toNumber(3);
21790     * // => 3
21791     *
21792     * _.toNumber(Number.MIN_VALUE);
21793     * // => 5e-324
21794     *
21795     * _.toNumber(Infinity);
21796     * // => Infinity
21797     *
21798     * _.toNumber('3');
21799     * // => 3
21800     */
21801    function toNumber(value) {
21802      if (typeof value == 'number') {
21803        return value;
21804      }
21805      if (isSymbol(value)) {
21806        return NAN;
21807      }
21808      if (isObject(value)) {
21809        var other = isFunction(value.valueOf) ? value.valueOf() : value;
21810        value = isObject(other) ? (other + '') : other;
21811      }
21812      if (typeof value != 'string') {
21813        return value === 0 ? value : +value;
21814      }
21815      value = value.replace(reTrim, '');
21816      var isBinary = reIsBinary.test(value);
21817      return (isBinary || reIsOctal.test(value))
21818        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
21819        : (reIsBadHex.test(value) ? NAN : +value);
21820    }
21821
21822    /**
21823     * Converts `value` to a plain object flattening inherited enumerable string
21824     * keyed properties of `value` to own properties of the plain object.
21825     *
21826     * @static
21827     * @memberOf _
21828     * @since 3.0.0
21829     * @category Lang
21830     * @param {*} value The value to convert.
21831     * @returns {Object} Returns the converted plain object.
21832     * @example
21833     *
21834     * function Foo() {
21835     *   this.b = 2;
21836     * }
21837     *
21838     * Foo.prototype.c = 3;
21839     *
21840     * _.assign({ 'a': 1 }, new Foo);
21841     * // => { 'a': 1, 'b': 2 }
21842     *
21843     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
21844     * // => { 'a': 1, 'b': 2, 'c': 3 }
21845     */
21846    function toPlainObject(value) {
21847      return copyObject(value, keysIn(value));
21848    }
21849
21850    /**
21851     * Converts `value` to a safe integer. A safe integer can be compared and
21852     * represented correctly.
21853     *
21854     * @static
21855     * @memberOf _
21856     * @since 4.0.0
21857     * @category Lang
21858     * @param {*} value The value to convert.
21859     * @returns {number} Returns the converted integer.
21860     * @example
21861     *
21862     * _.toSafeInteger(3);
21863     * // => 3
21864     *
21865     * _.toSafeInteger(Number.MIN_VALUE);
21866     * // => 0
21867     *
21868     * _.toSafeInteger(Infinity);
21869     * // => 9007199254740991
21870     *
21871     * _.toSafeInteger('3');
21872     * // => 3
21873     */
21874    function toSafeInteger(value) {
21875      return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
21876    }
21877
21878    /**
21879     * Converts `value` to a string if it's not one. An empty string is returned
21880     * for `null` and `undefined` values. The sign of `-0` is preserved.
21881     *
21882     * @static
21883     * @memberOf _
21884     * @since 4.0.0
21885     * @category Lang
21886     * @param {*} value The value to process.
21887     * @returns {string} Returns the string.
21888     * @example
21889     *
21890     * _.toString(null);
21891     * // => ''
21892     *
21893     * _.toString(-0);
21894     * // => '-0'
21895     *
21896     * _.toString([1, 2, 3]);
21897     * // => '1,2,3'
21898     */
21899    function toString(value) {
21900      // Exit early for strings to avoid a performance hit in some environments.
21901      if (typeof value == 'string') {
21902        return value;
21903      }
21904      if (value == null) {
21905        return '';
21906      }
21907      if (isSymbol(value)) {
21908        return symbolToString ? symbolToString.call(value) : '';
21909      }
21910      var result = (value + '');
21911      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
21912    }
21913
21914    /*------------------------------------------------------------------------*/
21915
21916    /**
21917     * Assigns own enumerable string keyed properties of source objects to the
21918     * destination object. Source objects are applied from left to right.
21919     * Subsequent sources overwrite property assignments of previous sources.
21920     *
21921     * **Note:** This method mutates `object` and is loosely based on
21922     * [`Object.assign`](https://mdn.io/Object/assign).
21923     *
21924     * @static
21925     * @memberOf _
21926     * @since 0.10.0
21927     * @category Object
21928     * @param {Object} object The destination object.
21929     * @param {...Object} [sources] The source objects.
21930     * @returns {Object} Returns `object`.
21931     * @example
21932     *
21933     * function Foo() {
21934     *   this.c = 3;
21935     * }
21936     *
21937     * function Bar() {
21938     *   this.e = 5;
21939     * }
21940     *
21941     * Foo.prototype.d = 4;
21942     * Bar.prototype.f = 6;
21943     *
21944     * _.assign({ 'a': 1 }, new Foo, new Bar);
21945     * // => { 'a': 1, 'c': 3, 'e': 5 }
21946     */
21947    var assign = createAssigner(function(object, source) {
21948      if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
21949        copyObject(source, keys(source), object);
21950        return;
21951      }
21952      for (var key in source) {
21953        if (hasOwnProperty.call(source, key)) {
21954          assignValue(object, key, source[key]);
21955        }
21956      }
21957    });
21958
21959    /**
21960     * This method is like `_.assign` except that it iterates over own and
21961     * inherited source properties.
21962     *
21963     * **Note:** This method mutates `object`.
21964     *
21965     * @static
21966     * @memberOf _
21967     * @since 4.0.0
21968     * @alias extend
21969     * @category Object
21970     * @param {Object} object The destination object.
21971     * @param {...Object} [sources] The source objects.
21972     * @returns {Object} Returns `object`.
21973     * @example
21974     *
21975     * function Foo() {
21976     *   this.b = 2;
21977     * }
21978     *
21979     * function Bar() {
21980     *   this.d = 4;
21981     * }
21982     *
21983     * Foo.prototype.c = 3;
21984     * Bar.prototype.e = 5;
21985     *
21986     * _.assignIn({ 'a': 1 }, new Foo, new Bar);
21987     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
21988     */
21989    var assignIn = createAssigner(function(object, source) {
21990      if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
21991        copyObject(source, keysIn(source), object);
21992        return;
21993      }
21994      for (var key in source) {
21995        assignValue(object, key, source[key]);
21996      }
21997    });
21998
21999    /**
22000     * This method is like `_.assignIn` except that it accepts `customizer`
22001     * which is invoked to produce the assigned values. If `customizer` returns
22002     * `undefined`, assignment is handled by the method instead. The `customizer`
22003     * is invoked with five arguments: (objValue, srcValue, key, object, source).
22004     *
22005     * **Note:** This method mutates `object`.
22006     *
22007     * @static
22008     * @memberOf _
22009     * @since 4.0.0
22010     * @alias extendWith
22011     * @category Object
22012     * @param {Object} object The destination object.
22013     * @param {...Object} sources The source objects.
22014     * @param {Function} [customizer] The function to customize assigned values.
22015     * @returns {Object} Returns `object`.
22016     * @example
22017     *
22018     * function customizer(objValue, srcValue) {
22019     *   return _.isUndefined(objValue) ? srcValue : objValue;
22020     * }
22021     *
22022     * var defaults = _.partialRight(_.assignInWith, customizer);
22023     *
22024     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
22025     * // => { 'a': 1, 'b': 2 }
22026     */
22027    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
22028      copyObjectWith(source, keysIn(source), object, customizer);
22029    });
22030
22031    /**
22032     * This method is like `_.assign` except that it accepts `customizer`
22033     * which is invoked to produce the assigned values. If `customizer` returns
22034     * `undefined`, assignment is handled by the method instead. The `customizer`
22035     * is invoked with five arguments: (objValue, srcValue, key, object, source).
22036     *
22037     * **Note:** This method mutates `object`.
22038     *
22039     * @static
22040     * @memberOf _
22041     * @since 4.0.0
22042     * @category Object
22043     * @param {Object} object The destination object.
22044     * @param {...Object} sources The source objects.
22045     * @param {Function} [customizer] The function to customize assigned values.
22046     * @returns {Object} Returns `object`.
22047     * @example
22048     *
22049     * function customizer(objValue, srcValue) {
22050     *   return _.isUndefined(objValue) ? srcValue : objValue;
22051     * }
22052     *
22053     * var defaults = _.partialRight(_.assignWith, customizer);
22054     *
22055     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
22056     * // => { 'a': 1, 'b': 2 }
22057     */
22058    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
22059      copyObjectWith(source, keys(source), object, customizer);
22060    });
22061
22062    /**
22063     * Creates an array of values corresponding to `paths` of `object`.
22064     *
22065     * @static
22066     * @memberOf _
22067     * @since 1.0.0
22068     * @category Object
22069     * @param {Object} object The object to iterate over.
22070     * @param {...(string|string[])} [paths] The property paths of elements to pick,
22071     *  specified individually or in arrays.
22072     * @returns {Array} Returns the new array of picked elements.
22073     * @example
22074     *
22075     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
22076     *
22077     * _.at(object, ['a[0].b.c', 'a[1]']);
22078     * // => [3, 4]
22079     *
22080     * _.at(['a', 'b', 'c'], 0, 2);
22081     * // => ['a', 'c']
22082     */
22083    var at = rest(function(object, paths) {
22084      return baseAt(object, baseFlatten(paths, 1));
22085    });
22086
22087    /**
22088     * Creates an object that inherits from the `prototype` object. If a
22089     * `properties` object is given, its own enumerable string keyed properties
22090     * are assigned to the created object.
22091     *
22092     * @static
22093     * @memberOf _
22094     * @since 2.3.0
22095     * @category Object
22096     * @param {Object} prototype The object to inherit from.
22097     * @param {Object} [properties] The properties to assign to the object.
22098     * @returns {Object} Returns the new object.
22099     * @example
22100     *
22101     * function Shape() {
22102     *   this.x = 0;
22103     *   this.y = 0;
22104     * }
22105     *
22106     * function Circle() {
22107     *   Shape.call(this);
22108     * }
22109     *
22110     * Circle.prototype = _.create(Shape.prototype, {
22111     *   'constructor': Circle
22112     * });
22113     *
22114     * var circle = new Circle;
22115     * circle instanceof Circle;
22116     * // => true
22117     *
22118     * circle instanceof Shape;
22119     * // => true
22120     */
22121    function create(prototype, properties) {
22122      var result = baseCreate(prototype);
22123      return properties ? baseAssign(result, properties) : result;
22124    }
22125
22126    /**
22127     * Assigns own and inherited enumerable string keyed properties of source
22128     * objects to the destination object for all destination properties that
22129     * resolve to `undefined`. Source objects are applied from left to right.
22130     * Once a property is set, additional values of the same property are ignored.
22131     *
22132     * **Note:** This method mutates `object`.
22133     *
22134     * @static
22135     * @since 0.1.0
22136     * @memberOf _
22137     * @category Object
22138     * @param {Object} object The destination object.
22139     * @param {...Object} [sources] The source objects.
22140     * @returns {Object} Returns `object`.
22141     * @example
22142     *
22143     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
22144     * // => { 'user': 'barney', 'age': 36 }
22145     */
22146    var defaults = rest(function(args) {
22147      args.push(undefined, assignInDefaults);
22148      return apply(assignInWith, undefined, args);
22149    });
22150
22151    /**
22152     * This method is like `_.defaults` except that it recursively assigns
22153     * default properties.
22154     *
22155     * **Note:** This method mutates `object`.
22156     *
22157     * @static
22158     * @memberOf _
22159     * @since 3.10.0
22160     * @category Object
22161     * @param {Object} object The destination object.
22162     * @param {...Object} [sources] The source objects.
22163     * @returns {Object} Returns `object`.
22164     * @example
22165     *
22166     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
22167     * // => { 'user': { 'name': 'barney', 'age': 36 } }
22168     *
22169     */
22170    var defaultsDeep = rest(function(args) {
22171      args.push(undefined, mergeDefaults);
22172      return apply(mergeWith, undefined, args);
22173    });
22174
22175    /**
22176     * This method is like `_.find` except that it returns the key of the first
22177     * element `predicate` returns truthy for instead of the element itself.
22178     *
22179     * @static
22180     * @memberOf _
22181     * @since 1.1.0
22182     * @category Object
22183     * @param {Object} object The object to search.
22184     * @param {Array|Function|Object|string} [predicate=_.identity]
22185     *  The function invoked per iteration.
22186     * @returns {string|undefined} Returns the key of the matched element,
22187     *  else `undefined`.
22188     * @example
22189     *
22190     * var users = {
22191     *   'barney':  { 'age': 36, 'active': true },
22192     *   'fred':    { 'age': 40, 'active': false },
22193     *   'pebbles': { 'age': 1,  'active': true }
22194     * };
22195     *
22196     * _.findKey(users, function(o) { return o.age < 40; });
22197     * // => 'barney' (iteration order is not guaranteed)
22198     *
22199     * // The `_.matches` iteratee shorthand.
22200     * _.findKey(users, { 'age': 1, 'active': true });
22201     * // => 'pebbles'
22202     *
22203     * // The `_.matchesProperty` iteratee shorthand.
22204     * _.findKey(users, ['active', false]);
22205     * // => 'fred'
22206     *
22207     * // The `_.property` iteratee shorthand.
22208     * _.findKey(users, 'active');
22209     * // => 'barney'
22210     */
22211    function findKey(object, predicate) {
22212      return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
22213    }
22214
22215    /**
22216     * This method is like `_.findKey` except that it iterates over elements of
22217     * a collection in the opposite order.
22218     *
22219     * @static
22220     * @memberOf _
22221     * @since 2.0.0
22222     * @category Object
22223     * @param {Object} object The object to search.
22224     * @param {Array|Function|Object|string} [predicate=_.identity]
22225     *  The function invoked per iteration.
22226     * @returns {string|undefined} Returns the key of the matched element,
22227     *  else `undefined`.
22228     * @example
22229     *
22230     * var users = {
22231     *   'barney':  { 'age': 36, 'active': true },
22232     *   'fred':    { 'age': 40, 'active': false },
22233     *   'pebbles': { 'age': 1,  'active': true }
22234     * };
22235     *
22236     * _.findLastKey(users, function(o) { return o.age < 40; });
22237     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
22238     *
22239     * // The `_.matches` iteratee shorthand.
22240     * _.findLastKey(users, { 'age': 36, 'active': true });
22241     * // => 'barney'
22242     *
22243     * // The `_.matchesProperty` iteratee shorthand.
22244     * _.findLastKey(users, ['active', false]);
22245     * // => 'fred'
22246     *
22247     * // The `_.property` iteratee shorthand.
22248     * _.findLastKey(users, 'active');
22249     * // => 'pebbles'
22250     */
22251    function findLastKey(object, predicate) {
22252      return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
22253    }
22254
22255    /**
22256     * Iterates over own and inherited enumerable string keyed properties of an
22257     * object invoking `iteratee` for each property. The iteratee is invoked with
22258     * three arguments: (value, key, object). Iteratee functions may exit iteration
22259     * early by explicitly returning `false`.
22260     *
22261     * @static
22262     * @memberOf _
22263     * @since 0.3.0
22264     * @category Object
22265     * @param {Object} object The object to iterate over.
22266     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
22267     * @returns {Object} Returns `object`.
22268     * @example
22269     *
22270     * function Foo() {
22271     *   this.a = 1;
22272     *   this.b = 2;
22273     * }
22274     *
22275     * Foo.prototype.c = 3;
22276     *
22277     * _.forIn(new Foo, function(value, key) {
22278     *   console.log(key);
22279     * });
22280     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
22281     */
22282    function forIn(object, iteratee) {
22283      return object == null
22284        ? object
22285        : baseFor(object, getIteratee(iteratee), keysIn);
22286    }
22287
22288    /**
22289     * This method is like `_.forIn` except that it iterates over properties of
22290     * `object` in the opposite order.
22291     *
22292     * @static
22293     * @memberOf _
22294     * @since 2.0.0
22295     * @category Object
22296     * @param {Object} object The object to iterate over.
22297     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
22298     * @returns {Object} Returns `object`.
22299     * @example
22300     *
22301     * function Foo() {
22302     *   this.a = 1;
22303     *   this.b = 2;
22304     * }
22305     *
22306     * Foo.prototype.c = 3;
22307     *
22308     * _.forInRight(new Foo, function(value, key) {
22309     *   console.log(key);
22310     * });
22311     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
22312     */
22313    function forInRight(object, iteratee) {
22314      return object == null
22315        ? object
22316        : baseForRight(object, getIteratee(iteratee), keysIn);
22317    }
22318
22319    /**
22320     * Iterates over own enumerable string keyed properties of an object invoking
22321     * `iteratee` for each property. The iteratee is invoked with three arguments:
22322     * (value, key, object). Iteratee functions may exit iteration early by
22323     * explicitly returning `false`.
22324     *
22325     * @static
22326     * @memberOf _
22327     * @since 0.3.0
22328     * @category Object
22329     * @param {Object} object The object to iterate over.
22330     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
22331     * @returns {Object} Returns `object`.
22332     * @example
22333     *
22334     * function Foo() {
22335     *   this.a = 1;
22336     *   this.b = 2;
22337     * }
22338     *
22339     * Foo.prototype.c = 3;
22340     *
22341     * _.forOwn(new Foo, function(value, key) {
22342     *   console.log(key);
22343     * });
22344     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
22345     */
22346    function forOwn(object, iteratee) {
22347      return object && baseForOwn(object, getIteratee(iteratee));
22348    }
22349
22350    /**
22351     * This method is like `_.forOwn` except that it iterates over properties of
22352     * `object` in the opposite order.
22353     *
22354     * @static
22355     * @memberOf _
22356     * @since 2.0.0
22357     * @category Object
22358     * @param {Object} object The object to iterate over.
22359     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
22360     * @returns {Object} Returns `object`.
22361     * @example
22362     *
22363     * function Foo() {
22364     *   this.a = 1;
22365     *   this.b = 2;
22366     * }
22367     *
22368     * Foo.prototype.c = 3;
22369     *
22370     * _.forOwnRight(new Foo, function(value, key) {
22371     *   console.log(key);
22372     * });
22373     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
22374     */
22375    function forOwnRight(object, iteratee) {
22376      return object && baseForOwnRight(object, getIteratee(iteratee));
22377    }
22378
22379    /**
22380     * Creates an array of function property names from own enumerable properties
22381     * of `object`.
22382     *
22383     * @static
22384     * @since 0.1.0
22385     * @memberOf _
22386     * @category Object
22387     * @param {Object} object The object to inspect.
22388     * @returns {Array} Returns the new array of property names.
22389     * @example
22390     *
22391     * function Foo() {
22392     *   this.a = _.constant('a');
22393     *   this.b = _.constant('b');
22394     * }
22395     *
22396     * Foo.prototype.c = _.constant('c');
22397     *
22398     * _.functions(new Foo);
22399     * // => ['a', 'b']
22400     */
22401    function functions(object) {
22402      return object == null ? [] : baseFunctions(object, keys(object));
22403    }
22404
22405    /**
22406     * Creates an array of function property names from own and inherited
22407     * enumerable properties of `object`.
22408     *
22409     * @static
22410     * @memberOf _
22411     * @since 4.0.0
22412     * @category Object
22413     * @param {Object} object The object to inspect.
22414     * @returns {Array} Returns the new array of property names.
22415     * @example
22416     *
22417     * function Foo() {
22418     *   this.a = _.constant('a');
22419     *   this.b = _.constant('b');
22420     * }
22421     *
22422     * Foo.prototype.c = _.constant('c');
22423     *
22424     * _.functionsIn(new Foo);
22425     * // => ['a', 'b', 'c']
22426     */
22427    function functionsIn(object) {
22428      return object == null ? [] : baseFunctions(object, keysIn(object));
22429    }
22430
22431    /**
22432     * Gets the value at `path` of `object`. If the resolved value is
22433     * `undefined`, the `defaultValue` is used in its place.
22434     *
22435     * @static
22436     * @memberOf _
22437     * @since 3.7.0
22438     * @category Object
22439     * @param {Object} object The object to query.
22440     * @param {Array|string} path The path of the property to get.
22441     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
22442     * @returns {*} Returns the resolved value.
22443     * @example
22444     *
22445     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
22446     *
22447     * _.get(object, 'a[0].b.c');
22448     * // => 3
22449     *
22450     * _.get(object, ['a', '0', 'b', 'c']);
22451     * // => 3
22452     *
22453     * _.get(object, 'a.b.c', 'default');
22454     * // => 'default'
22455     */
22456    function get(object, path, defaultValue) {
22457      var result = object == null ? undefined : baseGet(object, path);
22458      return result === undefined ? defaultValue : result;
22459    }
22460
22461    /**
22462     * Checks if `path` is a direct property of `object`.
22463     *
22464     * @static
22465     * @since 0.1.0
22466     * @memberOf _
22467     * @category Object
22468     * @param {Object} object The object to query.
22469     * @param {Array|string} path The path to check.
22470     * @returns {boolean} Returns `true` if `path` exists, else `false`.
22471     * @example
22472     *
22473     * var object = { 'a': { 'b': 2 } };
22474     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
22475     *
22476     * _.has(object, 'a');
22477     * // => true
22478     *
22479     * _.has(object, 'a.b');
22480     * // => true
22481     *
22482     * _.has(object, ['a', 'b']);
22483     * // => true
22484     *
22485     * _.has(other, 'a');
22486     * // => false
22487     */
22488    function has(object, path) {
22489      return object != null && hasPath(object, path, baseHas);
22490    }
22491
22492    /**
22493     * Checks if `path` is a direct or inherited property of `object`.
22494     *
22495     * @static
22496     * @memberOf _
22497     * @since 4.0.0
22498     * @category Object
22499     * @param {Object} object The object to query.
22500     * @param {Array|string} path The path to check.
22501     * @returns {boolean} Returns `true` if `path` exists, else `false`.
22502     * @example
22503     *
22504     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
22505     *
22506     * _.hasIn(object, 'a');
22507     * // => true
22508     *
22509     * _.hasIn(object, 'a.b');
22510     * // => true
22511     *
22512     * _.hasIn(object, ['a', 'b']);
22513     * // => true
22514     *
22515     * _.hasIn(object, 'b');
22516     * // => false
22517     */
22518    function hasIn(object, path) {
22519      return object != null && hasPath(object, path, baseHasIn);
22520    }
22521
22522    /**
22523     * Creates an object composed of the inverted keys and values of `object`.
22524     * If `object` contains duplicate values, subsequent values overwrite
22525     * property assignments of previous values.
22526     *
22527     * @static
22528     * @memberOf _
22529     * @since 0.7.0
22530     * @category Object
22531     * @param {Object} object The object to invert.
22532     * @returns {Object} Returns the new inverted object.
22533     * @example
22534     *
22535     * var object = { 'a': 1, 'b': 2, 'c': 1 };
22536     *
22537     * _.invert(object);
22538     * // => { '1': 'c', '2': 'b' }
22539     */
22540    var invert = createInverter(function(result, value, key) {
22541      result[value] = key;
22542    }, constant(identity));
22543
22544    /**
22545     * This method is like `_.invert` except that the inverted object is generated
22546     * from the results of running each element of `object` thru `iteratee`. The
22547     * corresponding inverted value of each inverted key is an array of keys
22548     * responsible for generating the inverted value. The iteratee is invoked
22549     * with one argument: (value).
22550     *
22551     * @static
22552     * @memberOf _
22553     * @since 4.1.0
22554     * @category Object
22555     * @param {Object} object The object to invert.
22556     * @param {Array|Function|Object|string} [iteratee=_.identity]
22557     *  The iteratee invoked per element.
22558     * @returns {Object} Returns the new inverted object.
22559     * @example
22560     *
22561     * var object = { 'a': 1, 'b': 2, 'c': 1 };
22562     *
22563     * _.invertBy(object);
22564     * // => { '1': ['a', 'c'], '2': ['b'] }
22565     *
22566     * _.invertBy(object, function(value) {
22567     *   return 'group' + value;
22568     * });
22569     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
22570     */
22571    var invertBy = createInverter(function(result, value, key) {
22572      if (hasOwnProperty.call(result, value)) {
22573        result[value].push(key);
22574      } else {
22575        result[value] = [key];
22576      }
22577    }, getIteratee);
22578
22579    /**
22580     * Invokes the method at `path` of `object`.
22581     *
22582     * @static
22583     * @memberOf _
22584     * @since 4.0.0
22585     * @category Object
22586     * @param {Object} object The object to query.
22587     * @param {Array|string} path The path of the method to invoke.
22588     * @param {...*} [args] The arguments to invoke the method with.
22589     * @returns {*} Returns the result of the invoked method.
22590     * @example
22591     *
22592     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
22593     *
22594     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
22595     * // => [2, 3]
22596     */
22597    var invoke = rest(baseInvoke);
22598
22599    /**
22600     * Creates an array of the own enumerable property names of `object`.
22601     *
22602     * **Note:** Non-object values are coerced to objects. See the
22603     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
22604     * for more details.
22605     *
22606     * @static
22607     * @since 0.1.0
22608     * @memberOf _
22609     * @category Object
22610     * @param {Object} object The object to query.
22611     * @returns {Array} Returns the array of property names.
22612     * @example
22613     *
22614     * function Foo() {
22615     *   this.a = 1;
22616     *   this.b = 2;
22617     * }
22618     *
22619     * Foo.prototype.c = 3;
22620     *
22621     * _.keys(new Foo);
22622     * // => ['a', 'b'] (iteration order is not guaranteed)
22623     *
22624     * _.keys('hi');
22625     * // => ['0', '1']
22626     */
22627    function keys(object) {
22628      var isProto = isPrototype(object);
22629      if (!(isProto || isArrayLike(object))) {
22630        return baseKeys(object);
22631      }
22632      var indexes = indexKeys(object),
22633          skipIndexes = !!indexes,
22634          result = indexes || [],
22635          length = result.length;
22636
22637      for (var key in object) {
22638        if (baseHas(object, key) &&
22639            !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
22640            !(isProto && key == 'constructor')) {
22641          result.push(key);
22642        }
22643      }
22644      return result;
22645    }
22646
22647    /**
22648     * Creates an array of the own and inherited enumerable property names of `object`.
22649     *
22650     * **Note:** Non-object values are coerced to objects.
22651     *
22652     * @static
22653     * @memberOf _
22654     * @since 3.0.0
22655     * @category Object
22656     * @param {Object} object The object to query.
22657     * @returns {Array} Returns the array of property names.
22658     * @example
22659     *
22660     * function Foo() {
22661     *   this.a = 1;
22662     *   this.b = 2;
22663     * }
22664     *
22665     * Foo.prototype.c = 3;
22666     *
22667     * _.keysIn(new Foo);
22668     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
22669     */
22670    function keysIn(object) {
22671      var index = -1,
22672          isProto = isPrototype(object),
22673          props = baseKeysIn(object),
22674          propsLength = props.length,
22675          indexes = indexKeys(object),
22676          skipIndexes = !!indexes,
22677          result = indexes || [],
22678          length = result.length;
22679
22680      while (++index < propsLength) {
22681        var key = props[index];
22682        if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
22683            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
22684          result.push(key);
22685        }
22686      }
22687      return result;
22688    }
22689
22690    /**
22691     * The opposite of `_.mapValues`; this method creates an object with the
22692     * same values as `object` and keys generated by running each own enumerable
22693     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
22694     * with three arguments: (value, key, object).
22695     *
22696     * @static
22697     * @memberOf _
22698     * @since 3.8.0
22699     * @category Object
22700     * @param {Object} object The object to iterate over.
22701     * @param {Array|Function|Object|string} [iteratee=_.identity]
22702     *  The function invoked per iteration.
22703     * @returns {Object} Returns the new mapped object.
22704     * @example
22705     *
22706     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
22707     *   return key + value;
22708     * });
22709     * // => { 'a1': 1, 'b2': 2 }
22710     */
22711    function mapKeys(object, iteratee) {
22712      var result = {};
22713      iteratee = getIteratee(iteratee, 3);
22714
22715      baseForOwn(object, function(value, key, object) {
22716        result[iteratee(value, key, object)] = value;
22717      });
22718      return result;
22719    }
22720
22721    /**
22722     * Creates an object with the same keys as `object` and values generated
22723     * by running each own enumerable string keyed property of `object` thru
22724     * `iteratee`. The iteratee is invoked with three arguments:
22725     * (value, key, object).
22726     *
22727     * @static
22728     * @memberOf _
22729     * @since 2.4.0
22730     * @category Object
22731     * @param {Object} object The object to iterate over.
22732     * @param {Array|Function|Object|string} [iteratee=_.identity]
22733     *  The function invoked per iteration.
22734     * @returns {Object} Returns the new mapped object.
22735     * @example
22736     *
22737     * var users = {
22738     *   'fred':    { 'user': 'fred',    'age': 40 },
22739     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
22740     * };
22741     *
22742     * _.mapValues(users, function(o) { return o.age; });
22743     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
22744     *
22745     * // The `_.property` iteratee shorthand.
22746     * _.mapValues(users, 'age');
22747     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
22748     */
22749    function mapValues(object, iteratee) {
22750      var result = {};
22751      iteratee = getIteratee(iteratee, 3);
22752
22753      baseForOwn(object, function(value, key, object) {
22754        result[key] = iteratee(value, key, object);
22755      });
22756      return result;
22757    }
22758
22759    /**
22760     * This method is like `_.assign` except that it recursively merges own and
22761     * inherited enumerable string keyed properties of source objects into the
22762     * destination object. Source properties that resolve to `undefined` are
22763     * skipped if a destination value exists. Array and plain object properties
22764     * are merged recursively.Other objects and value types are overridden by
22765     * assignment. Source objects are applied from left to right. Subsequent
22766     * sources overwrite property assignments of previous sources.
22767     *
22768     * **Note:** This method mutates `object`.
22769     *
22770     * @static
22771     * @memberOf _
22772     * @since 0.5.0
22773     * @category Object
22774     * @param {Object} object The destination object.
22775     * @param {...Object} [sources] The source objects.
22776     * @returns {Object} Returns `object`.
22777     * @example
22778     *
22779     * var users = {
22780     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
22781     * };
22782     *
22783     * var ages = {
22784     *   'data': [{ 'age': 36 }, { 'age': 40 }]
22785     * };
22786     *
22787     * _.merge(users, ages);
22788     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
22789     */
22790    var merge = createAssigner(function(object, source, srcIndex) {
22791      baseMerge(object, source, srcIndex);
22792    });
22793
22794    /**
22795     * This method is like `_.merge` except that it accepts `customizer` which
22796     * is invoked to produce the merged values of the destination and source
22797     * properties. If `customizer` returns `undefined`, merging is handled by the
22798     * method instead. The `customizer` is invoked with seven arguments:
22799     * (objValue, srcValue, key, object, source, stack).
22800     *
22801     * **Note:** This method mutates `object`.
22802     *
22803     * @static
22804     * @memberOf _
22805     * @since 4.0.0
22806     * @category Object
22807     * @param {Object} object The destination object.
22808     * @param {...Object} sources The source objects.
22809     * @param {Function} customizer The function to customize assigned values.
22810     * @returns {Object} Returns `object`.
22811     * @example
22812     *
22813     * function customizer(objValue, srcValue) {
22814     *   if (_.isArray(objValue)) {
22815     *     return objValue.concat(srcValue);
22816     *   }
22817     * }
22818     *
22819     * var object = {
22820     *   'fruits': ['apple'],
22821     *   'vegetables': ['beet']
22822     * };
22823     *
22824     * var other = {
22825     *   'fruits': ['banana'],
22826     *   'vegetables': ['carrot']
22827     * };
22828     *
22829     * _.mergeWith(object, other, customizer);
22830     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
22831     */
22832    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
22833      baseMerge(object, source, srcIndex, customizer);
22834    });
22835
22836    /**
22837     * The opposite of `_.pick`;
22837 this method creates an object composed of the
22838     * own and inherited enumerable string keyed properties of `object` that are
22839     * not omitted.
22840     *
22841     * @static
22842     * @since 0.1.0
22843     * @memberOf _
22844     * @category Object
22845     * @param {Object} object The source object.
22846     * @param {...(string|string[])} [props] The property identifiers to omit,
22847     *  specified individually or in arrays.
22848     * @returns {Object} Returns the new object.
22849     * @example
22850     *
22851     * var object = { 'a': 1, 'b': '2', 'c': 3 };
22852     *
22853     * _.omit(object, ['a', 'c']);
22854     * // => { 'b': '2' }
22855     */
22856    var omit = rest(function(object, props) {
22857      if (object == null) {
22858        return {};
22859      }
22860      props = arrayMap(baseFlatten(props, 1), baseCastKey);
22861      return basePick(object, baseDifference(getAllKeysIn(object), props));
22862    });
22863
22864    /**
22865     * The opposite of `_.pickBy`; this method creates an object composed of
22866     * the own and inherited enumerable string keyed properties of `object` that
22867     * `predicate` doesn't return truthy for. The predicate is invoked with two
22868     * arguments: (value, key).
22869     *
22870     * @static
22871     * @memberOf _
22872     * @since 4.0.0
22873     * @category Object
22874     * @param {Object} object The source object.
22875     * @param {Array|Function|Object|string} [predicate=_.identity]
22876     *  The function invoked per property.
22877     * @returns {Object} Returns the new object.
22878     * @example
22879     *
22880     * var object = { 'a': 1, 'b': '2', 'c': 3 };
22881     *
22882     * _.omitBy(object, _.isNumber);
22883     * // => { 'b': '2' }
22884     */
22885    function omitBy(object, predicate) {
22886      predicate = getIteratee(predicate);
22887      return basePickBy(object, function(value, key) {
22888        return !predicate(value, key);
22889      });
22890    }
22891
22892    /**
22893     * Creates an object composed of the picked `object` properties.
22894     *
22895     * @static
22896     * @since 0.1.0
22897     * @memberOf _
22898     * @category Object
22899     * @param {Object} object The source object.
22900     * @param {...(string|string[])} [props] The property identifiers to pick,
22901     *  specified individually or in arrays.
22902     * @returns {Object} Returns the new object.
22903     * @example
22904     *
22905     * var object = { 'a': 1, 'b': '2', 'c': 3 };
22906     *
22907     * _.pick(object, ['a', 'c']);
22908     * // => { 'a': 1, 'c': 3 }
22909     */
22910    var pick = rest(function(object, props) {
22911      return object == null ? {} : basePick(object, baseFlatten(props, 1));
22912    });
22913
22914    /**
22915     * Creates an object composed of the `object` properties `predicate` returns
22916     * truthy for. The predicate is invoked with two arguments: (value, key).
22917     *
22918     * @static
22919     * @memberOf _
22920     * @since 4.0.0
22921     * @category Object
22922     * @param {Object} object The source object.
22923     * @param {Array|Function|Object|string} [predicate=_.identity]
22924     *  The function invoked per property.
22925     * @returns {Object} Returns the new object.
22926     * @example
22927     *
22928     * var object = { 'a': 1, 'b': '2', 'c': 3 };
22929     *
22930     * _.pickBy(object, _.isNumber);
22931     * // => { 'a': 1, 'c': 3 }
22932     */
22933    function pickBy(object, predicate) {
22934      return object == null ? {} : basePickBy(object, getIteratee(predicate));
22935    }
22936
22937    /**
22938     * This method is like `_.get` except that if the resolved value is a
22939     * function it's invoked with the `this` binding of its parent object and
22940     * its result is returned.
22941     *
22942     * @static
22943     * @since 0.1.0
22944     * @memberOf _
22945     * @category Object
22946     * @param {Object} object The object to query.
22947     * @param {Array|string} path The path of the property to resolve.
22948     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
22949     * @returns {*} Returns the resolved value.
22950     * @example
22951     *
22952     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
22953     *
22954     * _.result(object, 'a[0].b.c1');
22955     * // => 3
22956     *
22957     * _.result(object, 'a[0].b.c2');
22958     * // => 4
22959     *
22960     * _.result(object, 'a[0].b.c3', 'default');
22961     * // => 'default'
22962     *
22963     * _.result(object, 'a[0].b.c3', _.constant('default'));
22964     * // => 'default'
22965     */
22966    function result(object, path, defaultValue) {
22967      path = isKey(path, object) ? [path] : baseCastPath(path);
22968
22969      var index = -1,
22970          length = path.length;
22971
22972      // Ensure the loop is entered when path is empty.
22973      if (!length) {
22974        object = undefined;
22975        length = 1;
22976      }
22977      while (++index < length) {
22978        var value = object == null ? undefined : object[path[index]];
22979        if (value === undefined) {
22980          index = length;
22981          value = defaultValue;
22982        }
22983        object = isFunction(value) ? value.call(object) : value;
22984      }
22985      return object;
22986    }
22987
22988    /**
22989     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
22990     * it's created. Arrays are created for missing index properties while objects
22991     * are created for all other missing properties. Use `_.setWith` to customize
22992     * `path` creation.
22993     *
22994     * **Note:** This method mutates `object`.
22995     *
22996     * @static
22997     * @memberOf _
22998     * @since 3.7.0
22999     * @category Object
23000     * @param {Object} object The object to modify.
23001     * @param {Array|string} path The path of the property to set.
23002     * @param {*} value The value to set.
23003     * @returns {Object} Returns `object`.
23004     * @example
23005     *
23006     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
23007     *
23008     * _.set(object, 'a[0].b.c', 4);
23009     * console.log(object.a[0].b.c);
23010     * // => 4
23011     *
23012     * _.set(object, ['x', '0', 'y', 'z'], 5);
23013     * console.log(object.x[0].y.z);
23014     * // => 5
23015     */
23016    function set(object, path, value) {
23017      return object == null ? object : baseSet(object, path, value);
23018    }
23019
23020    /**
23021     * This method is like `_.set` except that it accepts `customizer` which is
23022     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
23023     * path creation is handled by the method instead. The `customizer` is invoked
23024     * with three arguments: (nsValue, key, nsObject).
23025     *
23026     * **Note:** This method mutates `object`.
23027     *
23028     * @static
23029     * @memberOf _
23030     * @since 4.0.0
23031     * @category Object
23032     * @param {Object} object The object to modify.
23033     * @param {Array|string} path The path of the property to set.
23034     * @param {*} value The value to set.
23035     * @param {Function} [customizer] The function to customize assigned values.
23036     * @returns {Object} Returns `object`.
23037     * @example
23038     *
23039     * var object = {};
23040     *
23041     * _.setWith(object, '[0][1]', 'a', Object);
23042     * // => { '0': { '1': 'a' } }
23043     */
23044    function setWith(object, path, value, customizer) {
23045      customizer = typeof customizer == 'function' ? customizer : undefined;
23046      return object == null ? object : baseSet(object, path, value, customizer);
23047    }
23048
23049    /**
23050     * Creates an array of own enumerable string keyed-value pairs for `object`
23051     * which can be consumed by `_.fromPairs`.
23052     *
23053     * @static
23054     * @memberOf _
23055     * @since 4.0.0
23056     * @alias entries
23057     * @category Object
23058     * @param {Object} object The object to query.
23059     * @returns {Array} Returns the new array of key-value pairs.
23060     * @example
23061     *
23062     * function Foo() {
23063     *   this.a = 1;
23064     *   this.b = 2;
23065     * }
23066     *
23067     * Foo.prototype.c = 3;
23068     *
23069     * _.toPairs(new Foo);
23070     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
23071     */
23072    function toPairs(object) {
23073      return baseToPairs(object, keys(object));
23074    }
23075
23076    /**
23077     * Creates an array of own and inherited enumerable string keyed-value pairs
23078     * for `object` which can be consumed by `_.fromPairs`.
23079     *
23080     * @static
23081     * @memberOf _
23082     * @since 4.0.0
23083     * @alias entriesIn
23084     * @category Object
23085     * @param {Object} object The object to query.
23086     * @returns {Array} Returns the new array of key-value pairs.
23087     * @example
23088     *
23089     * function Foo() {
23090     *   this.a = 1;
23091     *   this.b = 2;
23092     * }
23093     *
23094     * Foo.prototype.c = 3;
23095     *
23096     * _.toPairsIn(new Foo);
23097     * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
23098     */
23099    function toPairsIn(object) {
23100      return baseToPairs(object, keysIn(object));
23101    }
23102
23103    /**
23104     * An alternative to `_.reduce`; this method transforms `object` to a new
23105     * `accumulator` object which is the result of running each of its own
23106     * enumerable string keyed properties thru `iteratee`, with each invocation
23107     * potentially mutating the `accumulator` object. The iteratee is invoked
23108     * with four arguments: (accumulator, value, key, object). Iteratee functions
23109     * may exit iteration early by explicitly returning `false`.
23110     *
23111     * @static
23112     * @memberOf _
23113     * @since 1.3.0
23114     * @category Object
23115     * @param {Array|Object} object The object to iterate over.
23116     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
23117     * @param {*} [accumulator] The custom accumulator value.
23118     * @returns {*} Returns the accumulated value.
23119     * @example
23120     *
23121     * _.transform([2, 3, 4], function(result, n) {
23122     *   result.push(n *= n);
23123     *   return n % 2 == 0;
23124     * }, []);
23125     * // => [4, 9]
23126     *
23127     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
23128     *   (result[value] || (result[value] = [])).push(key);
23129     * }, {});
23130     * // => { '1': ['a', 'c'], '2': ['b'] }
23131     */
23132    function transform(object, iteratee, accumulator) {
23133      var isArr = isArray(object) || isTypedArray(object);
23134      iteratee = getIteratee(iteratee, 4);
23135
23136      if (accumulator == null) {
23137        if (isArr || isObject(object)) {
23138          var Ctor = object.constructor;
23139          if (isArr) {
23140            accumulator = isArray(object) ? new Ctor : [];
23141          } else {
23142            accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
23143          }
23144        } else {
23145          accumulator = {};
23146        }
23147      }
23148      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
23149        return iteratee(accumulator, value, index, object);
23150      });
23151      return accumulator;
23152    }
23153
23154    /**
23155     * Removes the property at `path` of `object`.
23156     *
23157     * **Note:** This method mutates `object`.
23158     *
23159     * @static
23160     * @memberOf _
23161     * @since 4.0.0
23162     * @category Object
23163     * @param {Object} object The object to modify.
23164     * @param {Array|string} path The path of the property to unset.
23165     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
23166     * @example
23167     *
23168     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
23169     * _.unset(object, 'a[0].b.c');
23170     * // => true
23171     *
23172     * console.log(object);
23173     * // => { 'a': [{ 'b': {} }] };
23174     *
23175     * _.unset(object, ['a', '0', 'b', 'c']);
23176     * // => true
23177     *
23178     * console.log(object);
23179     * // => { 'a': [{ 'b': {} }] };
23180     */
23181    function unset(object, path) {
23182      return object == null ? true : baseUnset(object, path);
23183    }
23184
23185    /**
23186     * This method is like `_.set` except that accepts `updater` to produce the
23187     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
23188     * is invoked with one argument: (value).
23189     *
23190     * **Note:** This method mutates `object`.
23191     *
23192     * @static
23193     * @memberOf _
23194     * @since 4.6.0
23195     * @category Object
23196     * @param {Object} object The object to modify.
23197     * @param {Array|string} path The path of the property to set.
23198     * @param {Function} updater The function to produce the updated value.
23199     * @returns {Object} Returns `object`.
23200     * @example
23201     *
23202     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
23203     *
23204     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
23205     * console.log(object.a[0].b.c);
23206     * // => 9
23207     *
23208     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
23209     * console.log(object.x[0].y.z);
23210     * // => 0
23211     */
23212    function update(object, path, updater) {
23213      return object == null ? object : baseUpdate(object, path, baseCastFunction(updater));
23214    }
23215
23216    /**
23217     * This method is like `_.update` except that it accepts `customizer` which is
23218     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
23219     * path creation is handled by the method instead. The `customizer` is invoked
23220     * with three arguments: (nsValue, key, nsObject).
23221     *
23222     * **Note:** This method mutates `object`.
23223     *
23224     * @static
23225     * @memberOf _
23226     * @since 4.6.0
23227     * @category Object
23228     * @param {Object} object The object to modify.
23229     * @param {Array|string} path The path of the property to set.
23230     * @param {Function} updater The function to produce the updated value.
23231     * @param {Function} [customizer] The function to customize assigned values.
23232     * @returns {Object} Returns `object`.
23233     * @example
23234     *
23235     * var object = {};
23236     *
23237     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
23238     * // => { '0': { '1': 'a' } }
23239     */
23240    function updateWith(object, path, updater, customizer) {
23241      customizer = typeof customizer == 'function' ? customizer : undefined;
23242      return object == null ? object : baseUpdate(object, path, baseCastFunction(updater), customizer);
23243    }
23244
23245    /**
23246     * Creates an array of the own enumerable string keyed property values of `object`.
23247     *
23248     * **Note:** Non-object values are coerced to objects.
23249     *
23250     * @static
23251     * @since 0.1.0
23252     * @memberOf _
23253     * @category Object
23254     * @param {Object} object The object to query.
23255     * @returns {Array} Returns the array of property values.
23256     * @example
23257     *
23258     * function Foo() {
23259     *   this.a = 1;
23260     *   this.b = 2;
23261     * }
23262     *
23263     * Foo.prototype.c = 3;
23264     *
23265     * _.values(new Foo);
23266     * // => [1, 2] (iteration order is not guaranteed)
23267     *
23268     * _.values('hi');
23269     * // => ['h', 'i']
23270     */
23271    function values(object) {
23272      return object ? baseValues(object, keys(object)) : [];
23273    }
23274
23275    /**
23276     * Creates an array of the own and inherited enumerable string keyed property
23277     * values of `object`.
23278     *
23279     * **Note:** Non-object values are coerced to objects.
23280     *
23281     * @static
23282     * @memberOf _
23283     * @since 3.0.0
23284     * @category Object
23285     * @param {Object} object The object to query.
23286     * @returns {Array} Returns the array of property values.
23287     * @example
23288     *
23289     * function Foo() {
23290     *   this.a = 1;
23291     *   this.b = 2;
23292     * }
23293     *
23294     * Foo.prototype.c = 3;
23295     *
23296     * _.valuesIn(new Foo);
23297     * // => [1, 2, 3] (iteration order is not guaranteed)
23298     */
23299    function valuesIn(object) {
23300      return object == null ? [] : baseValues(object, keysIn(object));
23301    }
23302
23303    /*------------------------------------------------------------------------*/
23304
23305    /**
23306     * Clamps `number` within the inclusive `lower` and `upper` bounds.
23307     *
23308     * @static
23309     * @memberOf _
23310     * @since 4.0.0
23311     * @category Number
23312     * @param {number} number The number to clamp.
23313     * @param {number} [lower] The lower bound.
23314     * @param {number} upper The upper bound.
23315     * @returns {number} Returns the clamped number.
23316     * @example
23317     *
23318     * _.clamp(-10, -5, 5);
23319     * // => -5
23320     *
23321     * _.clamp(10, -5, 5);
23322     * // => 5
23323     */
23324    function clamp(number, lower, upper) {
23325      if (upper === undefined) {
23326        upper = lower;
23327        lower = undefined;
23328      }
23329      if (upper !== undefined) {
23330        upper = toNumber(upper);
23331        upper = upper === upper ? upper : 0;
23332      }
23333      if (lower !== undefined) {
23334        lower = toNumber(lower);
23335        lower = lower === lower ? lower : 0;
23336      }
23337      return baseClamp(toNumber(number), lower, upper);
23338    }
23339
23340    /**
23341     * Checks if `n` is between `start` and up to but not including, `end`. If
23342     * `end` is not specified, it's set to `start` with `start` then set to `0`.
23343     * If `start` is greater than `end` the params are swapped to support
23344     * negative ranges.
23345     *
23346     * @static
23347     * @memberOf _
23348     * @since 3.3.0
23349     * @category Number
23350     * @param {number} number The number to check.
23351     * @param {number} [start=0] The start of the range.
23352     * @param {number} end The end of the range.
23353     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
23354     * @example
23355     *
23356     * _.inRange(3, 2, 4);
23357     * // => true
23358     *
23359     * _.inRange(4, 8);
23360     * // => true
23361     *
23362     * _.inRange(4, 2);
23363     * // => false
23364     *
23365     * _.inRange(2, 2);
23366     * // => false
23367     *
23368     * _.inRange(1.2, 2);
23369     * // => true
23370     *
23371     * _.inRange(5.2, 4);
23372     * // => false
23373     *
23374     * _.inRange(-3, -2, -6);
23375     * // => true
23376     */
23377    function inRange(number, start, end) {
23378      start = toNumber(start) || 0;
23379      if (end === undefined) {
23380        end = start;
23381        start = 0;
23382      } else {
23383        end = toNumber(end) || 0;
23384      }
23385      number = toNumber(number);
23386      return baseInRange(number, start, end);
23387    }
23388
23389    /**
23390     * Produces a random number between the inclusive `lower` and `upper` bounds.
23391     * If only one argument is provided a number between `0` and the given number
23392     * is returned. If `floating` is `true`, or either `lower` or `upper` are
23393     * floats, a floating-point number is returned instead of an integer.
23394     *
23395     * **Note:** JavaScript follows the IEEE-754 standard for resolving
23396     * floating-point values which can produce unexpected results.
23397     *
23398     * @static
23399     * @memberOf _
23400     * @since 0.7.0
23401     * @category Number
23402     * @param {number} [lower=0] The lower bound.
23403     * @param {number} [upper=1] The upper bound.
23404     * @param {boolean} [floating] Specify returning a floating-point number.
23405     * @returns {number} Returns the random number.
23406     * @example
23407     *
23408     * _.random(0, 5);
23409     * // => an integer between 0 and 5
23410     *
23411     * _.random(5);
23412     * // => also an integer between 0 and 5
23413     *
23414     * _.random(5, true);
23415     * // => a floating-point number between 0 and 5
23416     *
23417     * _.random(1.2, 5.2);
23418     * // => a floating-point number between 1.2 and 5.2
23419     */
23420    function random(lower, upper, floating) {
23421      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
23422        upper = floating = undefined;
23423      }
23424      if (floating === undefined) {
23425        if (typeof upper == 'boolean') {
23426          floating = upper;
23427          upper = undefined;
23428        }
23429        else if (typeof lower == 'boolean') {
23430          floating = lower;
23431          lower = undefined;
23432        }
23433      }
23434      if (lower === undefined && upper === undefined) {
23435        lower = 0;
23436        upper = 1;
23437      }
23438      else {
23439        lower = toNumber(lower) || 0;
23440        if (upper === undefined) {
23441          upper = lower;
23442          lower = 0;
23443        } else {
23444          upper = toNumber(upper) || 0;
23445        }
23446      }
23447      if (lower > upper) {
23448        var temp = lower;
23449        lower = upper;
23450        upper = temp;
23451      }
23452      if (floating || lower % 1 || upper % 1) {
23453        var rand = nativeRandom();
23454        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
23455      }
23456      return baseRandom(lower, upper);
23457    }
23458
23459    /*------------------------------------------------------------------------*/
23460
23461    /**
23462     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
23463     *
23464     * @static
23465     * @memberOf _
23466     * @since 3.0.0
23467     * @category String
23468     * @param {string} [string=''] The string to convert.
23469     * @returns {string} Returns the camel cased string.
23470     * @example
23471     *
23472     * _.camelCase('Foo Bar');
23473     * // => 'fooBar'
23474     *
23475     * _.camelCase('--foo-bar--');
23476     * // => 'fooBar'
23477     *
23478     * _.camelCase('__FOO_BAR__');
23479     * // => 'fooBar'
23480     */
23481    var camelCase = createCompounder(function(result, word, index) {
23482      word = word.toLowerCase();
23483      return result + (index ? capitalize(word) : word);
23484    });
23485
23486    /**
23487     * Converts the first character of `string` to upper case and the remaining
23488     * to lower case.
23489     *
23490     * @static
23491     * @memberOf _
23492     * @since 3.0.0
23493     * @category String
23494     * @param {string} [string=''] The string to capitalize.
23495     * @returns {string} Returns the capitalized string.
23496     * @example
23497     *
23498     * _.capitalize('FRED');
23499     * // => 'Fred'
23500     */
23501    function capitalize(string) {
23502      return upperFirst(toString(string).toLowerCase());
23503    }
23504
23505    /**
23506     * Deburrs `string` by converting
23507     * [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
23508     * to basic latin letters and removing
23509     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
23510     *
23511     * @static
23512     * @memberOf _
23513     * @since 3.0.0
23514     * @category String
23515     * @param {string} [string=''] The string to deburr.
23516     * @returns {string} Returns the deburred string.
23517     * @example
23518     *
23519     * _.deburr('déjà vu');
23520     * // => 'deja vu'
23521     */
23522    function deburr(string) {
23523      string = toString(string);
23524      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
23525    }
23526
23527    /**
23528     * Checks if `string` ends with the given target string.
23529     *
23530     * @static
23531     * @memberOf _
23532     * @since 3.0.0
23533     * @category String
23534     * @param {string} [string=''] The string to search.
23535     * @param {string} [target] The string to search for.
23536     * @param {number} [position=string.length] The position to search from.
23537     * @returns {boolean} Returns `true` if `string` ends with `target`,
23538     *  else `false`.
23539     * @example
23540     *
23541     * _.endsWith('abc', 'c');
23542     * // => true
23543     *
23544     * _.endsWith('abc', 'b');
23545     * // => false
23546     *
23547     * _.endsWith('abc', 'b', 2);
23548     * // => true
23549     */
23550    function endsWith(string, target, position) {
23551      string = toString(string);
23552      target = typeof target == 'string' ? target : (target + '');
23553
23554      var length = string.length;
23555      position = position === undefined
23556        ? length
23557        : baseClamp(toInteger(position), 0, length);
23558
23559      position -= target.length;
23560      return position >= 0 && string.indexOf(target, position) == position;
23561    }
23562
23563    /**
23564     * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
23565     * their corresponding HTML entities.
23566     *
23567     * **Note:** No other characters are escaped. To escape additional
23568     * characters use a third-party library like [_he_](https://mths.be/he).
23569     *
23570     * Though the ">" character is escaped for symmetry, characters like
23571     * ">" and "/" don't need escaping in HTML and have no special meaning
23572     * unless they're part of a tag or unquoted attribute value. See
23573     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
23574     * (under "semi-related fun fact") for more details.
23575     *
23576     * Backticks are escaped because in IE < 9, they can break out of
23577     * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
23578     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
23579     * [#133](https://html5sec.org/#133) of the
23580     * [HTML5 Security Cheatsheet](https://html5sec.org/
vendor: 7,013 bytes, lines 23580-23824
23580) for more details.
23581     *
23582     * When working with HTML you should always
23583     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
23584     * XSS vectors.
23585     *
23586     * @static
23587     * @since 0.1.0
23588     * @memberOf _
23589     * @category String
23590     * @param {string} [string=''] The string to escape.
23591     * @returns {string} Returns the escaped string.
23592     * @example
23593     *
23594     * _.escape('fred, barney, & pebbles');
23595     * // => 'fred, barney, &amp; pebbles'
23596     */
23597    function escape(string) {
23598      string = toString(string);
23599      return (string && reHasUnescapedHtml.test(string))
23600        ? string.replace(reUnescapedHtml, escapeHtmlChar)
23601        : string;
23602    }
23603
23604    /**
23605     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
23606     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
23607     *
23608     * @static
23609     * @memberOf _
23610     * @since 3.0.0
23611     * @category String
23612     * @param {string} [string=''] The string to escape.
23613     * @returns {string} Returns the escaped string.
23614     * @example
23615     *
23616     * _.escapeRegExp('[lodash](https://lodash.com/)');
23617     * // => '\[lodash\]\(https://lodash\.com/\)'
23618     */
23619    function escapeRegExp(string) {
23620      string = toString(string);
23621      return (string && reHasRegExpChar.test(string))
23622        ? string.replace(reRegExpChar, '\\$&')
23623        : string;
23624    }
23625
23626    /**
23627     * Converts `string` to
23628     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
23629     *
23630     * @static
23631     * @memberOf _
23632     * @since 3.0.0
23633     * @category String
23634     * @param {string} [string=''] The string to convert.
23635     * @returns {string} Returns the kebab cased string.
23636     * @example
23637     *
23638     * _.kebabCase('Foo Bar');
23639     * // => 'foo-bar'
23640     *
23641     * _.kebabCase('fooBar');
23642     * // => 'foo-bar'
23643     *
23644     * _.kebabCase('__FOO_BAR__');
23645     * // => 'foo-bar'
23646     */
23647    var kebabCase = createCompounder(function(result, word, index) {
23648      return result + (index ? '-' : '') + word.toLowerCase();
23649    });
23650
23651    /**
23652     * Converts `string`, as space separated words, to lower case.
23653     *
23654     * @static
23655     * @memberOf _
23656     * @since 4.0.0
23657     * @category String
23658     * @param {string} [string=''] The string to convert.
23659     * @returns {string} Returns the lower cased string.
23660     * @example
23661     *
23662     * _.lowerCase('--Foo-Bar--');
23663     * // => 'foo bar'
23664     *
23665     * _.lowerCase('fooBar');
23666     * // => 'foo bar'
23667     *
23668     * _.lowerCase('__FOO_BAR__');
23669     * // => 'foo bar'
23670     */
23671    var lowerCase = createCompounder(function(result, word, index) {
23672      return result + (index ? ' ' : '') + word.toLowerCase();
23673    });
23674
23675    /**
23676     * Converts the first character of `string` to lower case.
23677     *
23678     * @static
23679     * @memberOf _
23680     * @since 4.0.0
23681     * @category String
23682     * @param {string} [string=''] The string to convert.
23683     * @returns {string} Returns the converted string.
23684     * @example
23685     *
23686     * _.lowerFirst('Fred');
23687     * // => 'fred'
23688     *
23689     * _.lowerFirst('FRED');
23690     * // => 'fRED'
23691     */
23692    var lowerFirst = createCaseFirst('toLowerCase');
23693
23694    /**
23695     * Pads `string` on the left and right sides if it's shorter than `length`.
23696     * Padding characters are truncated if they can't be evenly divided by `length`.
23697     *
23698     * @static
23699     * @memberOf _
23700     * @since 3.0.0
23701     * @category String
23702     * @param {string} [string=''] The string to pad.
23703     * @param {number} [length=0] The padding length.
23704     * @param {string} [chars=' '] The string used as padding.
23705     * @returns {string} Returns the padded string.
23706     * @example
23707     *
23708     * _.pad('abc', 8);
23709     * // => '  abc   '
23710     *
23711     * _.pad('abc', 8, '_-');
23712     * // => '_-abc_-_'
23713     *
23714     * _.pad('abc', 3);
23715     * // => 'abc'
23716     */
23717    function pad(string, length, chars) {
23718      string = toString(string);
23719      length = toInteger(length);
23720
23721      var strLength = length ? stringSize(string) : 0;
23722      if (!length || strLength >= length) {
23723        return string;
23724      }
23725      var mid = (length - strLength) / 2;
23726      return (
23727        createPadding(nativeFloor(mid), chars) +
23728        string +
23729        createPadding(nativeCeil(mid), chars)
23730      );
23731    }
23732
23733    /**
23734     * Pads `string` on the right side if it's shorter than `length`. Padding
23735     * characters are truncated if they exceed `length`.
23736     *
23737     * @static
23738     * @memberOf _
23739     * @since 4.0.0
23740     * @category String
23741     * @param {string} [string=''] The string to pad.
23742     * @param {number} [length=0] The padding length.
23743     * @param {string} [chars=' '] The string used as padding.
23744     * @returns {string} Returns the padded string.
23745     * @example
23746     *
23747     * _.padEnd('abc', 6);
23748     * // => 'abc   '
23749     *
23750     * _.padEnd('abc', 6, '_-');
23751     * // => 'abc_-_'
23752     *
23753     * _.padEnd('abc', 3);
23754     * // => 'abc'
23755     */
23756    function padEnd(string, length, chars) {
23757      string = toString(string);
23758      length = toInteger(length);
23759
23760      var strLength = length ? stringSize(string) : 0;
23761      return (length && strLength < length)
23762        ? (string + createPadding(length - strLength, chars))
23763        : string;
23764    }
23765
23766    /**
23767     * Pads `string` on the left side if it's shorter than `length`. Padding
23768     * characters are truncated if they exceed `length`.
23769     *
23770     * @static
23771     * @memberOf _
23772     * @since 4.0.0
23773     * @category String
23774     * @param {string} [string=''] The string to pad.
23775     * @param {number} [length=0] The padding length.
23776     * @param {string} [chars=' '] The string used as padding.
23777     * @returns {string} Returns the padded string.
23778     * @example
23779     *
23780     * _.padStart('abc', 6);
23781     * // => '   abc'
23782     *
23783     * _.padStart('abc', 6, '_-');
23784     * // => '_-_abc'
23785     *
23786     * _.padStart('abc', 3);
23787     * // => 'abc'
23788     */
23789    function padStart(string, length, chars) {
23790      string = toString(string);
23791      length = toInteger(length);
23792
23793      var strLength = length ? stringSize(string) : 0;
23794      return (length && strLength < length)
23795        ? (createPadding(length - strLength, chars) + string)
23796        : string;
23797    }
23798
23799    /**
23800     * Converts `string` to an integer of the specified radix. If `radix` is
23801     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
23802     * hexadecimal, in which case a `radix` of `16` is used.
23803     *
23804     * **Note:** This method aligns with the
23805     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
23806     *
23807     * @static
23808     * @memberOf _
23809     * @since 1.1.0
23810     * @category String
23811     * @param {string} string The string to convert.
23812     * @param {number} [radix=10] The radix to interpret `value` by.
23813     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
23814     * @returns {number} Returns the converted integer.
23815     * @example
23816     *
23817     * _.parseInt('08');
23818     * // => 8
23819     *
23820     * _.map(['6', '08', '10'], _.parseInt);
23821     * // => [6, 8, 10]
23822     */
23823    function parseInt(string, radix, guard) {
23824      
23824// Chrome fails to trim leading <BOM> whitespace characters.
23825      // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details.
23826      if (guard || radix == null) {
23827        radix = 0;
23828      } else if (radix) {
23829        radix = +radix;
23830      }
23831      string = toString(string).replace(reTrim, '');
23832      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
23833    }
23834
23835    /**
23836     * Repeats the given string `n` times.
23837     *
23838     * @static
23839     * @memberOf _
23840     * @since 3.0.0
23841     * @category String
23842     * @param {string} [string=''] The string to repeat.
23843     * @param {number} [n=1] The number of times to repeat the string.
23844     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
23845     * @returns {string} Returns the repeated string.
23846     * @example
23847     *
23848     * _.repeat('*', 3);
23849     * // => '***'
23850     *
23851     * _.repeat('abc', 2);
23852     * // => 'abcabc'
23853     *
23854     * _.repeat('abc', 0);
23855     * // => ''
23856     */
23857    function repeat(string, n, guard) {
23858      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
23859        n = 1;
23860      } else {
23861        n = toInteger(n);
23862      }
23863      return baseRepeat(toString(string), n);
23864    }
23865
23866    /**
23867     * Replaces matches for `pattern` in `string` with `replacement`.
23868     *
23869     * **Note:** This method is based on
23870     * [`String#replace`](https://mdn.io/String/replace).
23871     *
23872     * @static
23873     * @memberOf _
23874     * @since 4.0.0
23875     * @category String
23876     * @param {string} [string=''] The string to modify.
23877     * @param {RegExp|string} pattern The pattern to replace.
23878     * @param {Function|string} replacement The match replacement.
23879     * @returns {string} Returns the modified string.
23880     * @example
23881     *
23882     * _.replace('Hi Fred', 'Fred', 'Barney');
23883     * // =>
23883 'Hi Barney'
23884     */
23885    function replace() {
23886      var args = arguments,
23887          string = toString(args[0]);
23888
23889      return args.length < 3 ? string : string.replace(args[1], args[2]);
23890    }
23891
23892    /**
23893     * Converts `string` to
23894     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
23895     *
23896     * @static
23897     * @memberOf _
23898     * @since 3.0.0
23899     * @category String
23900     * @param {string} [string=''] The string to convert.
23901     * @returns {string} Returns the snake cased string.
23902     * @example
23903     *
23904     * _.snakeCase('Foo Bar');
23905     * // => 'foo_bar'
23906     *
23907     * _.snakeCase('fooBar');
23908     * // => 'foo_bar'
23909     *
23910     * _.snakeCase('--FOO-BAR--');
23911     * // => 'foo_bar'
23912     */
23913    var snakeCase = createCompounder(function(result, word, index) {
23914      return result + (index ? '_' : '') + word.toLowerCase();
23915    });
23916
23917    /**
23918     * Splits `string` by `separator`.
23919     *
23920     * **Note:** This method is based on
23921     * [`String#split`](https://mdn.io/String/split).
23922     *
23923     * @static
23924     * @memberOf _
23925     * @since 4.0.0
23926     * @category String
23927     * @param {string} [string=''] The string to split.
23928     * @param {RegExp|string} separator The separator pattern to split by.
23929     * @param {number} [limit] The length to truncate results to.
23930     * @returns {Array} Returns the new array of string segments.
23931     * @example
23932     *
23933     * _.split('a-b-c', '-', 2);
23934     * // => ['a', 'b']
23935     */
23936    function split(string, separator, limit) {
23937      string = toString(string);
23938      if (string && (
23939            typeof separator == 'string' ||
23940            (separator != null && !isRegExp(separator))
23941          )) {
23942        separator += '';
23943        if (separator == '' && reHasComplexSymbol.test(string)) {
23944          var strSymbols = stringToArray(string);
23945          return limit === undefined ? strSymbols : strSymbols.slice(0, limit < 0 ? 0 : limit);
23946        }
23947      }
23948      return string.split(separator, limit);
23949    }
23950
23951    /**
23952     * Converts `string` to
23953     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
23954     *
23955     * @static
23956     * @memberOf _
23957     * @since 3.1.0
23958     * @category String
23959     * @param {string} [string=''] The string to convert.
23960     * @returns {string} Returns the start cased string.
23961     * @example
23962     *
23963     * _.startCase('--foo-bar--');
23964     * // => 'Foo Bar'
23965     *
23966     * _.startCase('fooBar');
23967     * // => 'Foo Bar'
23968     *
23969     * _.startCase('__FOO_BAR__');
23970     * // => 'FOO BAR'
23971     */
23972    var startCase = createCompounder(function(result, word, index) {
23973      return result + (index ? ' ' : '') + upperFirst(word);
23974    });
23975
23976    /**
23977     * Checks if `string` starts with the given target string.
23978     *
23979     * @static
23980     * @memberOf _
23981     * @since 3.0.0
23982     * @category String
23983     * @param {string} [string=''] The string to search.
23984     * @param {string} [target] The string to search for.
23985     * @param {number} [position=0] The position to search from.
23986     * @returns {boolean} Returns `true` if `string` starts with `target`,
23987     *  else `false`.
23988     * @example
23989     *
23990     * _.startsWith('abc', 'a');
23991     * // => true
23992     *
23993     * _.startsWith('abc', 'b');
23994     * // => false
23995     *
23996     * _.startsWith('abc', 'b', 1);
23997     * // => true
23998     */
23999    function startsWith(string, target, position) {
24000      string = toString(string);
24001      position = baseClamp(toInteger(position), 0, string.length);
24002      return string.lastIndexOf(target, position) == position;
24003    }
24004
24005    /**
24006     * Creates a compiled template function that can interpolate data properties
24007     * in "interpolate" delimiters, HTML-escape interpolated data properties in
24008     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
24009     * properties may be accessed as free variables in the template. If a setting
24010     * object is given, it takes precedence over `_.templateSettings` values.
24011     *
24012     * **Note:** In the development build `_.template` utilizes
24013     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
24014     * for easier debugging.
24015     *
24016     * For more information on precompiling templates see
24017     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
24018     *
24019     * For more information on Chrome extension sandboxes see
24020     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
24021     *
24022     * @static
24023     * @since 0.1.0
24024     * @memberOf _
24025     * @category String
24026     * @param {string} [string=''] The template string.
24027     * @param {Object} [options={}] The options object.
24028     * @param {RegExp} [options.escape=_.templateSettings.escape]
24029     *  The HTML "escape" delimiter.
24030     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
24031     *  The "evaluate" delimiter.
24032     * @param {Object} [options.imports=_.templateSettings.imports]
24033     *  An object to import into the template as free variables.
24034     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
24035     *  The "interpolate" delimiter.
24036     * @param {string} [options.sourceURL='lodash.templateSources[n]']
24037     *  The sourceURL of the compiled template.
24038     * @param {string} [options.variable='obj']
24039     *  The data object variable name.
24040     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24041     * @returns {Function} Returns the compiled template function.
24042     * @example
24043     *
24044     * // Use the "interpolate" delimiter to create a compiled template.
24045     * var compiled = _.template('hello <%= user %>!');
24046     * compiled({ 'user': 'fred' });
24047     * // => 'hello fred!'
24048     *
24049     * // Use the HTML "escape" delimiter to escape data property values.
24050     * var compiled = _.template('<b><%- value %></b>');
24051     * compiled({ 'value': '<script>' });
24052     * // => '<b>&lt;script&gt;</b>'
24053     *
24054     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
24055     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
24056     * compiled({ 'users': ['fred', 'barney'] });
24057     * // => '<li>fred</li><li>barney</li>'
24058     *
24059     * // Use the internal `print` function in "evaluate" delimiters.
24060     * var compiled = _.template('<% print("hello " + user); %>!');
24061     * compiled({ 'user': 'barney' });
24062     * // => 'hello barney!'
24063     *
24064     * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
24065     * var compiled = _.template('hello ${ user }!');
24066     * compiled({ 'user': 'pebbles' });
24067     * // => 'hello pebbles!'
24068     *
24069     * // Use custom template delimiters.
24070     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
24071     * var compiled = _.template('hello {{ user }}!');
24072     * compiled({ 'user': 'mustache' });
24073     * // => 'hello mustache!'
24074     *
24075     * // Use backslashes to treat delimiters as plain text.
24076     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
24077     * compiled({ 'value': 'ignored' });
24078     * // => '<%- value %>'
24079     *
24080     * // Use the `imports` option to import `jQuery` as `jq`.
24081     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
24082     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
24083     * compiled({ 'users': ['fred', 'barney'] });
24084     * // => '<li>fred</li><li>barney</li>'
24085     *
24086     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
24087     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
24088     * compiled(data);
24089     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
24090     *
24091     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
24092     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
24093     * compiled.source;
24094     * // => function(data) {
24095     * //   var __t, __p = '';
24096     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
24097     * //   return __p;
24098     * // }
24099     *
24100     * // Use the `source` property to inline compiled templates for meaningful
24101     * // line numbers in error messages and stack traces.
24102     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
24103     *   var JST = {\
24104     *     "main": ' + _.template(mainText).source + '\
24105     *   };\
24106     * ');
24107     */
24108    function template(string, options, guard) {
24109      // Based on John Resig's `tmpl` implementation
24110      // (http://ejohn.org/blog/javascript-micro-templating/)
24111      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
24112      var settings = lodash.templateSettings;
24113
24114      if (guard && isIterateeCall(string, options, guard)) {
24115        options = undefined;
24116      }
24117      string = toString(string);
24118      options = assignInWith({}, options, settings, assignInDefaults);
24119
24120      var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
24121          importsKeys = keys(imports),
24122          importsValues = baseValues(imports, importsKeys);
24123
24124      var isEscaping,
24125          isEvaluating,
24126          index = 0,
24127          interpolate = options.interpolate || reNoMatch,
24128          source = "__p += '";
24129
24130      // Compile the regexp to match each delimiter.
24131      var reDelimiters = RegExp(
24132        (options.escape || reNoMatch).source + '|' +
24133        interpolate.source + '|' +
24134        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
24135        (options.evaluate || reNoMatch).source + '|$'
24136      , 'g');
24137
24138      // Use a sourceURL for easier debugging.
24139      var sourceURL = '//# sourceURL=' +
24140        ('sourceURL' in options
24141          ? options.sourceURL
24142          : ('lodash.templateSources[' + (++templateCounter) + ']')
24143        ) + '\n';
24144
24145      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
24146        interpolateValue || (interpolateValue = esTemplateValue);
24147
24148        // Escape characters that can't be included in string literals.
24149        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
24150
24151        // Replace delimiters with snippets.
24152        if (escapeValue) {
24153          isEscaping = true;
24154          source += "' +\n__e(" + escapeValue + ") +\n'";
24155        }
24156        if (evaluateValue) {
24157          isEvaluating = true;
24158          source += "';\n" + evaluateValue + ";\n__p += '";
24159        }
24160        if (interpolateValue) {
24161          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
24162        }
24163        index = offset + match.length;
24164
24165        // The JS engine embedded in Adobe products needs `match` returned in
24166        // order to produce the correct `offset` value.
24167        return match;
24168      });
24169
24170      source += "';\n";
24171
24172      // If `variable` is not specified wrap a with-statement around the generated
24173      // code to add the data object to the top of the scope chain.
24174      var variable = options.variable;
24175      if (!variable) {
24176        source = 'with (obj) {\n' + source + '\n}\n';
24177      }
24178      // Cleanup code by stripping empty strings.
24179      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
24180        .replace(reEmptyStringMiddle, '$1')
24181        .replace(reEmptyStringTrailing, '$1;');
24182
24183      // Frame code as the function body.
24184      source = 'function(' + (variable || 'obj') + ') {\n' +
24185        (variable
24186          ? ''
24187          : 'obj || (obj = {});\n'
24188        ) +
24189        "var __t, __p = ''" +
24190        (isEscaping
24191           ? ', __e = _.escape'
24192           : ''
24193        ) +
24194        (isEvaluating
24195          ? ', __j = Array.prototype.join;\n' +
24196            "function print() { __p += __j.call(arguments, '') }\n"
24197          : ';\n'
24198        ) +
24199        source +
24200        'return __p\n}';
24201
24202      var result = attempt(function() {
24203        return Function(importsKeys, sourceURL + 'return ' + source)
24204          .apply(undefined, importsValues);
24205      });
24206
24207      // Provide the compiled function's source by its `toString` method or
24208      // the `source` property as a convenience for inlining compiled templates.
24209      result.source = source;
24210      if (isError(result)) {
24211        throw result;
24212      }
24213      return result;
24214    }
24215
24216    /**
24217     * Converts `string`, as a whole, to lower case just like
24218     * [String#toLowerCase](https://mdn.io/toLowerCase).
24219     *
24220     * @static
24221     * @memberOf _
24222     * @since 4.0.0
24223     * @category String
24224     * @param {string} [string=''] The string to convert.
24225     * @returns {string} Returns the lower cased string.
24226     * @example
24227     *
24228     * _.toLower('--Foo-Bar--');
24229     * // => '--foo-bar--'
24230     *
24231     * _.toLower('fooBar');
24232     * // => 'foobar'
24233     *
24234     * _.toLower('__FOO_BAR__');
24235     * // => '__foo_bar__'
24236     */
24237    function toLower(value) {
24238      return toString(value).toLowerCase();
24239    }
24240
24241    /**
24242     * Converts `string`, as a whole, to upper case just like
24243     * [String#toUpperCase](https://mdn.io/toUpperCase).
24244     *
24245     * @static
24246     * @memberOf _
24247     * @since 4.0.0
24248     * @category String
24249     * @param {string} [string=''] The string to convert.
24250     * @returns {string} Returns the upper cased string.
24251     * @example
24252     *
24253     * _.toUpper('--foo-bar--');
24254     * // => '--FOO-BAR--'
24255     *
24256     * _.toUpper('fooBar');
24257     * // => 'FOOBAR'
24258     *
24259     * _.toUpper('__foo_bar__');
24260     * // => '__FOO_BAR__'
24261     */
24262    function toUpper(value) {
24263      return toString(value).toUpperCase();
24264    }
24265
24266    /**
24267     * Removes leading and trailing whitespace or specified characters from `string`.
24268     *
24269     * @static
24270     * @memberOf _
24271     * @since 3.0.0
24272     * @category String
24273     * @param {string} [string=''] The string to trim.
24274     * @param {string} [chars=whitespace] The characters to trim.
24275     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24276     * @returns {string} Returns the trimmed string.
24277     * @example
24278     *
24279     * _.trim('  abc  ');
24280     * // => 'abc'
24281     *
24282     * _.trim('-_-abc-_-', '_-');
24283     * // => 'abc'
24284     *
24285     * _.map(['  foo  ', '  bar  '], _.trim);
24286     * // => ['foo', 'bar']
24287     */
24288    function trim(string, chars, guard) {
24289      string = toString(string);
24290      if (!string) {
24291        return string;
24292      }
24293      if (guard || chars === undefined) {
24294        return string.replace(reTrim, '');
24295      }
24296      chars = (chars + '');
24297      if (!chars) {
24298        return string;
24299      }
24300      var strSymbols = stringToArray(string),
24301          chrSymbols = stringToArray(chars);
24302
24303      return strSymbols
24304        .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1)
24305        .join('');
24306    }
24307
24308    /**
24309     * Removes trailing whitespace or specified characters from `string`.
24310     *
24311     * @static
24312     * @memberOf _
24313     * @since 4.0.0
24314     * @category String
24315     * @param {string} [string=''] The string to trim.
24316     * @param {string} [chars=whitespace] The characters to trim.
24317     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24318     * @returns {string} Returns the trimmed string.
24319     * @example
24320     *
24321     * _.trimEnd('  abc  ');
24322     * // => '  abc'
24323     *
24324     * _.trimEnd('-_-abc-_-', '_-');
24325     * // => '-_-abc'
24326     */
24327    function trimEnd(string, chars, guard) {
24328      string = toString(string);
24329      if (!string) {
24330        return string;
24331      }
24332      if (guard || chars === undefined) {
24333        return string.replace(reTrimEnd, '');
24334      }
24335      chars = (chars + '');
24336      if (!chars) {
24337        return string;
24338      }
24339      var strSymbols = stringToArray(string);
24340      return strSymbols
24341        .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1)
24342        .join('');
24343    }
24344
24345    /**
24346     * Removes leading whitespace or specified characters from `string`.
24347     *
24348     * @static
24349     * @memberOf _
24350     * @since 4.0.0
24351     * @category String
24352     * @param {string} [string=''] The string to trim.
24353     * @param {string} [chars=whitespace] The characters to trim.
24354     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24355     * @returns {string} Returns the trimmed string.
24356     * @example
24357     *
24358     * _.trimStart('  abc  ');
24359     * // => 'abc  '
24360     *
24361     * _.trimStart('-_-abc-_-', '_-');
24362     * // => 'abc-_-'
24363     */
24364    function trimStart(string, chars, guard) {
24365      string = toString(string);
24366      if (!string) {
24367        return string;
24368      }
24369      if (guard || chars === undefined) {
24370        return string.replace(reTrimStart, '');
24371      }
24372      chars = (chars + '');
24373      if (!chars) {
24374        return string;
24375      }
24376      var strSymbols = stringToArray(string);
24377      return strSymbols
24378        .slice(charsStartIndex(strSymbols, stringToArray(chars)))
24379        .join('');
24380    }
24381
24382    /**
24383     * Truncates `string` if it's longer than the given maximum string length.
24384     * The last characters of the truncated string are replaced with the omission
24385     * string which defaults to "...".
24386     *
24387     * @static
24388     * @memberOf _
24389     * @since 4.0.0
24390     * @category String
24391     * @param {string} [string=''] The string to truncate.
24392     * @param {Object} [options={}] The options object.
24393     * @param {number} [options.length=30] The maximum string length.
24394     * @param {string} [options.omission='...'] The string to indicate text is omitted.
24395     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
24396     * @returns {string} Returns the truncated string.
24397     * @example
24398     *
24399     * _.truncate('hi-diddly-ho there, neighborino');
24400     * // => 'hi-diddly-ho there, neighbo...'
24401     *
24402     * _.truncate('hi-diddly-ho there, neighborino', {
24403     *   'length': 24,
24404     *   'separator': ' '
24405     * });
24406     * // => 'hi-diddly-ho there,...'
24407     *
24408     * _.truncate('hi-diddly-ho there, neighborino', {
24409     *   'length': 24,
24410     *   'separator': /,? +/
24411     * });
24412     * // => 'hi-diddly-ho there...'
24413     *
24414     * _.truncate('hi-diddly-ho there, neighborino', {
24415     *   'omission': ' [...]'
24416     * });
24417     * // => 'hi-diddly-ho there, neig [...]'
24418     */
24419    function truncate(string, options) {
24420      var length = DEFAULT_TRUNC_LENGTH,
24421          omission = DEFAULT_TRUNC_OMISSION;
24422
24423      if (isObject(options)) {
24424        var separator = 'separator' in options ? options.separator : separator;
24425        length = 'length' in options ? toInteger(options.length) : length;
24426        omission = 'omission' in options ? toString(options.omission) : omission;
24427      }
24428      string = toString(string);
24429
24430      var strLength = string.length;
24431      if (reHasComplexSymbol.test(string)) {
24432        var strSymbols = stringToArray(string);
24433        strLength = strSymbols.length;
24434      }
24435      if (length >= strLength) {
24436        return string;
24437      }
24438      var end = length - stringSize(omission);
24439      if (end < 1) {
24440        return omission;
24441      }
24442      var result = strSymbols
24443        ? strSymbols.slice(0, end).join('')
24444        : string.slice(0, end);
24445
24446      if (separator === undefined) {
24447        return result + omission;
24448      }
24449      if (strSymbols) {
24450        end += (result.length - end);
24451      }
24452      if (isRegExp(separator)) {
24453        if (string.slice(end).search(separator)) {
24454          var match,
24455              substring = result;
24456
24457          if (!separator.global) {
24458            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
24459          }
24460          separator.lastIndex = 0;
24461          while ((match = separator.exec(substring))) {
24462            var newEnd = match.index;
24463          }
24464          result = result.slice(0, newEnd === undefined ? end : newEnd);
24465        }
24466      } else if (string.indexOf(separator, end) != end) {
24467        var index = result.lastIndexOf(separator);
24468        if (index > -1) {
24469          result = result.slice(0, index);
24470        }
24471      }
24472      return result + omission;
24473    }
24474
24475    /**
24476     * The inverse of `_.escape`; this method converts the HTML entities
24477     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to
24478     * their corresponding characters.
24479     *
24480     * **Note:** No other HTML entities are unescaped. To unescape additional
24481     * HTML entities use a third-party library like [_he_](https://mths.be/he).
24482     *
24483     * @static
24484     * @memberOf _
24485     * @since 0.6.0
24486     * @category String
24487     * @param {string} [string=''] The string to unescape.
24488     * @returns {string} Returns the unescaped string.
24489     * @example
24490     *
24491     * _.unescape('fred, barney, &amp; pebbles');
24492     * // => 'fred, barney, & pebbles'
24493     */
24494    function unescape(string) {
vendor: 5,623 bytes, lines 24495-24682
24495      string = toString(string);
24496      return (string && reHasEscapedHtml.test(string))
24497        ? string.replace(reEscapedHtml, unescapeHtmlChar)
24498        : string;
24499    }
24500
24501    /**
24502     * Converts `string`, as space separated words, to upper case.
24503     *
24504     * @static
24505     * @memberOf _
24506     * @since 4.0.0
24507     * @category String
24508     * @param {string} [string=''] The string to convert.
24509     * @returns {string} Returns the upper cased string.
24510     * @example
24511     *
24512     * _.upperCase('--foo-bar');
24513     * // => 'FOO BAR'
24514     *
24515     * _.upperCase('fooBar');
24516     * // => 'FOO BAR'
24517     *
24518     * _.upperCase('__foo_bar__');
24519     * // => 'FOO BAR'
24520     */
24521    var upperCase = createCompounder(function(result, word, index) {
24522      return result + (index ? ' ' : '') + word.toUpperCase();
24523    });
24524
24525    /**
24526     * Converts the first character of `string` to upper case.
24527     *
24528     * @static
24529     * @memberOf _
24530     * @since 4.0.0
24531     * @category String
24532     * @param {string} [string=''] The string to convert.
24533     * @returns {string} Returns the converted string.
24534     * @example
24535     *
24536     * _.upperFirst('fred');
24537     * // => 'Fred'
24538     *
24539     * _.upperFirst('FRED');
24540     * // => 'FRED'
24541     */
24542    var upperFirst = createCaseFirst('toUpperCase');
24543
24544    /**
24545     * Splits `string` into an array of its words.
24546     *
24547     * @static
24548     * @memberOf _
24549     * @since 3.0.0
24550     * @category String
24551     * @param {string} [string=''] The string to inspect.
24552     * @param {RegExp|string} [pattern] The pattern to match words.
24553     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24554     * @returns {Array} Returns the words of `string`.
24555     * @example
24556     *
24557     * _.words('fred, barney, & pebbles');
24558     * // => ['fred', 'barney', 'pebbles']
24559     *
24560     * _.words('fred, barney, & pebbles', /[^, ]+/g);
24561     * // => ['fred', 'barney', '&', 'pebbles']
24562     */
24563    function words(string, pattern, guard) {
24564      string = toString(string);
24565      pattern = guard ? undefined : pattern;
24566
24567      if (pattern === undefined) {
24568        pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
24569      }
24570      return string.match(pattern) || [];
24571    }
24572
24573    /*------------------------------------------------------------------------*/
24574
24575    /**
24576     * Attempts to invoke `func`, returning either the result or the caught error
24577     * object. Any additional arguments are provided to `func` when it's invoked.
24578     *
24579     * @static
24580     * @memberOf _
24581     * @since 3.0.0
24582     * @category Util
24583     * @param {Function} func The function to attempt.
24584     * @param {...*} [args] The arguments to invoke `func` with.
24585     * @returns {*} Returns the `func` result or error object.
24586     * @example
24587     *
24588     * // Avoid throwing errors for invalid selectors.
24589     * var elements = _.attempt(function(selector) {
24590     *   return document.querySelectorAll(selector);
24591     * }, '>_>');
24592     *
24593     * if (_.isError(elements)) {
24594     *   elements = [];
24595     * }
24596     */
24597    var attempt = rest(function(func, args) {
24598      try {
24599        return apply(func, undefined, args);
24600      } catch (e) {
24601        return isError(e) ? e : new Error(e);
24602      }
24603    });
24604
24605    /**
24606     * Binds methods of an object to the object itself, overwriting the existing
24607     * method.
24608     *
24609     * **Note:** This method doesn't set the "length" property of bound functions.
24610     *
24611     * @static
24612     * @since 0.1.0
24613     * @memberOf _
24614     * @category Util
24615     * @param {Object} object The object to bind and assign the bound methods to.
24616     * @param {...(string|string[])} methodNames The object method names to bind,
24617     *  specified individually or in arrays.
24618     * @returns {Object} Returns `object`.
24619     * @example
24620     *
24621     * var view = {
24622     *   'label': 'docs',
24623     *   'onClick': function() {
24624     *     console.log('clicked ' + this.label);
24625     *   }
24626     * };
24627     *
24628     * _.bindAll(view, 'onClick');
24629     * jQuery(element).on('click', view.onClick);
24630     * // => Logs 'clicked docs' when clicked.
24631     */
24632    var bindAll = rest(function(object, methodNames) {
24633      arrayEach(baseFlatten(methodNames, 1), function(key) {
24634        object[key] = bind(object[key], object);
24635      });
24636      return object;
24637    });
24638
24639    /**
24640     * Creates a function that iterates over `pairs` invoking the corresponding
24641     * function of the first predicate to return truthy. The predicate-function
24642     * pairs are invoked with the `this` binding and arguments of the created
24643     * function.
24644     *
24645     * @static
24646     * @memberOf _
24647     * @since 4.0.0
24648     * @category Util
24649     * @param {Array} pairs The predicate-function pairs.
24650     * @returns {Function} Returns the new function.
24651     * @example
24652     *
24653     * var func = _.cond([
24654     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
24655     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
24656     *   [_.constant(true),                _.constant('no match')]
24657     * ]);
24658     *
24659     * func({ 'a': 1, 'b': 2 });
24660     * // => 'matches A'
24661     *
24662     * func({ 'a': 0, 'b': 1 });
24663     * // => 'matches B'
24664     *
24665     * func({ 'a': '1', 'b': '2' });
24666     * // => 'no match'
24667     */
24668    function cond(pairs) {
24669      var length = pairs ? pairs.length : 0,
24670          toIteratee = getIteratee();
24671
24672      pairs = !length ? [] : arrayMap(pairs, function(pair) {
24673        if (typeof pair[1] != 'function') {
24674          throw new TypeError(FUNC_ERROR_TEXT);
24675        }
24676        return [toIteratee(pair[0]), pair[1]];
24677      });
24678
24679      return rest(function(args) {
24680        var index = -1;
24681        while (++index < length) {
24682          var pair = pairs[index];
24683          if (apply(pair[0], this, args)) {
24684            return apply(pair[1], this, args);
24685          }
24686        }
24687      });
24688    }
24689
24690    /**
24691     * Creates a function that invokes the predicate properties of `source` with
24692     * the corresponding property values of a given object, returning `true` if
24693     * all predicates return truthy, else `false`.
24694     *
24695     * @static
24696     * @memberOf _
24697     * @since 4.0.0
24698     * @category Util
24699     * @param {Object} source The object of property predicates to conform to.
24700     * @returns {Function} Returns the new function.
24701     * @example
24702     *
24703     * var users = [
24704     *   { 'user': 'barney', 'age': 36 },
24705     *   { 'user': 'fred',   'age': 40 }
24706     * ];
24707     *
24708     * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
24709     * // => [{ 'user': 'fred', 'age': 40 }]
24710     */
24711    function conforms(source) {
24712      return baseConforms(baseClone(source, true));
24713    }
24714
24715    /**
24716     * Creates a function that returns `value`.
24717     *
24718     * @static
24719     * @memberOf _
24720     * @since 2.4.0
24721     * @category Util
24722     * @param {*} value The value to return from the new function.
24723     * @returns {Function} Returns the new function.
24724     * @example
24725     *
24726     * var object = { 'user': 'fred' };
24727     * var getter = _.constant(object);
24728     *
24729     * getter() === object;
24730     * // => true
24731     */
24732    function constant(value) {
24733      return function() {
24734        return value;
24735      };
24736    }
24737
24738    /**
24739     * Creates a function that returns the result of invoking the given functions
24740     * with the `this` binding of the created function, where each successive
24741     * invocation is supplied the return value of the previous.
24742     *
24743     * @static
24744     * @memberOf _
24745     * @since 3.0.0
24746     * @category Util
24747     * @param {...(Function|Function[])} [funcs] Functions to invoke.
24748     * @returns {Function} Returns the new function.
24749     * @example
24750     *
24751     * function square(n) {
24752     *   return n * n;
24753     * }
24754     *
24755     * var addSquare = _.flow(_.add, square);
24756     * addSquare(1, 2);
24757     * // => 9
24758     */
24759    var flow = createFlow();
24760
24761    /**
24762     * This method is like `_.flow` except that it creates a function that
24763     * invokes the given functions from right to left.
24764     *
24765     * @static
24766     * @since 0.1.0
24767     * @memberOf _
24768     * @category Util
24769     * @param {...(Function|Function[])} [funcs] Functions to invoke.
24770     * @returns {Function} Returns the new function.
24771     * @example
24772     *
24773     * function square(n) {
24774     *   return n * n;
24775     * }
24776     *
24777     * var addSquare = _.flowRight(square, _.add);
24778     * addSquare(1, 2);
24779     * // => 9
24780     */
24781    var flowRight = createFlow(true);
24782
24783    /**
24784     * This method returns the first argument given to it.
24785     *
24786     * @static
24787     * @since 0.1.0
24788     * @memberOf _
24789     * @category Util
24790     * @param {*} value Any value.
24791     * @returns {*} Returns `value`.
24792     * @example
24793     *
24794     * var object = { 'user': 'fred' };
24795     *
24796     * _.identity(object) === object;
24797     * // => true
24798     */
24799    function identity(value) {
24800      return value;
24801    }
24802
24803    /**
24804     * Creates a function that invokes `func` with the arguments of the created
24805     * function. If `func` is a property name, the created function returns the
24806     * property value for a given element. If `func` is an array or object, the
24807     * created function returns `true` for elements that contain the equivalent
24808     * source properties, otherwise it returns `false`.
24809     *
24810     * @static
24811     * @since 4.0.0
24812     * @memberOf _
24813     * @category Util
24814     * @param {*} [func=_.identity] The value to convert to a callback.
24815     * @returns {Function} Returns the callback.
24816     * @example
24817     *
24818     * var users = [
24819     *   { 'user': 'barney', 'age': 36, 'active': true },
24820     *   { 'user': 'fred',   'age': 40, 'active': false }
24821     * ];
24822     *
24823     * // The `_.matches` iteratee shorthand.
24824     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
24825     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
24826     *
24827     * // The `_.matchesProperty` iteratee shorthand.
24828     * _.filter(users, _.iteratee(['user', 'fred']));
24829     * // => [{ 'user': 'fred', 'age': 40 }]
24830     *
24831     * // The `_.property` iteratee shorthand.
24832     * _.map(users, _.iteratee('user'));
24833     * // => ['barney', 'fred']
24834     *
24835     * // Create custom iteratee shorthands.
24836     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
24837     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
24838     *     return func.test(string);
24839     *   };
24840     * });
24841     *
24842     * _.filter(['abc', 'def'], /ef/);
24843     * // => ['def']
24844     */
24845    function iteratee(func) {
24846      return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
24847    }
24848
24849    /**
24850     * Creates a function that performs a partial deep comparison between a given
24851     * object and `source`, returning `true` if the given object has equivalent
24852     * property values, else `false`. The created function is equivalent to
24853     * `_.isMatch` with a `source` partially applied.
24854     *
24855     * **Note:** This method supports comparing the same values as `_.isEqual`.
24856     *
24857     * @static
24858     * @memberOf _
24859     * @since 3.0.0
24860     * @category Util
24861     * @param {Object} source The object of property values to match.
24862     * @returns {Function} Returns the new function.
24863     * @example
24864     *
24865     * var users = [
24866     *   { 'user': 'barney', 'age': 36, 'active': true },
24867     *   { 'user': 'fred',   'age': 40, 'active': false }
24868     * ];
24869     *
24870     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
24871     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
24872     */
24873    function matches(source) {
24874      return baseMatches(baseClone(source, true));
24875    }
24876
24877    /**
24878     * Creates a function that performs a partial deep comparison between the
24879     * value at `path` of a given object to `srcValue`, returning `true` if the
24880     * object value is equivalent, else `false`.
24881     *
24882     * **Note:** This method supports comparing the same values as `_.isEqual`.
24883     *
24884     * @static
24885     * @memberOf _
24886     * @since 3.2.0
24887     * @category Util
24888     * @param {Array|string} path The path of the property to get.
24889     * @param {*} srcValue The value to match.
24890     * @returns {Function} Returns the new function.
24891     * @example
24892     *
24893     * var users = [
24894     *   { 'user': 'barney' },
24895     *   { 'user': 'fred' }
24896     * ];
24897     *
24898     * _.find(users, _.matchesProperty('user', 'fred'));
24899     * // => { 'user': 'fred' }
24900     */
24901    function matchesProperty(path, srcValue) {
24902      return baseMatchesProperty(path, baseClone(srcValue, true));
24903    }
24904
24905    /**
24906     * Creates a function that invokes the method at `path` of a given object.
24907     * Any additional arguments are provided to the invoked method.
24908     *
24909     * @static
24910     * @memberOf _
24911     * @since 3.7.0
24912     * @category Util
24913     * @param {Array|string} path The path of the method to invoke.
24914     * @param {...*} [args] The arguments to invoke the method with.
24915     * @returns {Function} Returns the new function.
24916     * @example
24917     *
24918     * var objects = [
24919     *   { 'a': { 'b': _.constant(2) } },
24920     *   { 'a': { 'b': _.constant(1) } }
24921     * ];
24922     *
24923     * _.map(objects, _.method('a.b'));
24924     * // => [2, 1]
24925     *
24926     * _.map(objects, _.method(['a', 'b']));
24927     * // => [2, 1]
24928     */
24929    var method = rest(function(path, args) {
24930      return function(object) {
24931        return baseInvoke(object, path, args);
24932      };
24933    });
24934
24935    /**
24936     * The opposite of `_.method`; this method creates a function that invokes
24937     * the method at a given path of `object`. Any additional arguments are
24938     * provided to the invoked method.
24939     *
24940     * @static
24941     * @memberOf _
24942     * @since 3.7.0
24943     * @category Util
24944     * @param {Object} object The object to query.
24945     * @param {...*} [args] The arguments to invoke the method with.
24946     * @returns {Function} Returns the new function.
24947     * @example
24948     *
24949     * var array = _.times(3, _.constant),
24950     *     object = { 'a': array, 'b': array, 'c': array };
24951     *
24952     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
24953     * // => [2, 0]
24954     *
24955     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
24956     * // => [2, 0]
24957     */
24958    var methodOf = rest(function(object, args) {
24959      return function(path) {
24960        return baseInvoke(object, path, args);
24961      };
24962    });
24963
24964    /**
24965     * Adds all own enumerable string keyed function properties of a source
24966     * object to the destination object. If `object` is a function, then methods
24967     * are added to its prototype as well.
24968     *
24969     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
24970     * avoid conflicts caused by modifying the original.
24971     *
24972     * @static
24973     * @since 0.1.0
24974     * @memberOf _
24975     * @category Util
24976     * @param {Function|Object} [object=lodash] The destination object.
24977     * @param {Object} source The object of functions to add.
24978     * @param {Object} [options={}] The options object.
24979     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
24980     * @returns {Function|Object} Returns `object`.
24981     * @example
24982     *
24983     * function vowels(string) {
24984     *   return _.filter(string, function(v) {
24985     *     return /[aeiou]/i.test(v);
24986     *   });
24987     * }
24988     *
24989     * _.mixin({ 'vowels': vowels });
24990     * _.vowels('fred');
24991     * // => ['e']
24992     *
24993     * _('fred').vowels().value();
24994     * // => ['e']
24995     *
24996     * _.mixin({ 'vowels': vowels }, { 'chain': false });
24997     * _('fred').vowels();
24998     * // => ['e']
24999     */
25000    function mixin(object, source, options) {
25001      var props = keys(source),
25002          methodNames = baseFunctions(source, props);
25003
25004      if (options == null &&
25005          !(isObject(source) && (methodNames.length || !props.length))) {
25006        options = source;
25007        source = object;
25008        object = this;
25009        methodNames = baseFunctions(source, keys(source));
25010      }
25011      var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
25012          isFunc = isFunction(object);
25013
25014      arrayEach(methodNames, function(methodName) {
25015        var func = source[methodName];
25016        object[methodName] = func;
25017        if (isFunc) {
25018          object.prototype[methodName] = function() {
25019            var chainAll = this.__chain__;
25020            if (chain || chainAll) {
25021              var result = object(this.__wrapped__),
25022                  actions = result.__actions__ = copyArray(this.__actions__);
25023
25024              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
25025              result.__chain__ = chainAll;
25026              return result;
25027            }
25028            return func.apply(object, arrayPush([this.value()], arguments));
25029          };
25030        }
25031      });
25032
25033      return object;
25034    }
25035
25036    /**
25037     * Reverts the `_` variable to its previous value and returns a reference to
25038     * the `lodash` function.
25039     *
25040     * @static
25041     * @since 0.1.0
25042     * @memberOf _
25043     * @category Util
25044     * @returns {Function} Returns the `lodash` function.
25045     * @example
25046     *
25047     * var lodash = _.noConflict();
25048     */
25049    function noConflict() {
25050      if (root._ === this) {
25051        root._ = oldDash;
25052      }
25053      return this;
25054    }
25055
25056    /**
25057     * A no-operation function that returns `undefined` regardless of the
25058     * arguments it receives.
25059     *
25060     * @static
25061     * @memberOf _
25062     * @since 2.3.0
25063     * @category Util
25064     * @example
25065     *
25066     * var object = { 'user': 'fred' };
25067     *
25068     * _.noop(object) === undefined;
25069     * // => true
25070     */
25071    function noop() {
25072      // No operation performed.
25073    }
25074
25075    /**
25076     * Creates a function that returns its nth argument.
25077     *
25078     * @static
25079     * @memberOf _
25080     * @since 4.0.0
25081     * @category Util
25082     * @param {number} [n=0] The index of the argument to return.
25083     * @returns {Function} Returns the new function.
25084     * @example
25085     *
25086     * var func = _.nthArg(1);
25087     *
25088     * func('a', 'b', 'c');
25089     * // => 'b'
25090     */
25091    function nthArg(n) {
25092      n = toInteger(n);
25093      return function() {
25094        return arguments[n];
25095      };
25096    }
25097
25098    /**
25099     * Creates a function that invokes `iteratees` with the arguments it receives
25100     * and returns their results.
25101     *
25102     * @static
25103     * @memberOf _
25104     * @since 4.0.0
25105     * @category Util
25106     * @param {...(Function|Function[])} iteratees The iteratees to invoke.
25107     * @returns {Function} Returns the new function.
25108     * @example
25109     *
25110     * var func = _.over(Math.max, Math.min);
25111     *
25112     * func(1, 2, 3, 4);
25113     * // => [4, 1]
25114     */
25115    var over = createOver(arrayMap);
25116
25117    /**
25118     * Creates a function that checks if **all** of the `predicates` return
25119     * truthy when invoked with the arguments it receives.
25120     *
25121     * @static
25122     * @memberOf _
25123     * @since 4.0.0
25124     * @category Util
25125     * @param {...(Function|Function[])} predicates The predicates to check.
25126     * @returns {Function} Returns the new function.
25127     * @example
25128     *
25129     * var func = _.overEvery(Boolean, isFinite);
25130     *
25131     * func('1');
25132     * // => true
25133     *
25134     * func(null);
25135     * // => false
25136     *
25137     * func(NaN);
25138     * // => false
25139     */
25140    var overEvery = createOver(arrayEvery);
25141
25142    /**
25143     * Creates a function that checks if **any** of the `predicates` return
25144     * truthy when invoked with the arguments it receives.
25145     *
25146     * @static
25147     * @memberOf _
25148     * @since 4.0.0
25149     * @category Util
25150     * @param {...(Function|Function[])} predicates The predicates to check.
25151     * @returns {Function} Returns the new function.
25152     * @example
25153     *
25154     * var func = _.overSome(Boolean, isFinite);
25155     *
25156     * func('1');
25157     * // => true
25158     *
25159     * func(null);
25160     * // => true
25161     *
25162     * func(NaN);
25163     * // => false
25164     */
25165    var overSome = createOver(arraySome);
25166
25167    /**
25168     * Creates a function that returns the value at `path` of a given object.
25169     *
25170     * @static
25171     * @memberOf _
25172     * @since 2.4.0
25173     * @category Util
25174     * @param {Array|string} path The path of the property to get.
25175     * @returns {Function} Returns the new function.
25176     * @example
25177     *
25178     * var objects = [
25179     *   { 'a': { 'b': 2 } },
25180     *   { 'a': { 'b': 1 } }
25181     * ];
25182     *
25183     * _.map(objects, _.property('a.b'));
25184     * // => [2, 1]
25185     *
25186     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
25187     * // => [1, 2]
25188     */
25189    function property(path) {
25190      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
25191    }
25192
25193    /**
25194     * The opposite of `_.property`; this method creates a function that returns
25195     * the value at a given path of `object`.
25196     *
25197     * @static
25198     * @memberOf _
25199     * @since 3.0.0
25200     * @category Util
25201     * @param {Object} object The object to query.
25202     * @returns {Function} Returns the new function.
25203     * @example
25204     *
25205     * var array = [0, 1, 2],
25206     *     object = { 'a': array, 'b': array, 'c': array };
25207     *
25208     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
25209     * // => [2, 0]
25210     *
25211     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
25212     * // => [2, 0]
25213     */
25214    function propertyOf(object) {
25215      return function(path) {
25216        return object == null ? undefined : baseGet(object, path);
25217      };
25218    }
25219
25220    /**
25221     * Creates an array of numbers (positive and/or negative) progressing from
25222     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
25223     * `start` is specified without an `end` or `step`. If `end` is not specified,
25224     * it's set to `start` with `start` then set to `0`.
25225     *
25226     * **Note:** JavaScript follows the IEEE-754 standard for resolving
25227     * floating-point values which can produce unexpected results.
25228     *
25229     * @static
25230     * @since 0.1.0
25231     * @memberOf _
25232     * @category Util
25233     * @param {number} [start=0] The start of the range.
25234     * @param {number} end The end of the range.
25235     * @param {number} [step=1] The value to increment or decrement by.
25236     * @returns {Array} Returns the new array of numbers.
25237     * @example
25238     *
25239     * _.range(4);
25240     * // => [0, 1, 2, 3]
25241     *
25242     * _.range(-4);
25243     * // => [0, -1, -2, -3]
25244     *
25245     * _.range(1, 5);
25246     * // => [1, 2, 3, 4]
25247     *
25248     * _.range(0, 20, 5);
25249     * // => [0, 5, 10, 15]
25250     *
25251     * _.range(0, -4, -1);
25252     * // => [0, -1, -2, -3]
25253     *
25254     * _.range(1, 4, 0);
25255     * // => [1, 1, 1]
25256     *
25257     * _.range(0);
25258     * // => []
25259     */
25260    var range = createRange();
25261
25262    /**
25263     * This method is like `_.range` except that it populates values in
25264     * descending order.
25265     *
25266     * @static
25267     * @memberOf _
25268     * @since 4.0.0
25269     * @category Util
25270     * @param {number} [start=0] The start of the range.
25271     * @param {number} end The end of the range.
25272     * @param {number} [step=1] The value to increment or decrement by.
25273     * @returns {Array} Returns the new array of numbers.
25274     * @example
25275     *
25276     * _.rangeRight(4);
25277     * // => [3, 2, 1, 0]
25278     *
25279     * _.rangeRight(-4);
25280     * // => [-3, -2, -1, 0]
25281     *
25282     * _.rangeRight(1, 5);
25283     * // => [4, 3, 2, 1]
25284     *
25285     * _.rangeRight(0, 20, 5);
25286     * // => [15, 10, 5, 0]
25287     *
25288     * _.rangeRight(0, -4, -1);
25289     * // => [-3, -2, -1, 0]
25290     *
25291     * _.rangeRight(1, 4, 0);
25292     * // => [1, 1, 1]
25293     *
25294     * _.rangeRight(0);
25295     * // => []
25296     */
25297    var rangeRight = createRange(true);
25298
25299    /**
25300     * Invokes the iteratee `n` times, returning an array of the results of
25301     * each invocation. The iteratee is invoked with one argument; (index).
25302     *
25303     * @static
25304     * @since 0.1.0
25305     * @memberOf _
25306     * @category Util
25307     * @param {number} n The number of times to invoke `iteratee`.
25308     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25309     * @returns {Array} Returns the array of results.
25310     * @example
25311     *
25312     * _.times(3, String);
25313     * // => ['0', '1', '2']
25314     *
25315     *  _.times(4, _.constant(true));
25316     * // => [true, true, true, true]
25317     */
25318    function times(n, iteratee) {
25319      n = toInteger(n);
25320      if (n < 1 || n > MAX_SAFE_INTEGER) {
25321        return [];
25322      }
25323      var index = MAX_ARRAY_LENGTH,
25324          length = nativeMin(n, MAX_ARRAY_LENGTH);
25325
25326      iteratee = getIteratee(iteratee);
25327      n -= MAX_ARRAY_LENGTH;
25328
25329      var result = baseTimes(length, iteratee);
25330      while (++index < n) {
25331        iteratee(index);
25332      }
25333      return result;
25334    }
25335
25336    /**
25337     * Converts `value` to a property path array.
25338     *
25339     * @static
25340     * @memberOf _
25341     * @since 4.0.0
25342     * @category Util
25343     * @param {*} value The value to convert.
25344     * @returns {Array} Returns the new property path array.
25345     * @example
25346     *
25347     * _.toPath('a.b.c');
25348     * // => ['a', 'b', 'c']
25349     *
25350     * _.toPath('a[0].b.c');
25351     * // => ['a', '0', 'b', 'c']
25352     *
25353     * var path = ['a', 'b', 'c'],
25354     *     newPath = _.toPath(path);
25355     *
25356     * console.log(newPath);
25357     * // => ['a', 'b', 'c']
25358     *
25359     * console.log(path === newPath);
25360     * // => false
25361     */
25362    function toPath(value) {
25363      if (isArray(value)) {
25364        return arrayMap(value, baseCastKey);
25365      }
25366      return isSymbol(value) ? [value] : copyArray(stringToPath(value));
25367    }
25368
25369    /**
25370     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
25371     *
25372     * @static
25373     * @since 0.1.0
25374     * @memberOf _
25375     * @category Util
25376     * @param {string} [prefix=''] The value to prefix the ID with.
25377     * @returns {string} Returns the unique ID.
25378     * @example
25379     *
25380     * _.uniqueId('contact_');
25381     * // => 'contact_104'
25382     *
25383     * _.uniqueId();
25384     * // => '105'
25385     */
25386    function uniqueId(prefix) {
25387      var id = ++idCounter;
25388      return toString(prefix) + id;
25389    }
25390
25391    /*------------------------------------------------------------------------*/
25392
25393    /**
25394     * Adds two numbers.
25395     *
25396     * @static
25397     * @memberOf _
25398     * @since 3.4.0
25399     * @category Math
25400     * @param {number} augend The first number in an addition.
25401     * @param {number} addend The second number in an addition.
25402     * @returns {number} Returns the total.
25403     * @example
25404     *
25405     * _.add(6, 4);
25406     * // => 10
25407     */
25408    var add = createMathOperation(function(augend, addend) {
25409      return augend + addend;
25410    });
25411
25412    /**
25413     * Computes `number` rounded up to `precision`.
25414     *
25415     * @static
25416     * @memberOf _
25417     * @since 3.10.0
25418     * @category Math
25419     * @param {number} number The number to round up.
25420     * @param {number} [precision=0] The precision to round up to.
25421     * @returns {number} Returns the rounded up number.
25422     * @example
25423     *
25424     * _.ceil(4.006);
25425     * // => 5
25426     *
25427     * _.ceil(6.004, 2);
25428     * // => 6.01
25429     *
25430     * _.ceil(6040, -2);
25431     * // => 6100
25432     */
25433    var ceil = createRound('ceil');
25434
25435    /**
25436     * Divide two numbers.
25437     *
25438     * @static
25439     * @memberOf _
25440     * @since 4.7.0
25441     * @category Math
25442     * @param {number} dividend The first number in a division.
25443     * @param {number} divisor The second number in a division.
25444     * @returns {number} Returns the quotient.
25445     * @example
25446     *
25447     * _.divide(6, 4);
25448     * // => 1.5
25449     */
25450    var divide = createMathOperation(function(dividend, divisor) {
25451      return dividend / divisor;
25452    });
25453
25454    /**
25455     * Computes `number` rounded down to `precision`.
25456     *
25457     * @static
25458     * @memberOf _
25459     * @since 3.10.0
25460     * @category Math
25461     * @param {number} number The number to round down.
25462     * @param {number} [precision=0] The precision to round down to.
25463     * @returns {number} Returns the rounded down number.
25464     * @example
25465     *
25466     * _.floor(4.006);
25467     * // => 4
25468     *
25469     * _.floor(0.046, 2);
25470     * // => 0.04
25471     *
25472     * _.floor(4060, -2);
25473     * // => 4000
25474     */
25475    var floor = createRound('floor');
25476
25477    /**
25478     * Computes the maximum value of `array`. If `array` is empty or falsey,
25479     * `undefined` is returned.
25480     *
25481     * @static
25482     * @since 0.1.0
25483     * @memberOf _
25484     * @category Math
25485     * @param {Array} array The array to iterate over.
25486     * @returns {*} Returns the maximum value.
25487     * @example
25488     *
25489     * _.max([4, 2, 8, 6]);
25490     * // => 8
25491     *
25492     * _.max([]);
25493     * // => undefined
25494     */
25495    function max(array) {
25496      return (array && array.length)
25497        ? baseExtremum(array, identity, gt)
25498        : undefined;
25499    }
25500
25501    /**
25502     * This method is like `_.max` except that it accepts `iteratee` which is
25503     * invoked for each element in `array` to generate the criterion by which
25504     * the value is ranked. The iteratee is invoked with one argument: (value).
25505     *
25506     * @static
25507     * @memberOf _
25508     * @since 4.0.0
25509     * @category Math
25510     * @param {Array} array The array to iterate over.
25511     * @param {Array|Function|Object|string} [iteratee=_.identity]
25512     *  The iteratee invoked per element.
25513     * @returns {*} Returns the maximum value.
25514     * @example
25515     *
25516     * var objects = [{ 'n': 1 }, { 'n': 2 }];
25517     *
25518     * _.maxBy(objects, function(o) { return o.n; });
25519     * // => { 'n': 2 }
25520     *
25521     * // The `_.property` iteratee shorthand.
25522     * _.maxBy(objects, 'n');
25523     * // => { 'n': 2 }
25524     */
25525    function maxBy(array, iteratee) {
25526      return (array && array.length)
25527        ? baseExtremum(array, getIteratee(iteratee), gt)
25528        : undefined;
25529    }
25530
25531    /**
25532     * Computes the mean of the values in `array`.
25533     *
25534     * @static
25535     * @memberOf _
25536     * @since 4.0.0
25537     * @category Math
25538     * @param {Array} array The array to iterate over.
25539     * @returns {number} Returns the mean.
25540     * @example
25541     *
25542     * _.mean([4, 2, 8, 6]);
25543     * // => 5
25544     */
25545    function mean(array) {
25546      return baseMean(array, identity);
25547    }
25548
25549    /**
25550     * This method is like `_.mean` except that it accepts `iteratee` which is
25551     * invoked for each element in `array` to generate the value to be averaged.
25552     * The iteratee is invoked with one argument: (value).
25553     *
25554     * @static
25555     * @memberOf _
25556     * @since 4.7.0
25557     * @category Math
25558     * @param {Array} array The array to iterate over.
25559     * @param {Array|Function|Object|string} [iteratee=_.identity]
25560     *  The iteratee invoked per element.
25561     * @returns {number} Returns the mean.
25562     * @example
25563     *
25564     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
25565     *
25566     * _.meanBy(objects, function(o) { return o.n; });
25567     * // => 5
25568     *
25569     * // The `_.property` iteratee shorthand.
25570     * _.meanBy(objects, 'n');
25571     * // => 5
25572     */
25573    function meanBy(array, iteratee) {
25574      return baseMean(array, getIteratee(iteratee));
25575    }
25576
25577    /**
25578     * Computes the minimum value of `array`. If `array` is empty or falsey,
25579     * `undefined` is returned.
25580     *
25581     * @static
25582     * @since 0.1.0
25583     * @memberOf _
25584     * @category Math
25585     * @param {Array} array The array to iterate over.
25586     * @returns {*} Returns the minimum value.
25587     * @example
25588     *
25589     * _.min([4, 2, 8, 6]);
25590     * // => 2
25591     *
25592     * _.min([]);
25593     * // => undefined
25594     */
25595    function min(array) {
25596      return (array && array.length)
25597        ? baseExtremum(array, identity, lt)
25598        : undefined;
25599    }
25600
25601    /**
25602     * This method is like `_.min` except that it accepts `iteratee` which is
25603     * invoked for each element in `array` to generate the criterion by which
25604     * the value is ranked. The iteratee is invoked with one argument: (value).
25605     *
25606     * @static
25607     * @memberOf _
25608     * @since 4.0.0
25609     * @category Math
25610     * @param {Array} array The array to iterate over.
25611     * @param {Array|Function|Object|string} [iteratee=_.identity]
25612     *  The iteratee invoked per element.
25613     * @returns {*} Returns the minimum value.
25614     * @example
25615     *
25616     * var objects = [{ 'n': 1 }, { 'n': 2 }];
25617     *
25618     * _.minBy(objects, function(o) { return o.n; });
25619     * // => { 'n': 1 }
25620     *
25621     * // The `_.property` iteratee shorthand.
25622     * _.minBy(objects, 'n');
25623     * // => { 'n': 1 }
25624     */
25625    function minBy(array, iteratee) {
25626      return (array && array.length)
25627        ? baseExtremum(array, getIteratee(iteratee), lt)
25628        : undefined;
25629    }
25630
25631    /**
25632     * Multiply two numbers.
25633     *
25634     * @static
25635     * @memberOf _
25636     * @since 4.7.0
25637     * @category Math
25638     * @param {number} multiplier The first number in a multiplication.
25639     * @param {number} multiplicand The second number in a multiplication.
25640     * @returns {number} Returns the product.
25641     * @example
25642     *
25643     * _.multiply(6, 4);
25644     * // => 24
25645     */
25646    var multiply = createMathOperation(function(multiplier, multiplicand) {
25647      return multiplier * multiplicand;
25648    });
25649
25650    /**
25651     * Computes `number` rounded to `precision`.
25652     *
25653     * @static
25654     * @memberOf _
25655     * @since 3.10.0
25656     * @category Math
25657     * @param {number} number The number to round.
25658     * @param {number} [precision=0] The precision to round to.
25659     * @returns {number} Returns the rounded number.
25660     * @example
25661     *
25662     * _.round(4.006);
25663     * // => 4
25664     *
25665     * _.round(4.006, 2);
25666     * // => 4.01
25667     *
25668     * _.round(4060, -2);
25669     * // => 4100
25670     */
25671    var round = createRound('round');
25672
25673    /**
25674     * Subtract two numbers.
25675     *
25676     * @static
25677     * @memberOf _
25678     * @since 4.0.0
25679     * @category Math
25680     * @param {number} minuend The first number in a subtraction.
25681     * @param {number} subtrahend The second number in a subtraction.
25682     * @returns {number} Returns the difference.
25683     * @example
25684     *
25685     * _.subtract(6, 4);
25686     * // => 2
25687     */
25688    var subtract = createMathOperation(function(minuend, subtrahend) {
25689      return minuend - subtrahend;
25690    });
25691
25692    /**
25693     * Computes the sum of the values in `array`.
25694     *
25695     * @static
25696     * @memberOf _
25697     * @since 3.4.0
25698     * @category Math
25699     * @param {Array} array The array to iterate over.
25700     * @returns {number} Returns the sum.
25701     * @example
25702     *
25703     * _.sum([4, 2, 8, 6]);
25704     * // => 20
25705     */
25706    function sum(array) {
25707      return (array && array.length)
25708        ? baseSum(array, identity)
25709        : 0;
25710    }
25711
25712    /**
25713     * This method is like `_.sum` except that it accepts `iteratee` which is
25714     * invoked for each element in `array` to generate the value to be summed.
25715     * The iteratee is invoked with one argument: (value).
25716     *
25717     * @static
25718     * @memberOf _
25719     * @since 4.0.0
25720     * @category Math
25721     * @param {Array} array The array to iterate over.
25722     * @param {Array|Function|Object|string} [iteratee=_.identity]
25723     *  The iteratee invoked per element.
25724     * @returns {number} Returns the sum.
25725     * @example
25726     *
25727     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
25728     *
25729     * _.sumBy(objects, function(o) { return o.n; });
25730     * // => 20
25731     *
25732     * // The `_.property` iteratee shorthand.
25733     * _.sumBy(objects, 'n');
25734     * // => 20
25735     */
25736    function sumBy(array, iteratee) {
25737      return (array && array.length)
25738        ? baseSum(array, getIteratee(iteratee))
25739        : 0;
25740    }
25741
25742    /*------------------------------------------------------------------------*/
25743
25744    // Add methods that return wrapped values in chain sequences.
25745    lodash.after = after;
25746    lodash.ary = ary;
25747    lodash.assign = assign;
25748    lodash.assignIn = assignIn;
25749    lodash.assignInWith = assignInWith;
25750    lodash.assignWith = assignWith;
25751    lodash.at = at;
25752    lodash.before = before;
25753    lodash.bind = bind;
25754    lodash.bindAll = bindAll;
25755    lodash.bindKey = bindKey;
25756    lodash.castArray = castArray;
25757    lodash.chain = chain;
25758    lodash.chunk = chunk;
25759    lodash.compact = compact;
25760    lodash.concat = concat;
25761    lodash.cond = cond;
25762    lodash.conforms = conforms;
25763    lodash.constant = constant;
25764    lodash.countBy = countBy;
25765    lodash.create = create;
25766    lodash.curry = curry;
25767    lodash.curryRight = curryRight;
25768    lodash.debounce = debounce;
25769    lodash.defaults = defaults;
25770    lodash.defaultsDeep = defaultsDeep;
25771    lodash.defer = defer;
25772    lodash.delay = delay;
25773    lodash.difference = difference;
25774    lodash.differenceBy = differenceBy;
25775    lodash.differenceWith = differenceWith;
25776    lodash.drop = drop;
25777    lodash.dropRight = dropRight;
25778    lodash.dropRightWhile = dropRightWhile;
25779    lodash.dropWhile = dropWhile;
25780    lodash.fill = fill;
25781    lodash.filter = filter;
25782    lodash.flatMap = flatMap;
25783    lodash.flatMapDeep = flatMapDeep;
25784    lodash.flatMapDepth = flatMapDepth;
25785    lodash.flatten = flatten;
25786    lodash.flattenDeep = flattenDeep;
25787    lodash.flattenDepth = flattenDepth;
25788    lodash.flip = flip;
25789    lodash.flow = flow;
25790    lodash.flowRight = flowRight;
25791    lodash.fromPairs = fromPairs;
25792    lodash.functions = functions;
25793    lodash.functionsIn = functionsIn;
25794    lodash.groupBy = groupBy;
25795    lodash.initial = initial;
25796    lodash.intersection = intersection;
25797    lodash.intersectionBy = intersectionBy;
25798    lodash.intersectionWith = intersectionWith;
25799    lodash.invert = invert;
25800    lodash.invertBy = invertBy;
25801    lodash.invokeMap = invokeMap;
25802    lodash.iteratee = iteratee;
25803    lodash.keyBy = keyBy;
25804    lodash.keys = keys;
25805    lodash.keysIn = keysIn;
25806    lodash.map = map;
25807    lodash.mapKeys = mapKeys;
25808    lodash.mapValues = mapValues;
25809    lodash.matches = matches;
25810    lodash.matchesProperty = matchesProperty;
25811    lodash.memoize = memoize;
25812    lodash.merge = merge;
25813    lodash.mergeWith = mergeWith;
25814    lodash.method = method;
25815    lodash.methodOf = methodOf;
25816    lodash.mixin = mixin;
25817    lodash.negate = negate;
25818    lodash.nthArg = nthArg;
25819    lodash.omit = omit;
25820    lodash.omitBy = omitBy;
25821    lodash.once = once;
25822    lodash.orderBy = orderBy;
25823    lodash.over = over;
25824    lodash.overArgs = overArgs;
25825    lodash.overEvery = overEvery;
vendor: 7,901 bytes, lines 25826-26083
25826    lodash.overSome = overSome;
25827    lodash.partial = partial;
25828    lodash.partialRight = partialRight;
25829    lodash.partition = partition;
25830    lodash.pick = pick;
25831    lodash.pickBy = pickBy;
25832    lodash.property = property;
25833    lodash.propertyOf = propertyOf;
25834    lodash.pull = pull;
25835    lodash.pullAll = pullAll;
25836    lodash.pullAllBy = pullAllBy;
25837    lodash.pullAllWith = pullAllWith;
25838    lodash.pullAt = pullAt;
25839    lodash.range = range;
25840    lodash.rangeRight = rangeRight;
25841    lodash.rearg = rearg;
25842    lodash.reject = reject;
25843    lodash.remove = remove;
25844    lodash.rest = rest;
25845    lodash.reverse = reverse;
25846    lodash.sampleSize = sampleSize;
25847    lodash.set = set;
25848    lodash.setWith = setWith;
25849    lodash.shuffle = shuffle;
25850    lodash.slice = slice;
25851    lodash.sortBy = sortBy;
25852    lodash.sortedUniq = sortedUniq;
25853    lodash.sortedUniqBy = sortedUniqBy;
25854    lodash.split = split;
25855    lodash.spread = spread;
25856    lodash.tail = tail;
25857    lodash.take = take;
25858    lodash.takeRight = takeRight;
25859    lodash.takeRightWhile = takeRightWhile;
25860    lodash.takeWhile = takeWhile;
25861    lodash.tap = tap;
25862    lodash.throttle = throttle;
25863    lodash.thru = thru;
25864    lodash.toArray = toArray;
25865    lodash.toPairs = toPairs;
25866    lodash.toPairsIn = toPairsIn;
25867    lodash.toPath = toPath;
25868    lodash.toPlainObject = toPlainObject;
25869    lodash.transform = transform;
25870    lodash.unary = unary;
25871    lodash.union = union;
25872    lodash.unionBy = unionBy;
25873    lodash.unionWith = unionWith;
25874    lodash.uniq = uniq;
25875    lodash.uniqBy = uniqBy;
25876    lodash.uniqWith = uniqWith;
25877    lodash.unset = unset;
25878    lodash.unzip = unzip;
25879    lodash.unzipWith = unzipWith;
25880    lodash.update = update;
25881    lodash.updateWith = updateWith;
25882    lodash.values = values;
25883    lodash.valuesIn = valuesIn;
25884    lodash.without = without;
25885    lodash.words = words;
25886    lodash.wrap = wrap;
25887    lodash.xor = xor;
25888    lodash.xorBy = xorBy;
25889    lodash.xorWith = xorWith;
25890    lodash.zip = zip;
25891    lodash.zipObject = zipObject;
25892    lodash.zipObjectDeep = zipObjectDeep;
25893    lodash.zipWith = zipWith;
25894
25895    // Add aliases.
25896    lodash.entries = toPairs;
25897    lodash.entriesIn = toPairsIn;
25898    lodash.extend = assignIn;
25899    lodash.extendWith = assignInWith;
25900
25901    // Add methods to `lodash.prototype`.
25902    mixin(lodash, lodash);
25903
25904    /*------------------------------------------------------------------------*/
25905
25906    // Add methods that return unwrapped values in chain sequences.
25907    lodash.add = add;
25908    lodash.attempt = attempt;
25909    lodash.camelCase = camelCase;
25910    lodash.capitalize = capitalize;
25911    lodash.ceil = ceil;
25912    lodash.clamp = clamp;
25913    lodash.clone = clone;
25914    lodash.cloneDeep = cloneDeep;
25915    lodash.cloneDeepWith = cloneDeepWith;
25916    lodash.cloneWith = cloneWith;
25917    lodash.deburr = deburr;
25918    lodash.divide = divide;
25919    lodash.endsWith = endsWith;
25920    lodash.eq = eq;
25921    lodash.escape = escape;
25922    lodash.escapeRegExp = escapeRegExp;
25923    lodash.every = every;
25924    lodash.find = find;
25925    lodash.findIndex = findIndex;
25926    lodash.findKey = findKey;
25927    lodash.findLast = findLast;
25928    lodash.findLastIndex = findLastIndex;
25929    lodash.findLastKey = findLastKey;
25930    lodash.floor = floor;
25931    lodash.forEach = forEach;
25932    lodash.forEachRight = forEachRight;
25933    lodash.forIn = forIn;
25934    lodash.forInRight = forInRight;
25935    lodash.forOwn = forOwn;
25936    lodash.forOwnRight = forOwnRight;
25937    lodash.get = get;
25938    lodash.gt = gt;
25939    lodash.gte = gte;
25940    lodash.has = has;
25941    lodash.hasIn = hasIn;
25942    lodash.head = head;
25943    lodash.identity = identity;
25944    lodash.includes = includes;
25945    lodash.indexOf = indexOf;
25946    lodash.inRange = inRange;
25947    lodash.invoke = invoke;
25948    lodash.isArguments = isArguments;
25949    lodash.isArray = isArray;
25950    lodash.isArrayBuffer = isArrayBuffer;
25951    lodash.isArrayLike = isArrayLike;
25952    lodash.isArrayLikeObject = isArrayLikeObject;
25953    lodash.isBoolean = isBoolean;
25954    lodash.isBuffer = isBuffer;
25955    lodash.isDate = isDate;
25956    lodash.isElement = isElement;
25957    lodash.isEmpty = isEmpty;
25958    lodash.isEqual = isEqual;
25959    lodash.isEqualWith = isEqualWith;
25960    lodash.isError = isError;
25961    lodash.isFinite = isFinite;
25962    lodash.isFunction = isFunction;
25963    lodash.isInteger = isInteger;
25964    lodash.isLength = isLength;
25965    lodash.isMap = isMap;
25966    lodash.isMatch = isMatch;
25967    lodash.isMatchWith = isMatchWith;
25968    lodash.isNaN = isNaN;
25969    lodash.isNative = isNative;
25970    lodash.isNil = isNil;
25971    lodash.isNull = isNull;
25972    lodash.isNumber = isNumber;
25973    lodash.isObject = isObject;
25974    lodash.isObjectLike = isObjectLike;
25975    lodash.isPlainObject = isPlainObject;
25976    lodash.isRegExp = isRegExp;
25977    lodash.isSafeInteger = isSafeInteger;
25978    lodash.isSet = isSet;
25979    lodash.isString = isString;
25980    lodash.isSymbol = isSymbol;
25981    lodash.isTypedArray = isTypedArray;
25982    lodash.isUndefined = isUndefined;
25983    lodash.isWeakMap = isWeakMap;
25984    lodash.isWeakSet = isWeakSet;
25985    lodash.join = join;
25986    lodash.kebabCase = kebabCase;
25987    lodash.last = last;
25988    lodash.lastIndexOf = lastIndexOf;
25989    lodash.lowerCase = lowerCase;
25990    lodash.lowerFirst = lowerFirst;
25991    lodash.lt = lt;
25992    lodash.lte = lte;
25993    lodash.max = max;
25994    lodash.maxBy = maxBy;
25995    lodash.mean = mean;
25996    lodash.meanBy = meanBy;
25997    lodash.min = min;
25998    lodash.minBy = minBy;
25999    lodash.multiply = multiply;
26000    lodash.noConflict = noConflict;
26001    lodash.noop = noop;
26002    lodash.now = now;
26003    lodash.pad = pad;
26004    lodash.padEnd = padEnd;
26005    lodash.padStart = padStart;
26006    lodash.parseInt = parseInt;
26007    lodash.random = random;
26008    lodash.reduce = reduce;
26009    lodash.reduceRight = reduceRight;
26010    lodash.repeat = repeat;
26011    lodash.replace = replace;
26012    lodash.result = result;
26013    lodash.round = round;
26014    lodash.runInContext = runInContext;
26015    lodash.sample = sample;
26016    lodash.size = size;
26017    lodash.snakeCase = snakeCase;
26018    lodash.some = some;
26019    lodash.sortedIndex = sortedIndex;
26020    lodash.sortedIndexBy = sortedIndexBy;
26021    lodash.sortedIndexOf = sortedIndexOf;
26022    lodash.sortedLastIndex = sortedLastIndex;
26023    lodash.sortedLastIndexBy = sortedLastIndexBy;
26024    lodash.sortedLastIndexOf = sortedLastIndexOf;
26025    lodash.startCase = startCase;
26026    lodash.startsWith = startsWith;
26027    lodash.subtract = subtract;
26028    lodash.sum = sum;
26029    lodash.sumBy = sumBy;
26030    lodash.template = template;
26031    lodash.times = times;
26032    lodash.toInteger = toInteger;
26033    lodash.toLength = toLength;
26034    lodash.toLower = toLower;
26035    lodash.toNumber = toNumber;
26036    lodash.toSafeInteger = toSafeInteger;
26037    lodash.toString = toString;
26038    lodash.toUpper = toUpper;
26039    lodash.trim = trim;
26040    lodash.trimEnd = trimEnd;
26041    lodash.trimStart = trimStart;
26042    lodash.truncate = truncate;
26043    lodash.unescape = unescape;
26044    lodash.uniqueId = uniqueId;
26045    lodash.upperCase = upperCase;
26046    lodash.upperFirst = upperFirst;
26047
26048    // Add aliases.
26049    lodash.each = forEach;
26050    lodash.eachRight = forEachRight;
26051    lodash.first = head;
26052
26053    mixin(lodash, (function() {
26054      var source = {};
26055      baseForOwn(lodash, function(func, methodName) {
26056        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
26057          source[methodName] = func;
26058        }
26059      });
26060      return source;
26061    }()), { 'chain': false });
26062
26063    /*------------------------------------------------------------------------*/
26064
26065    /**
26066     * The semantic version number.
26067     *
26068     * @static
26069     * @memberOf _
26070     * @type {string}
26071     */
26072    lodash.VERSION = VERSION;
26073
26074    // Assign default placeholders.
26075    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
26076      lodash[methodName].placeholder = lodash;
26077    });
26078
26079    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
26080    arrayEach(['drop', 'take'], function(methodName, index) {
26081      LazyWrapper.prototype[methodName] = function(n) {
26082        var filtered = this.__filtered__;
26083        if (filtered && !index) {
vendor: 4,485 bytes, lines 26084-26218
26084          return new LazyWrapper(this);
26085        }
26086        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
26087
26088        var result = this.clone();
26089        if (filtered) {
26090          result.__takeCount__ = nativeMin(n, result.__takeCount__);
26091        } else {
26092          result.__views__.push({
26093            'size': nativeMin(n, MAX_ARRAY_LENGTH),
26094            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
26095          });
26096        }
26097        return result;
26098      };
26099
26100      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
26101        return this.reverse()[methodName](n).reverse();
26102      };
26103    });
26104
26105    // Add `LazyWrapper` methods that accept an `iteratee` value.
26106    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
26107      var type = index + 1,
26108          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
26109
26110      LazyWrapper.prototype[methodName] = function(iteratee) {
26111        var result = this.clone();
26112        result.__iteratees__.push({
26113          'iteratee': getIteratee(iteratee, 3),
26114          'type': type
26115        });
26116        result.__filtered__ = result.__filtered__ || isFilter;
26117        return result;
26118      };
26119    });
26120
26121    // Add `LazyWrapper` methods for `_.head` and `_.last`.
26122    arrayEach(['head', 'last'], function(methodName, index) {
26123      var takeName = 'take' + (index ? 'Right' : '');
26124
26125      LazyWrapper.prototype[methodName] = function() {
26126        return this[takeName](1).value()[0];
26127      };
26128    });
26129
26130    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
26131    arrayEach(['initial', 'tail'], function(methodName, index) {
26132      var dropName = 'drop' + (index ? '' : 'Right');
26133
26134      LazyWrapper.prototype[methodName] = function() {
26135        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
26136      };
26137    });
26138
26139    LazyWrapper.prototype.compact = function() {
26140      return this.filter(identity);
26141    };
26142
26143    LazyWrapper.prototype.find = function(predicate) {
26144      return this.filter(predicate).head();
26145    };
26146
26147    LazyWrapper.prototype.findLast = function(predicate) {
26148      return this.reverse().find(predicate);
26149    };
26150
26151    LazyWrapper.prototype.invokeMap = rest(function(path, args) {
26152      if (typeof path == 'function') {
26153        return new LazyWrapper(this);
26154      }
26155      return this.map(function(value) {
26156        return baseInvoke(value, path, args);
26157      });
26158    });
26159
26160    LazyWrapper.prototype.reject = function(predicate) {
26161      predicate = getIteratee(predicate, 3);
26162      return this.filter(function(value) {
26163        return !predicate(value);
26164      });
26165    };
26166
26167    LazyWrapper.prototype.slice = function(start, end) {
26168      start = toInteger(start);
26169
26170      var result = this;
26171      if (result.__filtered__ && (start > 0 || end < 0)) {
26172        return new LazyWrapper(result);
26173      }
26174      if (start < 0) {
26175        result = result.takeRight(-start);
26176      } else if (start) {
26177        result = result.drop(start);
26178      }
26179      if (end !== undefined) {
26180        end = toInteger(end);
26181        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
26182      }
26183      return result;
26184    };
26185
26186    LazyWrapper.prototype.takeRightWhile = function(predicate) {
26187      return this.reverse().takeWhile(predicate).reverse();
26188    };
26189
26190    LazyWrapper.prototype.toArray = function() {
26191      return this.take(MAX_ARRAY_LENGTH);
26192    };
26193
26194    // Add `LazyWrapper` methods to `lodash.prototype`.
26195    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
26196      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
26197          isTaker = /^(?:head|last)$/.test(methodName),
26198          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
26199          retUnwrapped = isTaker || /^find/.test(methodName);
26200
26201      if (!lodashFunc) {
26202        return;
26203      }
26204      lodash.prototype[methodName] = function() {
26205        var value = this.__wrapped__,
26206            args = isTaker ? [1] : arguments,
26207            isLazy = value instanceof LazyWrapper,
26208            iteratee = args[0],
26209            useLazy = isLazy || isArray(value);
26210
26211        var interceptor = function(value) {
26212          var result = lodashFunc.apply(lodash, arrayPush([value], args));
26213          return (isTaker && chainAll) ? result[0] : result;
26214        };
26215
26216        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
26217          // Avoid lazy use if the iteratee has a "length" value other than `1`.
26218          isLazy = useLazy = false;
vendor: 3,084 bytes, lines 26219-26302
26219        }
26220        var chainAll = this.__chain__,
26221            isHybrid = !!this.__actions__.length,
26222            isUnwrapped = retUnwrapped && !chainAll,
26223            onlyLazy = isLazy && !isHybrid;
26224
26225        if (!retUnwrapped && useLazy) {
26226          value = onlyLazy ? value : new LazyWrapper(this);
26227          var result = func.apply(value, args);
26228          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
26229          return new LodashWrapper(result, chainAll);
26230        }
26231        if (isUnwrapped && onlyLazy) {
26232          return func.apply(this, args);
26233        }
26234        result = this.thru(interceptor);
26235        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
26236      };
26237    });
26238
26239    // Add `Array` methods to `lodash.prototype`.
26240    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
26241      var func = arrayProto[methodName],
26242          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
26243          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
26244
26245      lodash.prototype[methodName] = function() {
26246        var args = arguments;
26247        if (retUnwrapped && !this.__chain__) {
26248          var value = this.value();
26249          return func.apply(isArray(value) ? value : [], args);
26250        }
26251        return this[chainName](function(value) {
26252          return func.apply(isArray(value) ? value : [], args);
26253        });
26254      };
26255    });
26256
26257    // Map minified method names to their real names.
26258    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
26259      var lodashFunc = lodash[methodName];
26260      if (lodashFunc) {
26261        var key = (lodashFunc.name + ''),
26262            names = realNames[key] || (realNames[key] = []);
26263
26264        names.push({ 'name': methodName, 'func': lodashFunc });
26265      }
26266    });
26267
26268    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{
26269      'name': 'wrapper',
26270      'func': undefined
26271    }];
26272
26273    // Add methods to `LazyWrapper`.
26274    LazyWrapper.prototype.clone = lazyClone;
26275    LazyWrapper.prototype.reverse = lazyReverse;
26276    LazyWrapper.prototype.value = lazyValue;
26277
26278    // Add chain sequence methods to the `lodash` wrapper.
26279    lodash.prototype.at = wrapperAt;
26280    lodash.prototype.chain = wrapperChain;
26281    lodash.prototype.commit = wrapperCommit;
26282    lodash.prototype.next = wrapperNext;
26283    lodash.prototype.plant = wrapperPlant;
26284    lodash.prototype.reverse = wrapperReverse;
26285    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
26286
26287    if (iteratorSymbol) {
26288      lodash.prototype[iteratorSymbol] = wrapperToIterator;
26289    }
26290    return lodash;
26291  }
26292
26293  /*--------------------------------------------------------------------------*/
26294
26295  // Export lodash.
26296  var _ = runInContext();
26297
26298  // Expose lodash on the free variable `window` or `self` when available. This
26299  // prevents errors in cases where lodash is loaded by a script tag in the presence
26300  // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
26301  (freeWindow || freeSelf || {})._ = _;
26302
26303  // Some AMD build optimizers like r.js check for condition patterns like the following:
26304  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
26305    // Define as an anonymous module so, through path mapping, it can be
26306    // referenced as the "underscore" module.
26307    define(function() {
26308      return _;
26309    });
26310  }
26311  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
26312  else if (freeExports && freeModule) {
26313    // Export for Node.js.
26314    if (moduleExports) {
26315      (freeModule.exports = _)._ = _;
26316    }
26317    // Export for CommonJS support.
26318    freeExports._ = _;
26319  }
26320  else {
26321    // Export to the global object.
26322    root._ = _;
26323  }
26324}.call(this));
26325/*!
26326Dirty Forms jQuery Plugin | v2.0.0 | github.com/snikch/jquery.dirtyforms
26327(c) 2010-2015 Mal Curtis
26328License MIT
26329*/
26330!function(e,t,i,r){e.fn.on||(e.fn.on=function(e,t,i,r){return this.delegate(t,e,i,r)}),e.fn.dirtyForms=function(t){return n[t]?n[t].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof t&&t?void e.error("Method "+t+" does not exist on jQuery.dirtyForms"):n.init.apply(this,arguments)};var n={init:function(r){var n={};return a.initialized||(e.extend(!0,e.DirtyForms,r),e(i).trigger("bind.dirtyforms",[u]),u.bind(t,i,n),a.initialized=!0),this.filter("form").not(":dirtylistening").each(function(){var t=e(this);t.find(e.DirtyForms.fieldSelector).each(function(){m(e(this))}),t.trigger("scan.dirtyforms"),u.bindForm(t,n)}),this},isDirty:function(t){var i=p(),r=e.DirtyForms.dirtyClass,n=!1;return this.each(function(o){var a=e(this),s=b(a,i);return a.hasClass(r)&&!s?(n=!0,!1):(a.find("."+r).each(function(){return b(e(this),i)?void 0:(n=!0,!1)}),n?!1:s||t||(e.each(e.DirtyForms.helpers,function(e,t){return t.isDirty&&t.isDirty(a,o)?(n=!0,!1):void 0}),!n)?void 0:!1)}),n},setClean:function(t,i){var r=function(){var t=e(this);m(t),C(t,!1)};return g(this,e.DirtyForms.fieldSelector,t).each(r).parents("form").trigger("setclean.dirtyforms",[t]),i?this:y(this,"setClean",t,p())},rescan:function(t,i){var r=function(){var t=e(this);v(t)||m(t),C(t,F(t))};return g(this,e.DirtyForms.fieldSelector,t).each(r).parents("form").trigger("rescan.dirtyforms",[t]),i?this:y(this,"rescan",t,p())}};e.extend(e.expr[":"],{dirty:function(t){var i=e(t);return i.hasClass(e.DirtyForms.dirtyClass)&&!i.is(":dirtyignored")},dirtylistening:function(t){return e(t).hasClass(e.DirtyForms.listeningClass)},dirtyignored:function(t){return b(e(t),!1)}}),e.DirtyForms={message:"You've made changes on this page which aren't saved. If you leave you will lose these changes.",dirtyClass:"dirty",listeningClass:"dirtylisten",ignoreClass:"dirtyignore",ignoreSelector:"",fieldSelector:"input:not([type='button'],[type='image'],[type='submit'],[type='reset'],[type='file'],[type='search']),select,textarea",helpers:[],dialog:!1};var o,a={initialized:!1,formStash:!1,dialogStash:!1,deciding:!1,decidingEvent:!1},s=function(e){return e.data.bindEscKey&&27==e.which||e.data.bindEnterKey&&13==e.which?f(e,!1):void 0},d=function(t){var r=t.staySelector,n=t.proceedSelector;""!==r&&e(r).unbind("click",f).click(f),""!==n&&e(n).unbind("click",l).click(l),(t.bindEscKey||t.bindEnterKey)&&e(i).unbind("keydown",s).keydown(t,s)},c=function(t,i){e.isFunction(e.DirtyForms.dialog.close)&&e.DirtyForms.dialog.close(t,i)},l=function(e){return f(e,!0)},f=function(t,r){if(a.deciding){if(t.preventDefault(),r===!0){var n=a.decidingEvent;e(i).trigger("proceed.dirtyforms",[n]),u.clearUnload(),c(r,!1),E(n)}else{e(i).trigger("stay.dirtyforms");var o=e.DirtyForms.dialog!==!1&&a.dialogStash!==!1&&e.isFunction(e.DirtyForms.dialog.unstash);c(r,o),o&&e.DirtyForms.dialog.unstash(a.dialogStash,t),e(i).trigger("afterstay.dirtyforms")}return a.deciding=a.decidingEvent=a.dialogStash=a.formStash=!1,!1}},u={bind:function(t,i,r){e(t).bind("beforeunload",r,u.onBeforeUnload),e(i).on("click",'a:not([target="_blank"])',r,u.onAnchorClick).on("submit","form",r,u.onSubmit)},bindForm:function(t,r){var n=e.DirtyForms,o="onpropertychange"in i.createElement("input"),a="change input"+(o?" keyup selectionchange cut paste":"");t.addClass(n.listeningClass).on("focus keydown",n.fieldSelector,r,u.onFocus).on(a,n.fieldSelector,r,u.onFieldChange).bind("reset",r,u.onReset)},onFocus:function(t){var i=e(t.target);v(i)||m(i)},onFieldChange:function(t){var i=e(t.target);"change"!==t.type?S(function(){D(i)},100):D(i)},onReset:function(t){var i=e(t.target).closest("form");setTimeout(function(){i.dirtyForms("setClean")},100)},onAnchorClick:function(e){k(e)},onSubmit:function(e){k(e)},onBeforeUnload:function(e){var t=k(e);return t&&a.doubleunloadfix!==!0&&(a.deciding=!1),a.doubleunloadfix=!0,setTimeout(function(){a.doubleunloadfix=!1},200),"string"==typeof t?(e.returnValue=t,t):void 0},onRefireClick:function(t){var i=new e.Event("click");e(t.target).trigger(i),i.isDefaultPrevented()||u.onRefireAnchorClick(t)},onRefireAnchorClick:function(i){var n=e(i.target).closest("a[href]").attr("href");n!==r&&(t.location.href=n)},clearUnload:function(){e(t).unbind("beforeunload",u.onBeforeUnload),t.onbeforeunload=null,e(i).trigger("beforeunload.dirtyforms")}
26330},g=function(e,t,i){var r=e.filter(t).add(e.find(t));return i&&(r=r.not(":dirtyignored")),r},y=function(t,i,r,n){return t.each(function(t){var o=e(this);r&&b(o,n)||e.each(e.DirtyForms.helpers,function(e,n){n[i]&&n[i](o,t,r)})})},h=function(t){var i;return t.is("select")?(i="",t.find("option").each(function(){var t=e(this);t.is(":selected")&&(i.length>0&&(i+=","),i+=t.val())})):i=t.is(":checkbox,:radio")?t.is(":checked"):t.val(),i},m=function(e){e.data("df-orig",h(e));var t=e.data("df-orig")===r;e.data("df-empty",t)},v=function(e){return e.data("df-orig")!==r||e.data("df-empty")===!0},p=function(){var t=e.DirtyForms,i=t.ignoreSelector;return e.each(t.helpers,function(e,t){"ignoreSelector"in t&&(i.length>0&&(i+=","),i+=t.ignoreSelector)}),i},b=function(t,i){return i||(i=p()),t.is(i)||t.closest("."+e.DirtyForms.ignoreClass).length>0},F=function(e,t){return!v(e)||b(e,t)?!1:h(e)!=e.data("df-orig")},D=function(t,i){if(!b(t,i))if(t.is(":radio[name]")){var r=t.attr("name"),n=t.parents("form");n.find(":radio[name='"+r+"']").each(function(){var t=e(this);C(t,F(t,i))})}else C(t,F(t,i))},C=function(t,i){var r=e.DirtyForms.dirtyClass,n=t.parents("form");t.toggleClass(r,i);var o=i!==(n.hasClass(r)&&0===n.find(":dirty").length);o&&(n.toggleClass(r,i),i&&n.trigger("dirty.dirtyforms"),i||n.trigger("clean.dirtyforms"))},S=function(){var e=0;return function(t,i){clearTimeout(e),e=setTimeout(t,i)}}(),k=function(t){var r=e(t.target),n=t.type,s=e.DirtyForms;if(t.isDefaultPrevented())return!1;if("beforeunload"==n&&a.doubleunloadfix)return a.doubleunloadfix=!1,!1;if(r.is(":dirtyignored"))return u.clearUnload(),!1;if(a.deciding)return!1;if(!e("form:dirtylistening").dirtyForms("isDirty"))return u.clearUnload(),!1;if("submit"==n&&r.dirtyForms("isDirty"))return u.clearUnload(),!0;if(e(i).trigger("defer.dirtyforms"),"beforeunload"==n)return s.message;if(s.dialog){t.preventDefault(),t.stopImmediatePropagation(),a.deciding=!0,a.decidingEvent=t,e.isFunction(s.dialog.stash)&&(a.dialogStash=s.dialog.stash());var c=s.dialog.stashSelector;"string"==typeof c&&r.is("form")&&r.parents(c).length>0?a.formStash=r.clone(!0).hide():a.formStash=!1,o={proceed:!1,commit:function(e){return f(e,o.proceed)},bindEscKey:!0,bindEnterKey:!1,proceedSelector:"",staySelector:""},s.dialog.open(o,s.message,s.ignoreClass),d(o)}},E=function(t){if("click"===t.type)u.onRefireClick(t);else{var i;a.formStash?(i=a.formStash,e("body").append(i)):i=e(t.target).closest("form"),i.trigger(t.type)}}}(jQuery,window,document);
26331/*!
26332Bootstrap modal dialog (for jQuery Dirty Forms) | v2.0.0 | github.com/snikch/jquery.dirtyforms
26333(c) 2015 Shad Storhaug
26334License MIT
26335*/
26336!function(t,e,s,a){var i='<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> ';t.DirtyForms.dialog={title:i+"Are you sure you want to do that?",proceedButtonClass:"dirty-proceed",proceedButtonText:"Leave This Page",stayButtonClass:"dirty-stay",stayButtonText:"Stay Here",dialogID:"dirty-dialog",titleID:"dirty-title",messageClass:"dirty-message",preMessageText:"",postMessageText:"",replaceText:!0,open:function(e,s){var a=t("#"+this.dialogID);0===a.length&&(a=t('<div id="'+this.dialogID+'" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="'+this.titleID+'"><div class="modal-dialog" role="document"><div class="modal-content panel-danger"><div class="modal-header panel-heading"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h3 class="modal-title" id="'+this.titleID+'"></h3></div><div class="modal-body panel-body '+this.messageClass+'"></div><div class="modal-footer panel-footer"><button type="button" class="'+this.proceedButtonClass+' btn btn-danger" data-dismiss="modal"></button><button type="button" class="'+this.stayButtonClass+' btn btn-default" data-dismiss="modal"></button></div></div></div></div>'),t("body").append(a).data("df-dialog-appended",!0)),this.replaceText&&(a.find("#"+this.titleID).html(this.title),a.find("."+this.messageClass).html(this.preMessageText+s+this.postMessageText),a.find("."+this.proceedButtonClass).html(this.proceedButtonText),a.find("."+this.stayButtonClass).html(this.stayButtonText)),e.bindEscKey=!1;var i=function(){e.proceed=t.DirtyForms.choiceContinue=!0},o=function(s){var i=e.isDF1?t.DirtyForms.choiceCommit:e.commit;i(s),t("body").data("df-dialog-appended")===!0&&a.remove()};a.find("."+this.proceedButtonClass).off("click",i).on("click",i),a.off("hidden.bs.modal",o).on("hidden.bs.modal",o),a.modal({show:!0})},fire:function(t,e){this.title=i+e,this.open({isDF1:!0},t)},bind:function(){},stash:function(){return!1},refire:function(){return!1},selector:"no-op"}}(jQuery,window,document);
26337/*!
26338 * mustache.js - Logic-less {{mustache}} templates with JavaScript
26339 * http://github.com/janl/mustache.js
26340 */
26341
26342/*global define: false Mustache: true*/
26343
26344(function defineMustache (global, factory) {
26345  if (typeof exports === 'object' && exports && typeof exports.nodeName !== 'string') {
26346    factory(exports); // CommonJS
26347  } else if (typeof define === 'function' && define.amd) {
26348    define(['exports'], factory); // AMD
26349  } else {
26350    global.Mustache = {};
26351    factory(global.Mustache); // script, wsh, asp
26352  }
26353}(this, function mustacheFactory (mustache) {
26354
26355  var objectToString = Object.prototype.toString;
26356  var isArray = Array.isArray || function isArrayPolyfill (object) {
26357    return objectToString.call(object) === '[object Array]';
26358  };
26359
26360  function isFunction (object) {
26361    return typeof object === 'function';
26362  }
26363
26364  /**
26365   * More correct typeof string handling array
26366   * which normally returns typeof 'object'
26367   */
26368  function typeStr (obj) {
26369    return isArray(obj) ? 'array' : typeof obj;
26370  }
26371
26372  function escapeRegExp (string) {
26373    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
26374  }
26375
26376  /**
26377   * Null safe way of checking whether or not an object,
26378   * including its prototype, has a given property
26379   */
26380  function hasProperty (obj, propName) {
26381    return obj != null && typeof obj === 'object' && (propName in obj);
26382  }
26383
26384  // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
26385  // See https://github.com/janl/mustache.js/issues/189
26386  var regExpTest = RegExp.prototype.test;
26387  function testRegExp (re, string) {
26388    return regExpTest.call(re, string);
26389  }
26390
26391  var nonSpaceRe = /\S/;
26392  function isWhitespace (string) {
26393    return !testRegExp(nonSpaceRe, string);
26394  }
26395
26396  var entityMap = {
26397    '&': '&amp;',
26398    '<': '&lt;',
26399    '>': '&gt;',
26400    '"': '&quot;',
26401    "'": '&#39;',
26402    '/': '&#x2F;',
26403    '`': '&#x60;',
26404    '=': '&#x3D;'
26405  };
26406
26407  function escapeHtml (string) {
26408    return String(string).replace(/[&<>
vendor: 12,986 bytes, lines 26408-26837
26408"'`=\/]/g, function fromEntityMap (s) {
26409      return entityMap[s];
26410    });
26411  }
26412
26413  var whiteRe = /\s*/;
26414  var spaceRe = /\s+/;
26415  var equalsRe = /\s*=/;
26416  var curlyRe = /\s*\}/;
26417  var tagRe = /#|\^|\/|>|\{|&|=|!/;
26418
26419  /**
26420   * Breaks up the given `template` string into a tree of tokens. If the `tags`
26421   * argument is given here it must be an array with two string values: the
26422   * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
26423   * course, the default is to use mustaches (i.e. mustache.tags).
26424   *
26425   * A token is an array with at least 4 elements. The first element is the
26426   * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
26427   * did not contain a symbol (i.e. {{myValue}}) this element is "name". For
26428   * all text that appears outside a symbol this element is "text".
26429   *
26430   * The second element of a token is its "value". For mustache tags this is
26431   * whatever else was inside the tag besides the opening symbol. For text tokens
26432   * this is the text itself.
26433   *
26434   * The third and fourth elements of the token are the start and end indices,
26435   * respectively, of the token in the original template.
26436   *
26437   * Tokens that are the root node of a subtree contain two more elements: 1) an
26438   * array of tokens in the subtree and 2) the index in the original template at
26439   * which the closing tag for that section begins.
26440   */
26441  function parseTemplate (template, tags) {
26442    if (!template)
26443      return [];
26444
26445    var sections = [];     // Stack to hold section tokens
26446    var tokens = [];       // Buffer to hold the tokens
26447    var spaces = [];       // Indices of whitespace tokens on the current line
26448    var hasTag = false;    // Is there a {{tag}} on the current line?
26449    var nonSpace = false;  // Is there a non-space char on the current line?
26450
26451    // Strips all whitespace tokens array for the current line
26452    // if there was a {{#tag}} on it and otherwise only space.
26453    function stripSpace () {
26454      if (hasTag && !nonSpace) {
26455        while (spaces.length)
26456          delete tokens[spaces.pop()];
26457      } else {
26458        spaces = [];
26459      }
26460
26461      hasTag = false;
26462      nonSpace = false;
26463    }
26464
26465    var openingTagRe, closingTagRe, closingCurlyRe;
26466    function compileTags (tagsToCompile) {
26467      if (typeof tagsToCompile === 'string')
26468        tagsToCompile = tagsToCompile.split(spaceRe, 2);
26469
26470      if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
26471        throw new Error('Invalid tags: ' + tagsToCompile);
26472
26473      openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
26474      closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
26475      closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
26476    }
26477
26478    compileTags(tags || mustache.tags);
26479
26480    var scanner = new Scanner(template);
26481
26482    var start, type, value, chr, token, openSection;
26483    while (!scanner.eos()) {
26484      start = scanner.pos;
26485
26486      // Match any text between tags.
26487      value = scanner.scanUntil(openingTagRe);
26488
26489      if (value) {
26490        for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
26491          chr = value.charAt(i);
26492
26493          if (isWhitespace(chr)) {
26494            spaces.push(tokens.length);
26495          } else {
26496            nonSpace = true;
26497          }
26498
26499          tokens.push([ 'text', chr, start, start + 1 ]);
26500          start += 1;
26501
26502          // Check for whitespace on the current line.
26503          if (chr === '\n')
26504            stripSpace();
26505        }
26506      }
26507
26508      // Match the opening tag.
26509      if (!scanner.scan(openingTagRe))
26510        break;
26511
26512      hasTag = true;
26513
26514      // Get the tag type.
26515      type = scanner.scan(tagRe) || 'name';
26516      scanner.scan(whiteRe);
26517
26518      // Get the tag value.
26519      if (type === '=') {
26520        value = scanner.scanUntil(equalsRe);
26521        scanner.scan(equalsRe);
26522        scanner.scanUntil(closingTagRe);
26523      } else if (type === '{') {
26524        value = scanner.scanUntil(closingCurlyRe);
26525        scanner.scan(curlyRe);
26526        scanner.scanUntil(closingTagRe);
26527        type = '&';
26528      } else {
26529        value = scanner.scanUntil(closingTagRe);
26530      }
26531
26532      // Match the closing tag.
26533      if (!scanner.scan(closingTagRe))
26534        throw new Error('Unclosed tag at ' + scanner.pos);
26535
26536      token = [ type, value, start, scanner.pos ];
26537      tokens.push(token);
26538
26539      if (type === '#' || type === '^') {
26540        sections.push(token);
26541      } else if (type === '/') {
26542        // Check section nesting.
26543        openSection = sections.pop();
26544
26545        if (!openSection)
26546          throw new Error('Unopened section "' + value + '" at ' + start);
26547
26548        if (openSection[1] !== value)
26549          throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
26550      } else if (type === 'name' || type === '{' || type === '&') {
26551        nonSpace = true;
26552      } else if (type === '=') {
26553        // Set the tags for the next time around.
26554        compileTags(value);
26555      }
26556    }
26557
26558    // Make sure there are no open sections when we're done.
26559    openSection = sections.pop();
26560
26561    if (openSection)
26562      throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
26563
26564    return nestTokens(squashTokens(tokens));
26565  }
26566
26567  /**
26568   * Combines the values of consecutive text tokens in the given `tokens` array
26569   * to a single token.
26570   */
26571  function squashTokens (tokens) {
26572    var squashedTokens = [];
26573
26574    var token, lastToken;
26575    for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
26576      token = tokens[i];
26577
26578      if (token) {
26579        if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
26580          lastToken[1] += token[1];
26581          lastToken[3] = token[3];
26582        } else {
26583          squashedTokens.push(token);
26584          lastToken = token;
26585        }
26586      }
26587    }
26588
26589    return squashedTokens;
26590  }
26591
26592  /**
26593   * Forms the given array of `tokens` into a nested tree structure where
26594   * tokens that represent a section have two additional items: 1) an array of
26595   * all tokens that appear in that section and 2) the index in the original
26596   * template that represents the end of that section.
26597   */
26598  function nestTokens (tokens) {
26599    var nestedTokens = [];
26600    var collector = nestedTokens;
26601    var sections = [];
26602
26603    var token, section;
26604    for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
26605      token = tokens[i];
26606
26607      switch (token[0]) {
26608        case '#':
26609        case '^':
26610          collector.push(token);
26611          sections.push(token);
26612          collector = token[4] = [];
26613          break;
26614        case '/':
26615          section = sections.pop();
26616          section[5] = token[2];
26617          collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
26618          break;
26619        default:
26620          collector.push(token);
26621      }
26622    }
26623
26624    return nestedTokens;
26625  }
26626
26627  /**
26628   * A simple string scanner that is used by the template parser to find
26629   * tokens in template strings.
26630   */
26631  function Scanner (string) {
26632    this.string = string;
26633    this.tail = string;
26634    this.pos = 0;
26635  }
26636
26637  /**
26638   * Returns `true` if the tail is empty (end of string).
26639   */
26640  Scanner.prototype.eos = function eos () {
26641    return this.tail === '';
26642  };
26643
26644  /**
26645   * Tries to match the given regular expression at the current position.
26646   * Returns the matched text if it can match, the empty string otherwise.
26647   */
26648  Scanner.prototype.scan = function scan (re) {
26649    var match = this.tail.match(re);
26650
26651    if (!match || match.index !== 0)
26652      return '';
26653
26654    var string = match[0];
26655
26656    this.tail = this.tail.substring(string.length);
26657    this.pos += string.length;
26658
26659    return string;
26660  };
26661
26662  /**
26663   * Skips all text until the given regular expression can be matched. Returns
26664   * the skipped string, which is the entire tail if no match can be made.
26665   */
26666  Scanner.prototype.scanUntil = function scanUntil (re) {
26667    var index = this.tail.search(re), match;
26668
26669    switch (index) {
26670      case -1:
26671        match = this.tail;
26672        this.tail = '';
26673        break;
26674      case 0:
26675        match = '';
26676        break;
26677      default:
26678        match = this.tail.substring(0, index);
26679        this.tail = this.tail.substring(index);
26680    }
26681
26682    this.pos += match.length;
26683
26684    return match;
26685  };
26686
26687  /**
26688   * Represents a rendering context by wrapping a view object and
26689   * maintaining a reference to the parent context.
26690   */
26691  function Context (view, parentContext) {
26692    this.view = view;
26693    this.cache = { '.': this.view };
26694    this.parent = parentContext;
26695  }
26696
26697  /**
26698   * Creates a new context using the given view with this context
26699   * as the parent.
26700   */
26701  Context.prototype.push = function push (view) {
26702    return new Context(view, this);
26703  };
26704
26705  /**
26706   * Returns the value of the given name in this context, traversing
26707   * up the context hierarchy if the value is absent in this context's view.
26708   */
26709  Context.prototype.lookup = function lookup (name) {
26710    var cache = this.cache;
26711
26712    var value;
26713    if (cache.hasOwnProperty(name)) {
26714      value = cache[name];
26715    } else {
26716      var context = this, names, index, lookupHit = false;
26717
26718      while (context) {
26719        if (name.indexOf('.') > 0) {
26720          value = context.view;
26721          names = name.split('.');
26722          index = 0;
26723
26724          /**
26725           * Using the dot notion path in `name`, we descend through the
26726           * nested objects.
26727           *
26728           * To be certain that the lookup has been successful, we have to
26729           * check if the last object in the path actually has the property
26730           * we are looking for. We store the result in `lookupHit`.
26731           *
26732           * This is specially necessary for when the value has been set to
26733           * `undefined` and we want to avoid looking up parent contexts.
26734           **/
26735          while (value != null && index < names.length) {
26736            if (index === names.length - 1)
26737              lookupHit = hasProperty(value, names[index]);
26738
26739            value = value[names[index++]];
26740          }
26741        } else {
26742          value = context.view[name];
26743          lookupHit = hasProperty(context.view, name);
26744        }
26745
26746        if (lookupHit)
26747          break;
26748
26749        context = context.parent;
26750      }
26751
26752      cache[name] = value;
26753    }
26754
26755    if (isFunction(value))
26756      value = value.call(this.view);
26757
26758    return value;
26759  };
26760
26761  /**
26762   * A Writer knows how to take a stream of tokens and render them to a
26763   * string, given a context. It also maintains a cache of templates to
26764   * avoid the need to parse the same template twice.
26765   */
26766  function Writer () {
26767    this.cache = {};
26768  }
26769
26770  /**
26771   * Clears all cached templates in this writer.
26772   */
26773  Writer.prototype.clearCache = function clearCache () {
26774    this.cache = {};
26775  };
26776
26777  /**
26778   * Parses and caches the given `template` and returns the array of tokens
26779   * that is generated from the parse.
26780   */
26781  Writer.prototype.parse = function parse (template, tags) {
26782    var cache = this.cache;
26783    var tokens = cache[template];
26784
26785    if (tokens == null)
26786      tokens = cache[template] = parseTemplate(template, tags);
26787
26788    return tokens;
26789  };
26790
26791  /**
26792   * High-level method that is used to render the given `template` with
26793   * the given `view`.
26794   *
26795   * The optional `partials` argument may be an object that contains the
26796   * names and templates of partials that are used in the template. It may
26797   * also be a function that is used to load partial templates on the fly
26798   * that takes a single argument: the name of the partial.
26799   */
26800  Writer.prototype.render = function render (template, view, partials) {
26801    var tokens = this.parse(template);
26802    var context = (view instanceof Context) ? view : new Context(view);
26803    return this.renderTokens(tokens, context, partials, template);
26804  };
26805
26806  /**
26807   * Low-level method that renders the given array of `tokens` using
26808   * the given `context` and `partials`.
26809   *
26810   * Note: The `originalTemplate` is only ever used to extract the portion
26811   * of the original template that was contained in a higher-order section.
26812   * If the template doesn't use higher-order sections, this argument may
26813   * be omitted.
26814   */
26815  Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate) {
26816    var buffer = '';
26817
26818    var token, symbol, value;
26819    for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
26820      value = undefined;
26821      token = tokens[i];
26822      symbol = token[0];
26823
26824      if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate);
26825      else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate);
26826      else if (symbol === '>') value = this.renderPartial(token, context, partials, originalTemplate);
26827      else if (symbol === '&') value = this.unescapedValue(token, context);
26828      else if (symbol === 'name') value = this.escapedValue(token, context);
26829      else if (symbol === 'text') value = this.rawValue(token);
26830
26831      if (value !== undefined)
26832        buffer += value;
26833    }
26834
26835    return buffer;
26836  };
26837
26838  Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) {
26839    var self = this;
26840    var buffer = '';
26841    var value = context.lookup(token[1]);
26842
26843    // This function is used to render an arbitrary template
26844    // in the current context by higher-order sections.
26845    function subRender (template) {
26846      return self.render(template, context, partials);
26847    }
26848
26849    if (!value) return;
26850
26851    if (isArray(value)) {
26852      for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
26853        buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);
26854      }
26855    } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {
26856      buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);
26857    } else if (isFunction(value)) {
26858      if (typeof originalTemplate !== 'string')
26859        throw new Error('Cannot use higher-order sections without the original template');
26860
26861      // Extract the portion of the original template that the section contains.
26862      value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
26863
26864      if (value != null)
26865        buffer += value;
26866    } else {
26867      buffer += this.renderTokens(token[4], context, partials, originalTemplate);
26868    }
26869    return buffer;
26870  };
26871
26872  Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate) {
26873    var value = context.lookup(token[1]);
26874
26875    // Use JavaScript's definition of falsy. Include empty arrays.
26876    // See https://github.com/janl/mustache.js/issues/186
26877    if (!value || (isArray(value) && value.length === 0))
26878      return this.renderTokens(token[4], context, partials, originalTemplate);
26879  };
26880
26881  Writer.prototype.renderPartial = function renderPartial (token, context, partials) {
26882    if (!partials) return;
26883
26884    var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
26885    if (value != null)
26886      return this.renderTokens(this.parse(value), context, partials, value);
26887  };
26888
26889  Writer.prototype.unescapedValue = function unescapedValue (token, context) {
26890    var value = context.lookup(token[1]);
26891    if (value != null)
26892      return value;
26893  };
26894
26895  Writer.prototype.escapedValue = function escapedValue (token, context) {
26896    var value = context.lookup(token[1]);
26897    if (value != null)
26898      return mustache.escape(value);
26899  };
26900
26901  Writer.prototype.rawValue = function rawValue (token) {
26902    return token[1];
26903  };
26904
26905  mustache.name = 'mustache.js';
26906  mustache.version = '2.2.1';
26907  mustache.tags = [ '{{', '}}' ];
26908
26909  // All high-level mustache.* functions use this writer.
26910  var defaultWriter = new Writer();
26911
26912  /**
26913   * Clears all cached templates in the default writer.
26914   */
26915  mustache.clearCache = function clearCache () {
26916    return defaultWriter.clearCache();
26917  };
26918
26919  /**
26920   * Parses and caches the given template in the default writer and returns the
26921   * array of tokens it contains. Doing this ahead of time avoids the need to
26922   * parse templates on the fly as they are rendered.
26923   */
26924  mustache.parse = function parse (template, tags) {
26925    return defaultWriter.parse(template, tags);
26926  };
26927
26928  /**
26929   * Renders the `template` with the given `view` and `partials` using the
26930   * default writer.
26931   */
26932  mustache.render = function render (template, view, partials) {
26933    if (typeof template !== 'string') {
26934      throw new TypeError('Invalid template! Template should be a "string" ' +
26935                          'but "' + typeStr(template) + '" was given as the first ' +
26936                          'argument for mustache#render(template, view, partials)');
26937    }
26938
26939    return defaultWriter.render(template, view, partials);
26940  };
26941
26942  // This is here for backwards compatibility with 0.4.x.,
26943  /*eslint-disable */ // eslint wants camel cased function name
26944  mustache.to_html = function to_html (template, view, partials, send) {
26945    /*eslint-enable*/
26946
26947    var result = mustache.render(template, view, partials);
26948
26949    if (isFunction(send)) {
26950      send(result);
26951    } else {
26952      return result;
26953    }
26954  };
26955
26956  // Export the escaping function so that the user may override it.
26957  // See https://github.com/janl/mustache.js/issues/244
26958  mustache.escape = escapeHtml;
26959
26960  // Export these mainly for testing, but also for advanced usage.
26961  mustache.Scanner = Scanner;
26962  mustache.Context = Context;
26963  mustache.Writer = Writer;
26964
26965}));
26966/*!
26967 * Stickyfill -- `position: sticky` polyfill
26968 * v. 1.1.4 | https://github.com/wilddeer/stickyfill
26969 * Copyright Oleg Korsunsky | http://wd.dizaina.net/
26970 *
26971 * MIT License
26972 */
26973(function(doc, win) {
26974    var watchArray = [],
26975        scroll,
26976        initialized = false,
26977        html = doc.documentElement,
26978        noop = function() {},
26979        checkTimer,
26980
26981        //visibility API strings
26982        hiddenPropertyName = 'hidden',
26983        visibilityChangeEventName = 'visibilitychange';
26984
26985    //fallback to prefixed names in old webkit browsers
26986    if (doc.webkitHidden !== undefined) {
26987        hiddenPropertyName = 'webkitHidden';
26988        visibilityChangeEventName = 'webkitvisibilitychange';
26989    }
26990
26991    //test getComputedStyle
26992    if (!win.getComputedStyle) {
26993        seppuku();
26994    }
26995
26996    //test for native support
26997    var prefixes = ['', '-webkit-', '-moz-', '-ms-'],
26998        block = document.createElement('div');
26999
27000    for (var i = prefixes.length - 1; i >= 0; i--) {
27001        try {
27002            block.style.position = prefixes[i] + 'sticky';
27003        }
27004        catch(e) {}
27005        if (block.style.position != '') {
27006            seppuku();
27007        }
27008    }
27009
27010    updateScrollPos();
27011
27012    //commit seppuku!
27013    function seppuku() {
27014        init = add = rebuild = pause = stop = kill = noop;
27015    }
27016
27017    function mergeObjects(targetObj, sourceObject) {
27018        for (var key in sourceObject) {
27019            if (sourceObject.hasOwnProperty(key)) {
27020                targetObj[key] = sourceObject[key];
27021            }
27022        }
27023    }
27024
27025    function parseNumeric(val) {
27026        return parseFloat(val) || 0;
27027    }
27028
27029    function updateScrollPos() {
27030        scroll = {
27031            top: win.pageYOffset,
27032            left: win.pageXOffset
27033        };
27034    }
27035
27036    function onScroll() {
27037        if (win.pageXOffset != scroll.left) {
27038            updateScrollPos();
27039            rebuild();
27040            return;
27041        }
27042
27043        if (win.pageYOffset != scroll.top) {
27044            updateScrollPos();
27045            recalcAllPos();
27046        }
27047    }
27048
27049    //fixes flickering
27050    function onWheel(event) {
27051        setTimeout(function() {
27052            if (win.pageYOffset != scroll.top) {
27053                scroll.top = win.pageYOffset;
27054                recalcAllPos();
27055            }
27056        }, 0);
27057    }
27058
27059    function recalcAllPos() {
27060        for (var i = watchArray.length - 1; i >= 0; i--) {
27061            recalcElementPos(watchArray[i]);
27062        }
27063    }
27064
27065    function recalcElementPos(el) {
27066        if (!el.inited) return;
27067
27068        var currentMode = (scroll.top <= el.limit.start? 0: scroll.top >= el.limit.end? 2: 1);
27069
27070        if (el.mode != currentMode) {
27071            switchElementMode(el, currentMode);
27072        }
27073    }
27074
27075    //checks whether stickies start or stop positions have changed
27076    function fastCheck() {
27077        for (var i = watchArray.length - 1; i >= 0; i--) {
27078            if (!watchArray[i].inited) continue;
27079
27080            var deltaTop = Math.abs(getDocOffsetTop(watchArray[i].clone) - watchArray[i].docOffsetTop),
27081                deltaHeight = Math.abs(watchArray[i].parent.node.offsetHeight - watchArray[i].parent.height);
27082
27083            if (deltaTop >= 2 || deltaHeight >= 2) return false;
27084        }
27085        return true;
27086    }
27087
27088    function initElement(el) {
27089        if (isNaN(parseFloat(el.computed.top)) || el.isCell || el.computed.display == 'none') return;
27090
27091        el.inited = true;
27092
27093        if (!el.clone) clone(el);
27094        if (el.parent.computed.position != 'absolute' &&
27095            el.parent.computed.position != 'relative') el.parent.node.style.position = 'relative';
27096
27097        recalcElementPos(el);
27098
27099        el.parent.height = el.parent.node.offsetHeight;
27100        el.docOffsetTop = getDocOffsetTop(el.clone);
27101    }
27102
27103    function deinitElement(el) {
27104        var deinitParent = true;
27105
27106        el.clone && killClone(el);
27107        mergeObjects(el.node.style, el.css);
27108
27109        //check whether element's parent is used by other stickies
27110        for (var i = watchArray.length - 1; i >= 0; i--) {
27111            if (watchArray[i].node !== el.node && watchArray[i].parent.node === el.parent.node) {
27112                deinitParent = false;
27113                break;
27114            }
27115        };
27116
27117        if (deinitParent) el.parent.node.style.position = el.parent.css.position;
27118        el.mode = -1;
27119    }
27120
27121    function initAll() {
27122        for (var i = watchArray.length - 1; i >= 0; i--) {
27123            initElement(watchArray[i]);
27124        }
27125    }
27126
27127    function deinitAll() {
27128        for (var i = watchArray.length - 1; i >= 0; i--) {
27129            deinitElement(watchArray[i]);
27130        }
27131    }
27132
27133    function switchElementMode(el, mode) {
27134        var nodeStyle = el.node.style;
27135
27136        switch (mode) {
27137            case 0:
27138                nodeStyle.position = 'absolute';
27139                nodeStyle.left = el.offset.left + 'px';
27140                nodeStyle.right = el.offset.right + 'px';
27141                nodeStyle.top = el.offset.top + 'px';
27142                nodeStyle.bottom = 'auto';
27143                nodeStyle.width = 'auto';
27144                nodeStyle.marginLeft = 0;
27145                nodeStyle.marginRight = 0;
27146                nodeStyle.marginTop = 0;
27147                break;
27148
27149            case 1:
27150                nodeStyle.position = 'fixed';
27151                nodeStyle.left = el.box.left + 'px';
27152                nodeStyle.right = el.box.right + 'px';
27153                nodeStyle.top = el.css.top;
27154                nodeStyle.bottom = 'auto';
27155                nodeStyle.width = 'auto';
27156                nodeStyle.marginLeft = 0;
27157                nodeStyle.marginRight = 0;
27158                nodeStyle.marginTop = 0;
27159                break;
27160
27161            case 2:
27162                nodeStyle.position = 'absolute';
27163                nodeStyle.left = el.offset.left + 'px';
27164                nodeStyle.right = el.offset.right + 'px';
27165                nodeStyle.top = 'auto';
27166                nodeStyle.bottom = 0;
27167                nodeStyle.width = 'auto';
27168                nodeStyle.marginLeft = 0;
27169                nodeStyle.marginRight = 0;
27170                break;
27171        }
27172
27173        el.mode = mode;
27174    }
27175
27176    function clone(el) {
27177        el.clone = document.createElement('div');
27178
27179        var refElement = el.node.nextSibling || el.node,
27180            cloneStyle = el.clone.style;
27181
27182        cloneStyle.height = el.height + 'px';
27183        cloneStyle.width = el.width + 'px';
27184        cloneStyle.marginTop = el.computed.marginTop;
27185        cloneStyle.marginBottom = el.computed.marginBottom;
27186        cloneStyle.marginLeft = el.computed.marginLeft;
27187        cloneStyle.marginRight = el.computed.marginRight;
27188        cloneStyle.padding = cloneStyle.border = cloneStyle.borderSpacing = 0;
27189        cloneStyle.fontSize = '1em';
27190        cloneStyle.position = 'static';
27191        cloneStyle.cssFloat = el.computed.cssFloat;
27192
27193        el.node.parentNode.insertBefore(el.clone, refElement);
27194    }
27195
27196    function killClone(el) {
27197        el.clone.parentNode.removeChild(el.clone);
27198        el.clone = undefined;
27199    }
27200
27201    function getElementParams(node) {
27202        var computedStyle = getComputedStyle(node),
27203            parentNode = node.parentNode,
27204            parentComputedStyle = getComputedStyle(parentNode),
27205            cachedPosition = node.style.position;
27206
27207        node.style.position = 'relative';
27208
27209        var computed = {
27210                top: computedStyle.top,
27211                marginTop: computedStyle.marginTop,
27212                marginBottom: computedStyle.marginBottom,
27213                marginLeft: computedStyle.marginLeft,
27214                marginRight: computedStyle.marginRight,
27215                cssFloat: computedStyle.cssFloat,
27216                display: computedStyle.display
27217            },
27218            numeric = {
27219                top: parseNumeric(computedStyle.top),
27220                marginBottom: parseNumeric(computedStyle.marginBottom),
27221                paddingLeft: parseNumeric(computedStyle.paddingLeft),
27222                paddingRight: parseNumeric(computedStyle.paddingRight),
27223                borderLeftWidth: parseNumeric(computedStyle.borderLeftWidth),
27224                borderRightWidth: parseNumeric(computedStyle.borderRightWidth)
27225            };
27226
27227        node.style.position = cachedPosition;
27228
27229        var css = {
27230                position: node.style.position,
27231                top: node.style.top,
27232                bottom: node.style.bottom,
27233                left: node.style.left,
27234                right: node.style.right,
27235                width: node.style.width,
27236                marginTop: node.style.marginTop,
27237                marginLeft: node.style.marginLeft,
27238                marginRight: node.style.marginRight
27239            },
27240            nodeOffset = getElementOffset(node),
27241            parentOffset = getElementOffset(parentNode),
27242
27243            parent = {
27244                node: parentNode,
27245                css: {
27246                    position: parentNode.style.position
27247                },
27248                computed: {
27249                    position: parentComputedStyle.position
27250                },
27251                numeric: {
27252                    borderLeftWidth: parseNumeric(parentComputedStyle.borderLeftWidth),
27253                    borderRightWidth: parseNumeric(parentComputedStyle.borderRightWidth),
27254                    borderTopWidth: parseNumeric(parentComputedStyle.borderTopWidth),
27255                    borderBottomWidth: parseNumeric(parentComputedStyle.borderBottomWidth)
27256                }
27257            },
27258
27259            el = {
27260                node: node,
27261                box: {
27262                    left: nodeOffset.win.left,
27263                    right: html.clientWidth - nodeOffset.win.right
27264                },
27265                offset: {
27266                    top: nodeOffset.win.top - parentOffset.win.top - parent.numeric.borderTopWidth,
27267                    left: nodeOffset.win.left - parentOffset.win.left - parent.numeric.borderLeftWidth,
27268                    right: -nodeOffset.win.right + parentOffset.win.right - parent.numeric.borderRightWidth
27269                },
27270                css: css,
27271                isCell: computedStyle.display == 'table-cell',
27272                computed: computed,
27273                numeric: numeric,
27274                width: nodeOffset.win.right - nodeOffset.win.left,
27275                height: nodeOffset.win.bottom - nodeOffset.win.top,
27276                mode: -1,
27277                inited: false,
27278                parent: parent,
27279                limit: {
27280                    start: nodeOffset.doc.top - numeric.top,
27281                    end: parentOffset.doc.top + parentNode.offsetHeight - parent.numeric.borderBottomWidth -
27282                        node.offsetHeight - numeric.top - numeric.marginBottom
27283                }
27284            };
27285
27286        return el;
27287    }
27288
27289    function getDocOffsetTop(node) {
27290        var docOffsetTop = 0;
27291
27292        while (node) {
27293            docOffsetTop += node.offsetTop;
27294            node = node.offsetParent;
27295        }
27296
27297        return docOffsetTop;
27298    }
27299
27300    function getElementOffset(node) {
27301        var box = node.getBoundingClientRect();
27302
27303            return {
27304                doc: {
27305                    top: box.top + win.pageYOffset,
27306                    left: box.left + win.pageXOffset
27307                },
27308                win: box
27309            };
27310    }
27311
27312    function startFastCheckTimer() {
27313        checkTimer = setInterval(function() {
27314            !fastCheck() && rebuild();
27315        }, 500);
27316    }
27317
27318    function stopFastCheckTimer() {
27319        clearInterval(checkTimer);
27320    }
27321
27322    function handlePageVisibilityChange() {
27323        if (!initialized) return;
27324
27325        if (document[hiddenPropertyName]) {
27326            stopFastCheckTimer();
27327        }
27328        else {
27329            startFastCheckTimer();
27330        }
27331    }
27332
27333    function init() {
27334        if (initialized) return;
27335
27336        updateScrollPos();
27337        initAll();
27338
27339        win.addEventListener('scroll', onScroll);
27340        win.addEventListener('wheel', onWheel);
27341
27342        //watch for width changes
27343        win.addEventListener('resize', rebuild);
27344        win.addEventListener('orientationchange', rebuild);
27345
27346        //watch for page visibility
27347        doc.addEventListener(visibilityChangeEventName, handlePageVisibilityChange);
27348
27349        startFastCheckTimer();
27350
27351        initialized = true;
27352    }
27353
27354    function rebuild() {
27355        if (!initialized) return;
27356
27357        deinitAll();
27358
27359        for (var i = watchArray.length - 1; i >= 0; i--) {
27360            watchArray[i] = getElementParams(watchArray[i].node);
27361        }
27362
27363        initAll();
27364    }
27365
27366    function pause() {
27367        win.removeEventListener('scroll', onScroll);
27368        win.removeEventListener('wheel', onWheel);
27369        win.removeEventListener('resize', rebuild);
27370        win.removeEventListener('orientationchange', rebuild);
27371        doc.removeEventListener(visibilityChangeEventName, handlePageVisibilityChange);
27372
27373        stopFastCheckTimer();
27374
27375        initialized = false;
27376    }
27377
27378    function stop() {
27379        pause();
27380        deinitAll();
27381    }
27382
27383    function kill() {
27384        stop();
27385
27386        //empty the array without loosing the references,
27387        //the most performant method according to http://jsperf.com/empty-javascript-array
27388        while (watchArray.length) {
27389            watchArray.pop();
27390        }
27391    }
27392
27393    function add(node) {
27394        //check if Stickyfill is already applied to the node
27395        for (var i = watchArray.length - 1; i >= 0; i--) {
27396            if (watchArray[i].node === node) return;
27397        };
27398
27399        var el = getElementParams(node);
27400
27401        watchArray.push(el);
27402
27403        if (!initialized) {
27404            init();
27405        }
27406        else {
27407            initElement(el);
27408        }
27409    }
27410
27411    function remove(node) {
27412        for (var i = watchArray.length - 1; i >= 0; i--) {
27413            if (watchArray[i].node === node) {
27414                deinitElement(watchArray[i]);
27415                watchArray.splice(i, 1);
27416            }
27417        };
27418    }
27419
27420    //expose Stickyfill
27421    win.Stickyfill = {
27422        stickies: watchArray,
27423        add: add,
27424        remove: remove,
27425        init: init,
27426        rebuild: rebuild,
27427        pause: pause,
27428        stop: stop,
27429        kill: kill
27430    };
27431})(document, window);
27432
27433
27434//if jQuery is available -- create a plugin
27435if (window.jQuery) {
27436    (function($) {
27437        $.fn.Stickyfill = function(options) {
27438            this.each(function() {
27439                Stickyfill.add(this);
27440            });
27441
27442            return this;
27443        };
27444    })(window.jQuery);
27445};
27446/*!
27447 * Select2 4.0.8
27448 * https://select2.github.io
27449 *
27450 * Released under the MIT license
27451 * https://github.com/select2/select2/blob/master/LICENSE.md
27452 */
27453;
vendor: 18,996 bytes, lines 27453-28022
27453(function (factory) {
27454  if (typeof define === 'function' && define.amd) {
27455    // AMD. Register as an anonymous module.
27456    define(['jquery'], factory);
27457  } else if (typeof module === 'object' && module.exports) {
27458    // Node/CommonJS
27459    module.exports = function (root, jQuery) {
27460      if (jQuery === undefined) {
27461        // require('jQuery') returns a factory that requires window to
27462        // build a jQuery instance, we normalize how we use modules
27463        // that require this pattern but the window provided is a noop
27464        // if it's defined (how jquery works)
27465        if (typeof window !== 'undefined') {
27466          jQuery = require('jquery');
27467        }
27468        else {
27469          jQuery = require('jquery')(root);
27470        }
27471      }
27472      factory(jQuery);
27473      return jQuery;
27474    };
27475  } else {
27476    // Browser globals
27477    factory(jQuery);
27478  }
27479} (function (jQuery) {
27480  // This is needed so we can catch the AMD loader configuration and use it
27481  // The inner file should be wrapped (by `banner.start.js`) in a function that
27482  // returns the AMD loader references.
27483  var S2 =(function () {
27484  // Restore the Select2 AMD loader so it can be used
27485  // Needed mostly in the language files, where the loader is not inserted
27486  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
27487    var S2 = jQuery.fn.select2.amd;
27488  }
27489var S2;(function () { if (!S2 || !S2.requirejs) {
27490if (!S2) { S2 = {}; } else { require = S2; }
27491/**
27492 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
27493 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
27494 */
27495//Going sloppy to avoid 'use strict' string cost, but strict practices should
27496//be followed.
27497/*global setTimeout: false */
27498
27499var requirejs, require, define;
27500(function (undef) {
27501    var main, req, makeMap, handlers,
27502        defined = {},
27503        waiting = {},
27504        config = {},
27505        defining = {},
27506        hasOwn = Object.prototype.hasOwnProperty,
27507        aps = [].slice,
27508        jsSuffixRegExp = /\.js$/;
27509
27510    function hasProp(obj, prop) {
27511        return hasOwn.call(obj, prop);
27512    }
27513
27514    /**
27515     * Given a relative module name, like ./something, normalize it to
27516     * a real name that can be mapped to a path.
27517     * @param {String} name the relative name
27518     * @param {String} baseName a real name that the name arg is relative
27519     * to.
27520     * @returns {String} normalized name
27521     */
27522    function normalize(name, baseName) {
27523        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
27524            foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
27525            baseParts = baseName && baseName.split("/"),
27526            map = config.map,
27527            starMap = (map && map['*']) || {};
27528
27529        //Adjust any relative paths.
27530        if (name) {
27531            name = name.split('/');
27532            lastIndex = name.length - 1;
27533
27534            // If wanting node ID compatibility, strip .js from end
27535            // of IDs. Have to do this here, and not in nameToUrl
27536            // because node allows either .js or non .js to map
27537            // to same file.
27538            if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
27539                name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
27540            }
27541
27542            // Starts with a '.' so need the baseName
27543            if (name[0].charAt(0) === '.' && baseParts) {
27544                //Convert baseName to array, and lop off the last part,
27545                //so that . matches that 'directory' and not name of the baseName's
27546                //module. For instance, baseName of 'one/two/three', maps to
27547                //'one/two/three.js', but we want the directory, 'one/two' for
27548                //this normalization.
27549                normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
27550                name = normalizedBaseParts.concat(name);
27551            }
27552
27553            //start trimDots
27554            for (i = 0; i < name.length; i++) {
27555                part = name[i];
27556                if (part === '.') {
27557                    name.splice(i, 1);
27558                    i -= 1;
27559                } else if (part === '..') {
27560                    // If at the start, or previous value is still ..,
27561                    // keep them so that when converted to a path it may
27562                    // still work when converted to a path, even though
27563                    // as an ID it is less than ideal. In larger point
27564                    // releases, may be better to just kick out an error.
27565                    if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
27566                        continue;
27567                    } else if (i > 0) {
27568                        name.splice(i - 1, 2);
27569                        i -= 2;
27570                    }
27571                }
27572            }
27573            //end trimDots
27574
27575            name = name.join('/');
27576        }
27577
27578        //Apply map config if available.
27579        if ((baseParts || starMap) && map) {
27580            nameParts = name.split('/');
27581
27582            for (i = nameParts.length; i > 0; i -= 1) {
27583                nameSegment = nameParts.slice(0, i).join("/");
27584
27585                if (baseParts) {
27586                    //Find the longest baseName segment match in the config.
27587                    //So, do joins on the biggest to smallest lengths of baseParts.
27588                    for (j = baseParts.length; j > 0; j -= 1) {
27589                        mapValue = map[baseParts.slice(0, j).join('/')];
27590
27591                        //baseName segment has  config, find if it has one for
27592                        //this name.
27593                        if (mapValue) {
27594                            mapValue = mapValue[nameSegment];
27595                            if (mapValue) {
27596                                //Match, update name to the new value.
27597                                foundMap = mapValue;
27598                                foundI = i;
27599                                break;
27600                            }
27601                        }
27602                    }
27603                }
27604
27605                if (foundMap) {
27606                    break;
27607                }
27608
27609                //Check for a star map match, but just hold on to it,
27610                //if there is a shorter segment match later in a matching
27611                //config, then favor over this star map.
27612                if (!foundStarMap && starMap && starMap[nameSegment]) {
27613                    foundStarMap = starMap[nameSegment];
27614                    starI = i;
27615                }
27616            }
27617
27618            if (!foundMap && foundStarMap) {
27619                foundMap = foundStarMap;
27620                foundI = starI;
27621            }
27622
27623            if (foundMap) {
27624                nameParts.splice(0, foundI, foundMap);
27625                name = nameParts.join('/');
27626            }
27627        }
27628
27629        return name;
27630    }
27631
27632    function makeRequire(relName, forceSync) {
27633        return function () {
27634            //A version of a require function that passes a moduleName
27635            //value for items that may need to
27636            //look up paths relative to the moduleName
27637            var args = aps.call(arguments, 0);
27638
27639            //If first arg is not require('string'), and there is only
27640            //one arg, it is the array form without a callback. Insert
27641            //a null so that the following concat is correct.
27642            if (typeof args[0] !== 'string' && args.length === 1) {
27643                args.push(null);
27644            }
27645            return req.apply(undef, args.concat([relName, forceSync]));
27646        };
27647    }
27648
27649    function makeNormalize(relName) {
27650        return function (name) {
27651            return normalize(name, relName);
27652        };
27653    }
27654
27655    function makeLoad(depName) {
27656        return function (value) {
27657            defined[depName] = value;
27658        };
27659    }
27660
27661    function callDep(name) {
27662        if (hasProp(waiting, name)) {
27663            var args = waiting[name];
27664            delete waiting[name];
27665            defining[name] = true;
27666            main.apply(undef, args);
27667        }
27668
27669        if (!hasProp(defined, name) && !hasProp(defining, name)) {
27670            throw new Error('No ' + name);
27671        }
27672        return defined[name];
27673    }
27674
27675    //Turns a plugin!resource to [plugin, resource]
27676    //with the plugin being undefined if the name
27677    //did not have a plugin prefix.
27678    function splitPrefix(name) {
27679        var prefix,
27680            index = name ? name.indexOf('!') : -1;
27681        if (index > -1) {
27682            prefix = name.substring(0, index);
27683            name = name.substring(index + 1, name.length);
27684        }
27685        return [prefix, name];
27686    }
27687
27688    //Creates a parts array for a relName where first part is plugin ID,
27689    //second part is resource ID. Assumes relName has already been normalized.
27690    function makeRelParts(relName) {
27691        return relName ? splitPrefix(relName) : [];
27692    }
27693
27694    /**
27695     * Makes a name map, normalizing the name, and using a plugin
27696     * for normalization if necessary. Grabs a ref to plugin
27697     * too, as an optimization.
27698     */
27699    makeMap = function (name, relParts) {
27700        var plugin,
27701            parts = splitPrefix(name),
27702            prefix = parts[0],
27703            relResourceName = relParts[1];
27704
27705        name = parts[1];
27706
27707        if (prefix) {
27708            prefix = normalize(prefix, relResourceName);
27709            plugin = callDep(prefix);
27710        }
27711
27712        //Normalize according
27713        if (prefix) {
27714            if (plugin && plugin.normalize) {
27715                name = plugin.normalize(name, makeNormalize(relResourceName));
27716            } else {
27717                name = normalize(name, relResourceName);
27718            }
27719        } else {
27720            name = normalize(name, relResourceName);
27721            parts = splitPrefix(name);
27722            prefix = parts[0];
27723            name = parts[1];
27724            if (prefix) {
27725                plugin = callDep(prefix);
27726            }
27727        }
27728
27729        //Using ridiculous property names for space reasons
27730        return {
27731            f: prefix ? prefix + '!' + name : name, //fullName
27732            n: name,
27733            pr: prefix,
27734            p: plugin
27735        };
27736    };
27737
27738    function makeConfig(name) {
27739        return function () {
27740            return (config && config.config && config.config[name]) || {};
27741        };
27742    }
27743
27744    handlers = {
27745        require: function (name) {
27746            return makeRequire(name);
27747        },
27748        exports: function (name) {
27749            var e = defined[name];
27750            if (typeof e !== 'undefined') {
27751                return e;
27752            } else {
27753                return (defined[name] = {});
27754            }
27755        },
27756        module: function (name) {
27757            return {
27758                id: name,
27759                uri: '',
27760                exports: defined[name],
27761                config: makeConfig(name)
27762            };
27763        }
27764    };
27765
27766    main = function (name, deps, callback, relName) {
27767        var cjsModule, depName, ret, map, i, relParts,
27768            args = [],
27769            callbackType = typeof callback,
27770            usingExports;
27771
27772        //Use name if no relName
27773        relName = relName || name;
27774        relParts = makeRelParts(relName);
27775
27776        //Call the callback to define the module, if necessary.
27777        if (callbackType === 'undefined' || callbackType === 'function') {
27778            //Pull out the defined dependencies and pass the ordered
27779            //values to the callback.
27780            //Default to [require, exports, module] if no deps
27781            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
27782            for (i = 0; i < deps.length; i += 1) {
27783                map = makeMap(deps[i], relParts);
27784                depName = map.f;
27785
27786                //Fast path CommonJS standard dependencies.
27787                if (depName === "require") {
27788                    args[i] = handlers.require(name);
27789                } else if (depName === "exports") {
27790                    //CommonJS module spec 1.1
27791                    args[i] = handlers.exports(name);
27792                    usingExports = true;
27793                } else if (depName === "module") {
27794                    //CommonJS module spec 1.1
27795                    cjsModule = args[i] = handlers.module(name);
27796                } else if (hasProp(defined, depName) ||
27797                           hasProp(waiting, depName) ||
27798                           hasProp(defining, depName)) {
27799                    args[i] = callDep(depName);
27800                } else if (map.p) {
27801                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
27802                    args[i] = defined[depName];
27803                } else {
27804                    throw new Error(name + ' missing ' + depName);
27805                }
27806            }
27807
27808            ret = callback ? callback.apply(defined[name], args) : undefined;
27809
27810            if (name) {
27811                //If setting exports via "module" is in play,
27812                //favor that over return value and exports. After that,
27813                //favor a non-undefined return value over exports use.
27814                if (cjsModule && cjsModule.exports !== undef &&
27815                        cjsModule.exports !== defined[name]) {
27816                    defined[name] = cjsModule.exports;
27817                } else if (ret !== undef || !usingExports) {
27818                    //Use the return value from the function.
27819                    defined[name] = ret;
27820                }
27821            }
27822        } else if (name) {
27823            //May just be an object definition for the module. Only
27824            //worry about defining if have a module name.
27825            defined[name] = callback;
27826        }
27827    };
27828
27829    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
27830        if (typeof deps === "string") {
27831            if (handlers[deps]) {
27832                //callback in this case is really relName
27833                return handlers[deps](callback);
27834            }
27835            //Just return the module wanted. In this scenario, the
27836            //deps arg is the module name, and second arg (if passed)
27837            //is just the relName.
27838            //Normalize module name, if it contains . or ..
27839            return callDep(makeMap(deps, makeRelParts(callback)).f);
27840        } else if (!deps.splice) {
27841            //deps is a config object, not an array.
27842            config = deps;
27843            if (config.deps) {
27844                req(config.deps, config.callback);
27845            }
27846            if (!callback) {
27847                return;
27848            }
27849
27850            if (callback.splice) {
27851                //callback is an array, which means it is a dependency list.
27852                //Adjust args if there are dependencies
27853                deps = callback;
27854                callback = relName;
27855                relName = null;
27856            } else {
27857                deps = undef;
27858            }
27859        }
27860
27861        //Support require(['a'])
27862        callback = callback || function () {};
27863
27864        //If relName is a function, it is an errback handler,
27865        //so remove it.
27866        if (typeof relName === 'function') {
27867            relName = forceSync;
27868            forceSync = alt;
27869        }
27870
27871        //Simulate async callback;
27872        if (forceSync) {
27873            main(undef, deps, callback, relName);
27874        } else {
27875            //Using a non-zero value because of concern for what old browsers
27876            //do, and latest browsers "upgrade" to 4 if lower value is used:
27877            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
27878            //If want a value immediately, use require('id') instead -- something
27879            //that works in almond on the global level, but not guaranteed and
27880            //unlikely to work in other AMD implementations.
27881            setTimeout(function () {
27882                main(undef, deps, callback, relName);
27883            }, 4);
27884        }
27885
27886        return req;
27887    };
27888
27889    /**
27890     * Just drops the config on the floor, but returns req in case
27891     * the config return value is used.
27892     */
27893    req.config = function (cfg) {
27894        return req(cfg);
27895    };
27896
27897    /**
27898     * Expose module registry for debugging and tooling
27899     */
27900    requirejs._defined = defined;
27901
27902    define = function (name, deps, callback) {
27903        if (typeof name !== 'string') {
27904            throw new Error('See almond README: incorrect module build, no module name');
27905        }
27906
27907        //This module may not have dependencies
27908        if (!deps.splice) {
27909            //deps is not an array, so probably means
27910            //an object literal or factory function for
27911            //the value. Adjust args.
27912            callback = deps;
27913            deps = [];
27914        }
27915
27916        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
27917            waiting[name] = [name, deps, callback];
27918        }
27919    };
27920
27921    define.amd = {
27922        jQuery: true
27923    };
27924}());
27925
27926S2.requirejs = requirejs;S2.require = require;S2.define = define;
27927}
27928}());
27929S2.define("almond", function(){});
27930
27931/* global jQuery:false, $:false */
27932S2.define('jquery',[],function () {
27933  var _$ = jQuery || $;
27934
27935  if (_$ == null && console && console.error) {
27936    console.error(
27937      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
27938      'found. Make sure that you are including jQuery before Select2 on your ' +
27939      'web page.'
27940    );
27941  }
27942
27943  return _$;
27944});
27945
27946S2.define('select2/utils',[
27947  'jquery'
27948], function ($) {
27949  var Utils = {};
27950
27951  Utils.Extend = function (ChildClass, SuperClass) {
27952    var __hasProp = {}.hasOwnProperty;
27953
27954    function BaseConstructor () {
27955      this.constructor = ChildClass;
27956    }
27957
27958    for (var key in SuperClass) {
27959      if (__hasProp.call(SuperClass, key)) {
27960        ChildClass[key] = SuperClass[key];
27961      }
27962    }
27963
27964    BaseConstructor.prototype = SuperClass.prototype;
27965    ChildClass.prototype = new BaseConstructor();
27966    ChildClass.__super__ = SuperClass.prototype;
27967
27968    return ChildClass;
27969  };
27970
27971  function getMethods (theClass) {
27972    var proto = theClass.prototype;
27973
27974    var methods = [];
27975
27976    for (var methodName in proto) {
27977      var m = proto[methodName];
27978
27979      if (typeof m !== 'function') {
27980        continue;
27981      }
27982
27983      if (methodName === 'constructor') {
27984        continue;
27985      }
27986
27987      methods.push(methodName);
27988    }
27989
27990    return methods;
27991  }
27992
27993  Utils.Decorate = function (SuperClass, DecoratorClass) {
27994    var decoratedMethods = getMethods(DecoratorClass);
27995    var superMethods = getMethods(SuperClass);
27996
27997    function DecoratedClass () {
27998      var unshift = Array.prototype.unshift;
27999
28000      var argCount = DecoratorClass.prototype.constructor.length;
28001
28002      var calledConstructor = SuperClass.prototype.constructor;
28003
28004      if (argCount > 0) {
28005        unshift.call(arguments, SuperClass.prototype.constructor);
28006
28007        calledConstructor = DecoratorClass.prototype.constructor;
28008      }
28009
28010      calledConstructor.apply(this, arguments);
28011    }
28012
28013    DecoratorClass.displayName = SuperClass.displayName;
28014
28015    function ctr () {
28016      this.constructor = DecoratedClass;
28017    }
28018
28019    DecoratedClass.prototype = new ctr();
28020
28021    for (var m = 0; m < superMethods.length; m++) {
28022      
vendor: 3,385 bytes, lines 28022-28159
28022var superMethod = superMethods[m];
28023
28024      DecoratedClass.prototype[superMethod] =
28025        SuperClass.prototype[superMethod];
28026    }
28027
28028    var calledMethod = function (methodName) {
28029      // Stub out the original method if it's not decorating an actual method
28030      var originalMethod = function () {};
28031
28032      if (methodName in DecoratedClass.prototype) {
28033        originalMethod = DecoratedClass.prototype[methodName];
28034      }
28035
28036      var decoratedMethod = DecoratorClass.prototype[methodName];
28037
28038      return function () {
28039        var unshift = Array.prototype.unshift;
28040
28041        unshift.call(arguments, originalMethod);
28042
28043        return decoratedMethod.apply(this, arguments);
28044      };
28045    };
28046
28047    for (var d = 0; d < decoratedMethods.length; d++) {
28048      var decoratedMethod = decoratedMethods[d];
28049
28050      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
28051    }
28052
28053    return DecoratedClass;
28054  };
28055
28056  var Observable = function () {
28057    this.listeners = {};
28058  };
28059
28060  Observable.prototype.on = function (event, callback) {
28061    this.listeners = this.listeners || {};
28062
28063    if (event in this.listeners) {
28064      this.listeners[event].push(callback);
28065    } else {
28066      this.listeners[event] = [callback];
28067    }
28068  };
28069
28070  Observable.prototype.trigger = function (event) {
28071    var slice = Array.prototype.slice;
28072    var params = slice.call(arguments, 1);
28073
28074    this.listeners = this.listeners || {};
28075
28076    // Params should always come in as an array
28077    if (params == null) {
28078      params = [];
28079    }
28080
28081    // If there are no arguments to the event, use a temporary object
28082    if (params.length === 0) {
28083      params.push({});
28084    }
28085
28086    // Set the `_type` of the first object to the event
28087    params[0]._type = event;
28088
28089    if (event in this.listeners) {
28090      this.invoke(this.listeners[event], slice.call(arguments, 1));
28091    }
28092
28093    if ('*' in this.listeners) {
28094      this.invoke(this.listeners['*'], arguments);
28095    }
28096  };
28097
28098  Observable.prototype.invoke = function (listeners, params) {
28099    for (var i = 0, len = listeners.length; i < len; i++) {
28100      listeners[i].apply(this, params);
28101    }
28102  };
28103
28104  Utils.Observable = Observable;
28105
28106  Utils.generateChars = function (length) {
28107    var chars = '';
28108
28109    for (var i = 0; i < length; i++) {
28110      var randomChar = Math.floor(Math.random() * 36);
28111      chars += randomChar.toString(36);
28112    }
28113
28114    return chars;
28115  };
28116
28117  Utils.bind = function (func, context) {
28118    return function () {
28119      func.apply(context, arguments);
28120    };
28121  };
28122
28123  Utils._convertData = function (data) {
28124    for (var originalKey in data) {
28125      var keys = originalKey.split('-');
28126
28127      var dataLevel = data;
28128
28129      if (keys.length === 1) {
28130        continue;
28131      }
28132
28133      for (var k = 0; k < keys.length; k++) {
28134        var key = keys[k];
28135
28136        // Lowercase the first letter
28137        // By default, dash-separated becomes camelCase
28138        key = key.substring(0, 1).toLowerCase() + key.substring(1);
28139
28140        if (!(key in dataLevel)) {
28141          dataLevel[key] = {};
28142        }
28143
28144        if (k == keys.length - 1) {
28145          dataLevel[key] = data[originalKey];
28146        }
28147
28148        dataLevel = dataLevel[key];
28149      }
28150
28151      delete data[originalKey];
28152    }
28153
28154    return data;
28155  };
28156
28157  Utils.hasScroll = function (index, el) {
28158    // Adapted from the function created by @ShadowScripter
28159    // and adapted by @BillBarry on the Stack Exchange Code Review website.
28160    // The original code can be found at
28161    // http://codereview.stackexchange.com/q/13338
28162    // and was designed to be used with the Sizzle selector engine.
28163
28164    var $el = $(el);
28165    var overflowX = el.style.overflowX;
28166    var overflowY = el.style.overflowY;
28167
28168    //Check both x and y declarations
28169    if (overflowX === overflowY &&
28170        (overflowY === 'hidden' || overflowY === 'visible')) {
28171      return false;
28172    }
28173
28174    if (overflowX === 'scroll' || overflowY === 'scroll') {
28175      return true;
28176    }
28177
28178    return ($el.innerHeight() < el.scrollHeight ||
28179      $el.innerWidth() < el.scrollWidth);
28180  };
28181
28182  Utils.escapeMarkup = function (markup) {
28183    var replaceMap = {
28184      '\\': '&#92;',
28185      '&': '&amp;',
28186      '<': '&lt;',
28187      '>': '&gt;',
28188      '"': '&quot;',
28189      '\'': '&#39;',
28190      '/': '&#47;'
28191    };
28192
28193    // Do not try to escape the markup if it's not a string
28194    if (typeof markup !== 'string') {
28195      return markup;
28196    }
28197
28198    return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
28199      return replaceMap[match];
28200    });
28201  };
28202
28203  // Append an array of jQuery nodes to a given element.
28204  Utils.appendMany = function ($element, $nodes) {
28205    // jQuery 1.7.x does not support $.fn.append() with an array
28206    // Fall back to a jQuery object collection using $.fn.add()
28207    if ($.fn.jquery.substr(0, 3) === '1.7') {
28208      var $jqNodes = $();
28209
28210      $.map($nodes, function (node) {
28211        $jqNodes = $jqNodes.add(node);
28212      });
28213
28214      $nodes = $jqNodes;
28215    }
28216
28217    $element.append($nodes);
28218  };
28219
28220  // Cache objects in Utils.__cache instead of $.data (see #4346)
28221  Utils.__cache = {};
28222
28223  var id = 0;
28224  Utils.GetUniqueElementId = function (element) {
28225    // Get a unique element Id. If element has no id,
28226    // creates a new unique number, stores it in the id
28227    // attribute and returns the new id.
28228    // If an id already exists, it simply returns it.
28229
28230    var select2Id = element.getAttribute('data-select2-id');
28231    if (select2Id == null) {
28232      // If element has id, use it.
28233      if (element.id) {
28234        select2Id = element.id;
28235        element.setAttribute('data-select2-id', select2Id);
28236      } else {
28237        element.setAttribute('data-select2-id', ++id);
28238        select2Id = id.toString();
28239      }
28240    }
28241    return select2Id;
28242  };
28243
28244  Utils.StoreData = function (element, name, value) {
28245    // Stores an item in the cache for a specified element.
28246    // name is the cache key.
28247    var id = Utils.GetUniqueElementId(element);
28248    if (!Utils.__cache[id]) {
28249      Utils.__cache[id] = {};
28250    }
28251
28252    Utils.__cache[id][name] = value;
28253  };
28254
28255  Utils.GetData = function (element, name) {
28256    // Retrieves a value from the cache by its key (name)
28257    // name is optional. If no name specified, return
28258    // all cache items for the specified element.
28259    // and for a specified element.
28260    var id = Utils.GetUniqueElementId(element);
28261    if (name) {
28262      if (Utils.__cache[id]) {
28263        if (Utils.__cache[id][name] != null) {
28264          return Utils.__cache[id][name];
28265        }
28266        return $(element).data(name); // Fallback to HTML5 data attribs.
28267      }
28268      return $(element).data(name); // Fallback to HTML5 data attribs.
28269    } else {
28270      return Utils.__cache[id];
28271    }
28272  };
28273
28274  Utils.RemoveData = function (element) {
28275    // Removes all cached items for a specified element.
28276    var id = Utils.GetUniqueElementId(element);
28277    if (Utils.__cache[id] != null) {
28278      delete Utils.__cache[id];
28279    }
28280  };
28281
28282  return Utils;
28283});
28284
28285S2.define('select2/results',[
28286  'jquery',
28287  './utils'
28288], function ($, Utils) {
28289  function Results ($element, options, dataAdapter) {
28290    this.$element = $element;
28291    this.data = dataAdapter;
28292    this.options = options;
28293
28294    Results.__super__.constructor.call(this);
28295  }
28296
28297  Utils.Extend(Results, Utils.Observable);
28298
28299  Results.prototype.render = function () {
28300    var $results = $(
28301      '<ul class="select2-results__options" role="tree"></ul>'
28302    );
28303
28304    if (this.options.get('multiple')) {
28305      $results.attr('aria-multiselectable', 'true');
28306    }
28307
28308    this.$results = $results;
28309
28310    return $results;
28311  };
28312
28313  Results.prototype.clear = function () {
28314    this.$results.empty();
28315  };
28316
28317  Results.prototype.displayMessage = function (params) {
28318    var escapeMarkup = this.options.get('escapeMarkup');
28319
28320    this.clear();
28321    this.hideLoading();
28322
28323    var $message = $(
28324      '<li role="treeitem" aria-live="assertive"' +
28325      ' class="select2-results__option"></li>'
28326    );
28327
28328    var message = this.options.get('translations').get(params.message);
28329
28330    $message.append(
28331      escapeMarkup(
28332        message(params.args)
28333      )
28334    );
28335
28336    $message[0].className += ' select2-results__message';
vendor: 84,279 bytes, lines 28337-31938
28337
28338    this.$results.append($message);
28339  };
28340
28341  Results.prototype.hideMessages = function () {
28342    this.$results.find('.select2-results__message').remove();
28343  };
28344
28345  Results.prototype.append = function (data) {
28346    this.hideLoading();
28347
28348    var $options = [];
28349
28350    if (data.results == null || data.results.length === 0) {
28351      if (this.$results.children().length === 0) {
28352        this.trigger('results:message', {
28353          message: 'noResults'
28354        });
28355      }
28356
28357      return;
28358    }
28359
28360    data.results = this.sort(data.results);
28361
28362    for (var d = 0; d < data.results.length; d++) {
28363      var item = data.results[d];
28364
28365      var $option = this.option(item);
28366
28367      $options.push($option);
28368    }
28369
28370    this.$results.append($options);
28371  };
28372
28373  Results.prototype.position = function ($results, $dropdown) {
28374    var $resultsContainer = $dropdown.find('.select2-results');
28375    $resultsContainer.append($results);
28376  };
28377
28378  Results.prototype.sort = function (data) {
28379    var sorter = this.options.get('sorter');
28380
28381    return sorter(data);
28382  };
28383
28384  Results.prototype.highlightFirstItem = function () {
28385    var $options = this.$results
28386      .find('.select2-results__option[aria-selected]');
28387
28388    var $selected = $options.filter('[aria-selected=true]');
28389
28390    // Check if there are any selected options
28391    if ($selected.length > 0) {
28392      // If there are selected options, highlight the first
28393      $selected.first().trigger('mouseenter');
28394    } else {
28395      // If there are no selected options, highlight the first option
28396      // in the dropdown
28397      $options.first().trigger('mouseenter');
28398    }
28399
28400    this.ensureHighlightVisible();
28401  };
28402
28403  Results.prototype.setClasses = function () {
28404    var self = this;
28405
28406    this.data.current(function (selected) {
28407      var selectedIds = $.map(selected, function (s) {
28408        return s.id.toString();
28409      });
28410
28411      var $options = self.$results
28412        .find('.select2-results__option[aria-selected]');
28413
28414      $options.each(function () {
28415        var $option = $(this);
28416
28417        var item = Utils.GetData(this, 'data');
28418
28419        // id needs to be converted to a string when comparing
28420        var id = '' + item.id;
28421
28422        if ((item.element != null && item.element.selected) ||
28423            (item.element == null && $.inArray(id, selectedIds) > -1)) {
28424          $option.attr('aria-selected', 'true');
28425        } else {
28426          $option.attr('aria-selected', 'false');
28427        }
28428      });
28429
28430    });
28431  };
28432
28433  Results.prototype.showLoading = function (params) {
28434    this.hideLoading();
28435
28436    var loadingMore = this.options.get('translations').get('searching');
28437
28438    var loading = {
28439      disabled: true,
28440      loading: true,
28441      text: loadingMore(params)
28442    };
28443    var $loading = this.option(loading);
28444    $loading.className += ' loading-results';
28445
28446    this.$results.prepend($loading);
28447  };
28448
28449  Results.prototype.hideLoading = function () {
28450    this.$results.find('.loading-results').remove();
28451  };
28452
28453  Results.prototype.option = function (data) {
28454    var option = document.createElement('li');
28455    option.className = 'select2-results__option';
28456
28457    var attrs = {
28458      'role': 'treeitem',
28459      'aria-selected': 'false'
28460    };
28461
28462    var matches = window.Element.prototype.matches ||
28463      window.Element.prototype.msMatchesSelector ||
28464      window.Element.prototype.webkitMatchesSelector;
28465
28466    if ((data.element != null && matches.call(data.element, ':disabled')) ||
28467        (data.element == null && data.disabled)) {
28468      delete attrs['aria-selected'];
28469      attrs['aria-disabled'] = 'true';
28470    }
28471
28472    if (data.id == null) {
28473      delete attrs['aria-selected'];
28474    }
28475
28476    if (data._resultId != null) {
28477      option.id = data._resultId;
28478    }
28479
28480    if (data.title) {
28481      option.title = data.title;
28482    }
28483
28484    if (data.children) {
28485      attrs.role = 'group';
28486      attrs['aria-label'] = data.text;
28487      delete attrs['aria-selected'];
28488    }
28489
28490    for (var attr in attrs) {
28491      var val = attrs[attr];
28492
28493      option.setAttribute(attr, val);
28494    }
28495
28496    if (data.children) {
28497      var $option = $(option);
28498
28499      var label = document.createElement('strong');
28500      label.className = 'select2-results__group';
28501
28502      var $label = $(label);
28503      this.template(data, label);
28504
28505      var $children = [];
28506
28507      for (var c = 0; c < data.children.length; c++) {
28508        var child = data.children[c];
28509
28510        var $child = this.option(child);
28511
28512        $children.push($child);
28513      }
28514
28515      var $childrenContainer = $('<ul></ul>', {
28516        'class': 'select2-results__options select2-results__options--nested'
28517      });
28518
28519      $childrenContainer.append($children);
28520
28521      $option.append(label);
28522      $option.append($childrenContainer);
28523    } else {
28524      this.template(data, option);
28525    }
28526
28527    Utils.StoreData(option, 'data', data);
28528
28529    return option;
28530  };
28531
28532  Results.prototype.bind = function (container, $container) {
28533    var self = this;
28534
28535    var id = container.id + '-results';
28536
28537    this.$results.attr('id', id);
28538
28539    container.on('results:all', function (params) {
28540      self.clear();
28541      self.append(params.data);
28542
28543      if (container.isOpen()) {
28544        self.setClasses();
28545        self.highlightFirstItem();
28546      }
28547    });
28548
28549    container.on('results:append', function (params) {
28550      self.append(params.data);
28551
28552      if (container.isOpen()) {
28553        self.setClasses();
28554      }
28555    });
28556
28557    container.on('query', function (params) {
28558      self.hideMessages();
28559      self.showLoading(params);
28560    });
28561
28562    container.on('select', function () {
28563      if (!container.isOpen()) {
28564        return;
28565      }
28566
28567      self.setClasses();
28568
28569      if (self.options.get('scrollAfterSelect')) {
28570        self.highlightFirstItem();
28571      }
28572    });
28573
28574    container.on('unselect', function () {
28575      if (!container.isOpen()) {
28576        return;
28577      }
28578
28579      self.setClasses();
28580
28581      if (self.options.get('scrollAfterSelect')) {
28582        self.highlightFirstItem();
28583      }
28584    });
28585
28586    container.on('open', function () {
28587      // When the dropdown is open, aria-expended="true"
28588      self.$results.attr('aria-expanded', 'true');
28589      self.$results.attr('aria-hidden', 'false');
28590
28591      self.setClasses();
28592      self.ensureHighlightVisible();
28593    });
28594
28595    container.on('close', function () {
28596      // When the dropdown is closed, aria-expended="false"
28597      self.$results.attr('aria-expanded', 'false');
28598      self.$results.attr('aria-hidden', 'true');
28599      self.$results.removeAttr('aria-activedescendant');
28600    });
28601
28602    container.on('results:toggle', function () {
28603      var $highlighted = self.getHighlightedResults();
28604
28605      if ($highlighted.length === 0) {
28606        return;
28607      }
28608
28609      $highlighted.trigger('mouseup');
28610    });
28611
28612    container.on('results:select', function () {
28613      var $highlighted = self.getHighlightedResults();
28614
28615      if ($highlighted.length === 0) {
28616        return;
28617      }
28618
28619      var data = Utils.GetData($highlighted[0], 'data');
28620
28621      if ($highlighted.attr('aria-selected') == 'true') {
28622        self.trigger('close', {});
28623      } else {
28624        self.trigger('select', {
28625          data: data
28626        });
28627      }
28628    });
28629
28630    container.on('results:previous', function () {
28631      var $highlighted = self.getHighlightedResults();
28632
28633      var $options = self.$results.find('[aria-selected]');
28634
28635      var currentIndex = $options.index($highlighted);
28636
28637      // If we are already at the top, don't move further
28638      // If no options, currentIndex will be -1
28639      if (currentIndex <= 0) {
28640        return;
28641      }
28642
28643      var nextIndex = currentIndex - 1;
28644
28645      // If none are highlighted, highlight the first
28646      if ($highlighted.length === 0) {
28647        nextIndex = 0;
28648      }
28649
28650      var $next = $options.eq(nextIndex);
28651
28652      $next.trigger('mouseenter');
28653
28654      var currentOffset = self.$results.offset().top;
28655      var nextTop = $next.offset().top;
28656      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
28657
28658      if (nextIndex === 0) {
28659        self.$results.scrollTop(0);
28660      } else if (nextTop - currentOffset < 0) {
28661        self.$results.scrollTop(nextOffset);
28662      }
28663    });
28664
28665    container.on('results:next', function () {
28666      var $highlighted = self.getHighlightedResults();
28667
28668      var $options = self.$results.find('[aria-selected]');
28669
28670      var currentIndex = $options.index($highlighted);
28671
28672      var nextIndex = currentIndex + 1;
28673
28674      // If we are at the last option, stay there
28675      if (nextIndex >= $options.length) {
28676        return;
28677      }
28678
28679      var $next = $options.eq(nextIndex);
28680
28681      $next.trigger('mouseenter');
28682
28683      var currentOffset = self.$results.offset().top +
28684        self.$results.outerHeight(false);
28685      var nextBottom = $next.offset().top + $next.outerHeight(false);
28686      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
28687
28688      if (nextIndex === 0) {
28689        self.$results.scrollTop(0);
28690      } else if (nextBottom > currentOffset) {
28691        self.$results.scrollTop(nextOffset);
28692      }
28693    });
28694
28695    container.on('results:focus', function (params) {
28696      params.element.addClass('select2-results__option--highlighted');
28697    });
28698
28699    container.on('results:message', function (params) {
28700      self.displayMessage(params);
28701    });
28702
28703    if ($.fn.mousewheel) {
28704      this.$results.on('mousewheel', function (e) {
28705        var top = self.$results.scrollTop();
28706
28707        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
28708
28709        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
28710        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
28711
28712        if (isAtTop) {
28713          self.$results.scrollTop(0);
28714
28715          e.preventDefault();
28716          e.stopPropagation();
28717        } else if (isAtBottom) {
28718          self.$results.scrollTop(
28719            self.$results.get(0).scrollHeight - self.$results.height()
28720          );
28721
28722          e.preventDefault();
28723          e.stopPropagation();
28724        }
28725      });
28726    }
28727
28728    this.$results.on('mouseup', '.select2-results__option[aria-selected]',
28729      function (evt) {
28730      var $this = $(this);
28731
28732      var data = Utils.GetData(this, 'data');
28733
28734      if ($this.attr('aria-selected') === 'true') {
28735        if (self.options.get('multiple')) {
28736          self.trigger('unselect', {
28737            originalEvent: evt,
28738            data: data
28739          });
28740        } else {
28741          self.trigger('close', {});
28742        }
28743
28744        return;
28745      }
28746
28747      self.trigger('select', {
28748        originalEvent: evt,
28749        data: data
28750      });
28751    });
28752
28753    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
28754      function (evt) {
28755      var data = Utils.GetData(this, 'data');
28756
28757      self.getHighlightedResults()
28758          .removeClass('select2-results__option--highlighted');
28759
28760      self.trigger('results:focus', {
28761        data: data,
28762        element: $(this)
28763      });
28764    });
28765  };
28766
28767  Results.prototype.getHighlightedResults = function () {
28768    var $highlighted = this.$results
28769    .find('.select2-results__option--highlighted');
28770
28771    return $highlighted;
28772  };
28773
28774  Results.prototype.destroy = function () {
28775    this.$results.remove();
28776  };
28777
28778  Results.prototype.ensureHighlightVisible = function () {
28779    var $highlighted = this.getHighlightedResults();
28780
28781    if ($highlighted.length === 0) {
28782      return;
28783    }
28784
28785    var $options = this.$results.find('[aria-selected]');
28786
28787    var currentIndex = $options.index($highlighted);
28788
28789    var currentOffset = this.$results.offset().top;
28790    var nextTop = $highlighted.offset().top;
28791    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
28792
28793    var offsetDelta = nextTop - currentOffset;
28794    nextOffset -= $highlighted.outerHeight(false) * 2;
28795
28796    if (currentIndex <= 2) {
28797      this.$results.scrollTop(0);
28798    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
28799      this.$results.scrollTop(nextOffset);
28800    }
28801  };
28802
28803  Results.prototype.template = function (result, container) {
28804    var template = this.options.get('templateResult');
28805    var escapeMarkup = this.options.get('escapeMarkup');
28806
28807    var content = template(result, container);
28808
28809    if (content == null) {
28810      container.style.display = 'none';
28811    } else if (typeof content === 'string') {
28812      container.innerHTML = escapeMarkup(content);
28813    } else {
28814      $(container).append(content);
28815    }
28816  };
28817
28818  return Results;
28819});
28820
28821S2.define('select2/keys',[
28822
28823], function () {
28824  var KEYS = {
28825    BACKSPACE: 8,
28826    TAB: 9,
28827    ENTER: 13,
28828    SHIFT: 16,
28829    CTRL: 17,
28830    ALT: 18,
28831    ESC: 27,
28832    SPACE: 32,
28833    PAGE_UP: 33,
28834    PAGE_DOWN: 34,
28835    END: 35,
28836    HOME: 36,
28837    LEFT: 37,
28838    UP: 38,
28839    RIGHT: 39,
28840    DOWN: 40,
28841    DELETE: 46
28842  };
28843
28844  return KEYS;
28845});
28846
28847S2.define('select2/selection/base',[
28848  'jquery',
28849  '../utils',
28850  '../keys'
28851], function ($, Utils, KEYS) {
28852  function BaseSelection ($element, options) {
28853    this.$element = $element;
28854    this.options = options;
28855
28856    BaseSelection.__super__.constructor.call(this);
28857  }
28858
28859  Utils.Extend(BaseSelection, Utils.Observable);
28860
28861  BaseSelection.prototype.render = function () {
28862    var $selection = $(
28863      '<span class="select2-selection" role="combobox" ' +
28864      ' aria-haspopup="true" aria-expanded="false">' +
28865      '</span>'
28866    );
28867
28868    this._tabindex = 0;
28869
28870    if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
28871      this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
28872    } else if (this.$element.attr('tabindex') != null) {
28873      this._tabindex = this.$element.attr('tabindex');
28874    }
28875
28876    $selection.attr('title', this.$element.attr('title'));
28877    $selection.attr('tabindex', this._tabindex);
28878
28879    this.$selection = $selection;
28880
28881    return $selection;
28882  };
28883
28884  BaseSelection.prototype.bind = function (container, $container) {
28885    var self = this;
28886
28887    var id = container.id + '-container';
28888    var resultsId = container.id + '-results';
28889
28890    this.container = container;
28891
28892    this.$selection.on('focus', function (evt) {
28893      self.trigger('focus', evt);
28894    });
28895
28896    this.$selection.on('blur', function (evt) {
28897      self._handleBlur(evt);
28898    });
28899
28900    this.$selection.on('keydown', function (evt) {
28901      self.trigger('keypress', evt);
28902
28903      if (evt.which === KEYS.SPACE) {
28904        evt.preventDefault();
28905      }
28906    });
28907
28908    container.on('results:focus', function (params) {
28909      self.$selection.attr('aria-activedescendant', params.data._resultId);
28910    });
28911
28912    container.on('selection:update', function (params) {
28913      self.update(params.data);
28914    });
28915
28916    container.on('open', function () {
28917      // When the dropdown is open, aria-expanded="true"
28918      self.$selection.attr('aria-expanded', 'true');
28919      self.$selection.attr('aria-owns', resultsId);
28920
28921      self._attachCloseHandler(container);
28922    });
28923
28924    container.on('close', function () {
28925      // When the dropdown is closed, aria-expanded="false"
28926      self.$selection.attr('aria-expanded', 'false');
28927      self.$selection.removeAttr('aria-activedescendant');
28928      self.$selection.removeAttr('aria-owns');
28929
28930      self.$selection.trigger('focus');
28931
28932      self._detachCloseHandler(container);
28933    });
28934
28935    container.on('enable', function () {
28936      self.$selection.attr('tabindex', self._tabindex);
28937    });
28938
28939    container.on('disable', function () {
28940      self.$selection.attr('tabindex', '-1');
28941    });
28942  };
28943
28944  BaseSelection.prototype._handleBlur = function (evt) {
28945    var self = this;
28946
28947    // This needs to be delayed as the active element is the body when the tab
28948    // key is pressed, possibly along with others.
28949    window.setTimeout(function () {
28950      // Don't trigger `blur` if the focus is still in the selection
28951      if (
28952        (document.activeElement == self.$selection[0]) ||
28953        ($.contains(self.$selection[0], document.activeElement))
28954      ) {
28955        return;
28956      }
28957
28958      self.trigger('blur', evt);
28959    }, 1);
28960  };
28961
28962  BaseSelection.prototype._attachCloseHandler = function (container) {
28963    var self = this;
28964
28965    $(document.body).on('mousedown.select2.' + container.id, function (e) {
28966      var $target = $(e.target);
28967
28968      var $select = $target.closest('.select2');
28969
28970      var $all = $('.select2.select2-container--open');
28971
28972      $all.each(function () {
28973        var $this = $(this);
28974
28975        if (this == $select[0]) {
28976          return;
28977        }
28978
28979        var $element = Utils.GetData(this, 'element');
28980
28981        $element.select2('close');
28982      });
28983    });
28984  };
28985
28986  BaseSelection.prototype._detachCloseHandler = function (container) {
28987    $(document.body).off('mousedown.select2.' + container.id);
28988  };
28989
28990  BaseSelection.prototype.position = function ($selection, $container) {
28991    var $selectionContainer = $container.find('.selection');
28992    $selectionContainer.append($selection);
28993  };
28994
28995  BaseSelection.prototype.destroy = function () {
28996    this._detachCloseHandler(this.container);
28997  };
28998
28999  BaseSelection.prototype.update = function (data) {
29000    throw new Error('The `update` method must be defined in child classes.');
29001  };
29002
29003  return BaseSelection;
29004});
29005
29006S2.define('select2/selection/single',[
29007  'jquery',
29008  './base',
29009  '../utils',
29010  '../keys'
29011], function ($, BaseSelection, Utils, KEYS) {
29012  function SingleSelection () {
29013    SingleSelection.__super__.constructor.apply(this, arguments);
29014  }
29015
29016  Utils.Extend(SingleSelection, BaseSelection);
29017
29018  SingleSelection.prototype.render = function () {
29019    var $selection = SingleSelection.__super__.render.call(this);
29020
29021    $selection.addClass('select2-selection--single');
29022
29023    $selection.html(
29024      '<span class="select2-selection__rendered"></span>' +
29025      '<span class="select2-selection__arrow" role="presentation">' +
29026        '<b role="presentation"></b>' +
29027      '</span>'
29028    );
29029
29030    return $selection;
29031  };
29032
29033  SingleSelection.prototype.bind = function (container, $container) {
29034    var self = this;
29035
29036    SingleSelection.__super__.bind.apply(this, arguments);
29037
29038    var id = container.id + '-container';
29039
29040    this.$selection.find('.select2-selection__rendered')
29041      .attr('id', id)
29042      .attr('role', 'textbox')
29043      .attr('aria-readonly', 'true');
29044    this.$selection.attr('aria-labelledby', id);
29045
29046    this.$selection.on('mousedown', function (evt) {
29047      // Only respond to left clicks
29048      if (evt.which !== 1) {
29049        return;
29050      }
29051
29052      self.trigger('toggle', {
29053        originalEvent: evt
29054      });
29055    });
29056
29057    this.$selection.on('focus', function (evt) {
29058      // User focuses on the container
29059    });
29060
29061    this.$selection.on('blur', function (evt) {
29062      // User exits the container
29063    });
29064
29065    container.on('focus', function (evt) {
29066      if (!container.isOpen()) {
29067        self.$selection.trigger('focus');
29068      }
29069    });
29070  };
29071
29072  SingleSelection.prototype.clear = function () {
29073    var $rendered = this.$selection.find('.select2-selection__rendered');
29074    $rendered.empty();
29075    $rendered.removeAttr('title'); // clear tooltip on empty
29076  };
29077
29078  SingleSelection.prototype.display = function (data, container) {
29079    var template = this.options.get('templateSelection');
29080    var escapeMarkup = this.options.get('escapeMarkup');
29081
29082    return escapeMarkup(template(data, container));
29083  };
29084
29085  SingleSelection.prototype.selectionContainer = function () {
29086    return $('<span></span>');
29087  };
29088
29089  SingleSelection.prototype.update = function (data) {
29090    if (data.length === 0) {
29091      this.clear();
29092      return;
29093    }
29094
29095    var selection = data[0];
29096
29097    var $rendered = this.$selection.find('.select2-selection__rendered');
29098    var formatted = this.display(selection, $rendered);
29099
29100    $rendered.empty().append(formatted);
29101    $rendered.attr('title', selection.title || selection.text);
29102  };
29103
29104  return SingleSelection;
29105});
29106
29107S2.define('select2/selection/multiple',[
29108  'jquery',
29109  './base',
29110  '../utils'
29111], function ($, BaseSelection, Utils) {
29112  function MultipleSelection ($element, options) {
29113    MultipleSelection.__super__.constructor.apply(this, arguments);
29114  }
29115
29116  Utils.Extend(MultipleSelection, BaseSelection);
29117
29118  MultipleSelection.prototype.render = function () {
29119    var $selection = MultipleSelection.__super__.render.call(this);
29120
29121    $selection.addClass('select2-selection--multiple');
29122
29123    $selection.html(
29124      '<ul class="select2-selection__rendered"></ul>'
29125    );
29126
29127    return $selection;
29128  };
29129
29130  MultipleSelection.prototype.bind = function (container, $container) {
29131    var self = this;
29132
29133    MultipleSelection.__super__.bind.apply(this, arguments);
29134
29135    this.$selection.on('click', function (evt) {
29136      self.trigger('toggle', {
29137        originalEvent: evt
29138      });
29139    });
29140
29141    this.$selection.on(
29142      'click',
29143      '.select2-selection__choice__remove',
29144      function (evt) {
29145        // Ignore the event if it is disabled
29146        if (self.options.get('disabled')) {
29147          return;
29148        }
29149
29150        var $remove = $(this);
29151        var $selection = $remove.parent();
29152
29153        var data = Utils.GetData($selection[0], 'data');
29154
29155        self.trigger('unselect', {
29156          originalEvent: evt,
29157          data: data
29158        });
29159      }
29160    );
29161  };
29162
29163  MultipleSelection.prototype.clear = function () {
29164    var $rendered = this.$selection.find('.select2-selection__rendered');
29165    $rendered.empty();
29166    $rendered.removeAttr('title');
29167  };
29168
29169  MultipleSelection.prototype.display = function (data, container) {
29170    var template = this.options.get('templateSelection');
29171    var escapeMarkup = this.options.get('escapeMarkup');
29172
29173    return escapeMarkup(template(data, container));
29174  };
29175
29176  MultipleSelection.prototype.selectionContainer = function () {
29177    var $container = $(
29178      '<li class="select2-selection__choice">' +
29179        '<span class="select2-selection__choice__remove" role="presentation">' +
29180          '&times;' +
29181        '</span>' +
29182      '</li>'
29183    );
29184
29185    return $container;
29186  };
29187
29188  MultipleSelection.prototype.update = function (data) {
29189    this.clear();
29190
29191    if (data.length === 0) {
29192      return;
29193    }
29194
29195    var $selections = [];
29196
29197    for (var d = 0; d < data.length; d++) {
29198      var selection = data[d];
29199
29200      var $selection = this.selectionContainer();
29201      var formatted = this.display(selection, $selection);
29202
29203      $selection.append(formatted);
29204      $selection.attr('title', selection.title || selection.text);
29205
29206      Utils.StoreData($selection[0], 'data', selection);
29207
29208      $selections.push($selection);
29209    }
29210
29211    var $rendered = this.$selection.find('.select2-selection__rendered');
29212
29213    Utils.appendMany($rendered, $selections);
29214  };
29215
29216  return MultipleSelection;
29217});
29218
29219S2.define('select2/selection/placeholder',[
29220  '../utils'
29221], function (Utils) {
29222  function Placeholder (decorated, $element, options) {
29223    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
29224
29225    decorated.call(this, $element, options);
29226  }
29227
29228  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
29229    if (typeof placeholder === 'string') {
29230      placeholder = {
29231        id: '',
29232        text: placeholder
29233      };
29234    }
29235
29236    return placeholder;
29237  };
29238
29239  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
29240    var $placeholder = this.selectionContainer();
29241
29242    $placeholder.html(this.display(placeholder));
29243    $placeholder.addClass('select2-selection__placeholder')
29244                .removeClass('select2-selection__choice');
29245
29246    return $placeholder;
29247  };
29248
29249  Placeholder.prototype.update = function (decorated, data) {
29250    var singlePlaceholder = (
29251      data.length == 1 && data[0].id != this.placeholder.id
29252    );
29253    var multipleSelections = data.length > 1;
29254
29255    if (multipleSelections || singlePlaceholder) {
29256      return decorated.call(this, data);
29257    }
29258
29259    this.clear();
29260
29261    var $placeholder = this.createPlaceholder(this.placeholder);
29262
29263    this.$selection.find('.select2-selection__rendered').append($placeholder);
29264  };
29265
29266  return Placeholder;
29267});
29268
29269S2.define('select2/selection/allowClear',[
29270  'jquery',
29271  '../keys',
29272  '../utils'
29273], function ($, KEYS, Utils) {
29274  function AllowClear () { }
29275
29276  AllowClear.prototype.bind = function (decorated, container, $container) {
29277    var self = this;
29278
29279    decorated.call(this, container, $container);
29280
29281    if (this.placeholder == null) {
29282      if (this.options.get('debug') && window.console && console.error) {
29283        console.error(
29284          'Select2: The `allowClear` option should be used in combination ' +
29285          'with the `placeholder` option.'
29286        );
29287      }
29288    }
29289
29290    this.$selection.on('mousedown', '.select2-selection__clear',
29291      function (evt) {
29292        self._handleClear(evt);
29293    });
29294
29295    container.on('keypress', function (evt) {
29296      self._handleKeyboardClear(evt, container);
29297    });
29298  };
29299
29300  AllowClear.prototype._handleClear = function (_, evt) {
29301    // Ignore the event if it is disabled
29302    if (this.options.get('disabled')) {
29303      return;
29304    }
29305
29306    var $clear = this.$selection.find('.select2-selection__clear');
29307
29308    // Ignore the event if nothing has been selected
29309    if ($clear.length === 0) {
29310      return;
29311    }
29312
29313    evt.stopPropagation();
29314
29315    var data = Utils.GetData($clear[0], 'data');
29316
29317    var previousVal = this.$element.val();
29318    this.$element.val(this.placeholder.id);
29319
29320    var unselectData = {
29321      data: data
29322    };
29323    this.trigger('clear', unselectData);
29324    if (unselectData.prevented) {
29325      this.$element.val(previousVal);
29326      return;
29327    }
29328
29329    for (var d = 0; d < data.length; d++) {
29330      unselectData = {
29331        data: data[d]
29332      };
29333
29334      // Trigger the `unselect` event, so people can prevent it from being
29335      // cleared.
29336      this.trigger('unselect', unselectData);
29337
29338      // If the event was prevented, don't clear it out.
29339      if (unselectData.prevented) {
29340        this.$element.val(previousVal);
29341        return;
29342      }
29343    }
29344
29345    this.$element.trigger('change');
29346
29347    this.trigger('toggle', {});
29348  };
29349
29350  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
29351    if (container.isOpen()) {
29352      return;
29353    }
29354
29355    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
29356      this._handleClear(evt);
29357    }
29358  };
29359
29360  AllowClear.prototype.update = function (decorated, data) {
29361    decorated.call(this, data);
29362
29363    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
29364        data.length === 0) {
29365      return;
29366    }
29367
29368    var removeAll = this.options.get('translations').get('removeAllItems');
29369
29370    var $remove = $(
29371      '<span class="select2-selection__clear" title="' + removeAll() +'">' +
29372        '&times;' +
29373      '</span>'
29374    );
29375    Utils.StoreData($remove[0], 'data', data);
29376
29377    this.$selection.find('.select2-selection__rendered').prepend($remove);
29378  };
29379
29380  return AllowClear;
29381});
29382
29383S2.define('select2/selection/search',[
29384  'jquery',
29385  '../utils',
29386  '../keys'
29387], function ($, Utils, KEYS) {
29388  function Search (decorated, $element, options) {
29389    decorated.call(this, $element, options);
29390  }
29391
29392  Search.prototype.render = function (decorated) {
29393    var $search = $(
29394      '<li class="select2-search select2-search--inline">' +
29395        '<input class="select2-search__field" type="search" tabindex="-1"' +
29396        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
29397        ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
29398      '</li>'
29399    );
29400
29401    this.$searchContainer = $search;
29402    this.$search = $search.find('input');
29403
29404    var $rendered = decorated.call(this);
29405
29406    this._transferTabIndex();
29407
29408    return $rendered;
29409  };
29410
29411  Search.prototype.bind = function (decorated, container, $container) {
29412    var self = this;
29413
29414    decorated.call(this, container, $container);
29415
29416    container.on('open', function () {
29417      self.$search.trigger('focus');
29418    });
29419
29420    container.on('close', function () {
29421      self.$search.val('');
29422      self.$search.removeAttr('aria-activedescendant');
29423      self.$search.trigger('focus');
29424    });
29425
29426    container.on('enable', function () {
29427      self.$search.prop('disabled', false);
29428
29429      self._transferTabIndex();
29430    });
29431
29432    container.on('disable', function () {
29433      self.$search.prop('disabled', true);
29434    });
29435
29436    container.on('focus', function (evt) {
29437      self.$search.trigger('focus');
29438    });
29439
29440    container.on('results:focus', function (params) {
29441      self.$search.attr('aria-activedescendant', params.id);
29442    });
29443
29444    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
29445      self.trigger('focus', evt);
29446    });
29447
29448    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
29449      self._handleBlur(evt);
29450    });
29451
29452    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
29453      evt.stopPropagation();
29454
29455      self.trigger('keypress', evt);
29456
29457      self._keyUpPrevented = evt.isDefaultPrevented();
29458
29459      var key = evt.which;
29460
29461      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
29462        var $previousChoice = self.$searchContainer
29463          .prev('.select2-selection__choice');
29464
29465        if ($previousChoice.length > 0) {
29466          var item = Utils.GetData($previousChoice[0], 'data');
29467
29468          self.searchRemoveChoice(item);
29469
29470          evt.preventDefault();
29471        }
29472      }
29473    });
29474
29475    // Try to detect the IE version should the `documentMode` property that
29476    // is stored on the document. This is only implemented in IE and is
29477    // slightly cleaner than doing a user agent check.
29478    // This property is not available in Edge, but Edge also doesn't have
29479    // this bug.
29480    var msie = document.documentMode;
29481    var disableInputEvents = msie && msie <= 11;
29482
29483    // Workaround for browsers which do not support the `input` event
29484    // This will prevent double-triggering of events for browsers which support
29485    // both the `keyup` and `input` events.
29486    this.$selection.on(
29487      'input.searchcheck',
29488      '.select2-search--inline',
29489      function (evt) {
29490        // IE will trigger the `input` event when a placeholder is used on a
29491        // search box. To get around this issue, we are forced to ignore all
29492        // `input` events in IE and keep using `keyup`.
29493        if (disableInputEvents) {
29494          self.$selection.off('input.search input.searchcheck');
29495          return;
29496        }
29497
29498        // Unbind the duplicated `keyup` event
29499        self.$selection.off('keyup.search');
29500      }
29501    );
29502
29503    this.$selection.on(
29504      'keyup.search input.search',
29505      '.select2-search--inline',
29506      function (evt) {
29507        // IE will trigger the `input` event when a placeholder is used on a
29508        // search box. To get around this issue, we are forced to ignore all
29509        // `input` events in IE and keep using `keyup`.
29510        if (disableInputEvents && evt.type === 'input') {
29511          self.$selection.off('input.search input.searchcheck');
29512          return;
29513        }
29514
29515        var key = evt.which;
29516
29517        // We can freely ignore events from modifier keys
29518        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
29519          return;
29520        }
29521
29522        // Tabbing will be handled during the `keydown` phase
29523        if (key == KEYS.TAB) {
29524          return;
29525        }
29526
29527        self.handleSearch(evt);
29528      }
29529    );
29530  };
29531
29532  /**
29533   * This method will transfer the tabindex attribute from the rendered
29534   * selection to the search box. This allows for the search box to be used as
29535   * the primary focus instead of the selection container.
29536   *
29537   * @private
29538   */
29539  Search.prototype._transferTabIndex = function (decorated) {
29540    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
29541    this.$selection.attr('tabindex', '-1');
29542  };
29543
29544  Search.prototype.createPlaceholder = function (decorated, placeholder) {
29545    this.$search.attr('placeholder', placeholder.text);
29546  };
29547
29548  Search.prototype.update = function (decorated, data) {
29549    var searchHadFocus = this.$search[0] == document.activeElement;
29550
29551    this.$search.attr('placeholder', '');
29552
29553    decorated.call(this, data);
29554
29555    this.$selection.find('.select2-selection__rendered')
29556                   .append(this.$searchContainer);
29557
29558    this.resizeSearch();
29559    if (searchHadFocus) {
29560      this.$search.trigger('focus');
29561    }
29562  };
29563
29564  Search.prototype.handleSearch = function () {
29565    this.resizeSearch();
29566
29567    if (!this._keyUpPrevented) {
29568      var input = this.$search.val();
29569
29570      this.trigger('query', {
29571        term: input
29572      });
29573    }
29574
29575    this._keyUpPrevented = false;
29576  };
29577
29578  Search.prototype.searchRemoveChoice = function (decorated, item) {
29579    this.trigger('unselect', {
29580      data: item
29581    });
29582
29583    this.$search.val(item.text);
29584    this.handleSearch();
29585  };
29586
29587  Search.prototype.resizeSearch = function () {
29588    this.$search.css('width', '25px');
29589
29590    var width = '';
29591
29592    if (this.$search.attr('placeholder') !== '') {
29593      width = this.$selection.find('.select2-selection__rendered').innerWidth();
29594    } else {
29595      var minimumWidth = this.$search.val().length + 1;
29596
29597      width = (minimumWidth * 0.75) + 'em';
29598    }
29599
29600    this.$search.css('width', width);
29601  };
29602
29603  return Search;
29604});
29605
29606S2.define('select2/selection/eventRelay',[
29607  'jquery'
29608], function ($) {
29609  function EventRelay () { }
29610
29611  EventRelay.prototype.bind = function (decorated, container, $container) {
29612    var self = this;
29613    var relayEvents = [
29614      'open', 'opening',
29615      'close', 'closing',
29616      'select', 'selecting',
29617      'unselect', 'unselecting',
29618      'clear', 'clearing'
29619    ];
29620
29621    var preventableEvents = [
29622      'opening', 'closing', 'selecting', 'unselecting', 'clearing'
29623    ];
29624
29625    decorated.call(this, container, $container);
29626
29627    container.on('*', function (name, params) {
29628      // Ignore events that should not be relayed
29629      if ($.inArray(name, relayEvents) === -1) {
29630        return;
29631      }
29632
29633      // The parameters should always be an object
29634      params = params || {};
29635
29636      // Generate the jQuery event for the Select2 event
29637      var evt = $.Event('select2:' + name, {
29638        params: params
29639      });
29640
29641      self.$element.trigger(evt);
29642
29643      // Only handle preventable events if it was one
29644      if ($.inArray(name, preventableEvents) === -1) {
29645        return;
29646      }
29647
29648      params.prevented = evt.isDefaultPrevented();
29649    });
29650  };
29651
29652  return EventRelay;
29653});
29654
29655S2.define('select2/translation',[
29656  'jquery',
29657  'require'
29658], function ($, require) {
29659  function Translation (dict) {
29660    this.dict = dict || {};
29661  }
29662
29663  Translation.prototype.all = function () {
29664    return this.dict;
29665  };
29666
29667  Translation.prototype.get = function (key) {
29668    return this.dict[key];
29669  };
29670
29671  Translation.prototype.extend = function (translation) {
29672    this.dict = $.extend({}, translation.all(), this.dict);
29673  };
29674
29675  // Static functions
29676
29677  Translation._cache = {};
29678
29679  Translation.loadPath = function (path) {
29680    if (!(path in Translation._cache)) {
29681      var translations = require(path);
29682
29683      Translation._cache[path] = translations;
29684    }
29685
29686    return new Translation(Translation._cache[path]);
29687  };
29688
29689  return Translation;
29690});
29691
29692S2.define('select2/diacritics',[
29693
29694], function () {
29695  var diacritics = {
29696    '\u24B6': 'A',
29697    '\uFF21': 'A',
29698    '\u00C0': 'A',
29699    '\u00C1': 'A',
29700    '\u00C2': 'A',
29701    '\u1EA6': 'A',
29702    '\u1EA4': 'A',
29703    '\u1EAA': 'A',
29704    '\u1EA8': 'A',
29705    '\u00C3': 'A',
29706    '\u0100': 'A',
29707    '\u0102': 'A',
29708    '\u1EB0': 'A',
29709    '\u1EAE': 'A',
29710    '\u1EB4': 'A',
29711    '\u1EB2': 'A',
29712    '\u0226': 'A',
29713    '\u01E0': 'A',
29714    '\u00C4': 'A',
29715    '\u01DE': 'A',
29716    '\u1EA2': 'A',
29717    '\u00C5': 'A',
29718    '\u01FA': 'A',
29719    '\u01CD': 'A',
29720    '\u0200': 'A',
29721    '\u0202': 'A',
29722    '\u1EA0': 'A',
29723    '\u1EAC': 'A',
29724    '\u1EB6': 'A',
29725    '\u1E00': 'A',
29726    '\u0104': 'A',
29727    '\u023A': 'A',
29728    '\u2C6F': 'A',
29729    '\uA732': 'AA',
29730    '\u00C6': 'AE',
29731    '\u01FC': 'AE',
29732    '\u01E2': 'AE',
29733    '\uA734': 'AO',
29734    '\uA736': 'AU',
29735    '\uA738': 'AV',
29736    '\uA73A': 'AV',
29737    '\uA73C': 'AY',
29738    '\u24B7': 'B',
29739    '\uFF22': 'B',
29740    '\u1E02': 'B',
29741    '\u1E04': 'B',
29742    '\u1E06': 'B',
29743    '\u0243': 'B',
29744    '\u0182': 'B',
29745    '\u0181': 'B',
29746    '\u24B8': 'C',
29747    '\uFF23': 'C',
29748    '\u0106': 'C',
29749    '\u0108': 'C',
29750    '\u010A': 'C',
29751    '\u010C': 'C',
29752    '\u00C7': 'C',
29753    '\u1E08': 'C',
29754    '\u0187': 'C',
29755    '\u023B': 'C',
29756    '\uA73E': 'C',
29757    '\u24B9': 'D',
29758    '\uFF24': 'D',
29759    '\u1E0A': 'D',
29760    '\u010E': 'D',
29761    '\u1E0C': 'D',
29762    '\u1E10': 'D',
29763    '\u1E12': 'D',
29764    '\u1E0E': 'D',
29765    '\u0110': 'D',
29766    '\u018B': 'D',
29767    '\u018A': 'D',
29768    '\u0189': 'D',
29769    '\uA779': 'D',
29770    '\u01F1': 'DZ',
29771    '\u01C4': 'DZ',
29772    '\u01F2': 'Dz',
29773    '\u01C5': 'Dz',
29774    '\u24BA': 'E',
29775    '\uFF25': 'E',
29776    '\u00C8': 'E',
29777    '\u00C9': 'E',
29778    '\u00CA': 'E',
29779    '\u1EC0': 'E',
29780    '\u1EBE': 'E',
29781    '\u1EC4': 'E',
29782    '\u1EC2': 'E',
29783    '\u1EBC': 'E',
29784    '\u0112': 'E',
29785    '\u1E14': 'E',
29786    '\u1E16': 'E',
29787    '\u0114': 'E',
29788    '\u0116': 'E',
29789    '\u00CB': 'E',
29790    '\u1EBA': 'E',
29791    '\u011A': 'E',
29792    '\u0204': 'E',
29793    '\u0206': 'E',
29794    '\u1EB8': 'E',
29795    '\u1EC6': 'E',
29796    '\u0228': 'E',
29797    '\u1E1C': 'E',
29798    '\u0118': 'E',
29799    '\u1E18': 'E',
29800    '\u1E1A': 'E',
29801    '\u0190': 'E',
29802    '\u018E': 'E',
29803    '\u24BB': 'F',
29804    '\uFF26': 'F',
29805    '\u1E1E': 'F',
29806    '\u0191': 'F',
29807    '\uA77B': 'F',
29808    '\u24BC': 'G',
29809    '\uFF27': 'G',
29810    '\u01F4': 'G',
29811    '\u011C': 'G',
29812    '\u1E20': 'G',
29813    '\u011E': 'G',
29814    '\u0120': 'G',
29815    '\u01E6': 'G',
29816    '\u0122': 'G',
29817    '\u01E4': 'G',
29818    '\u0193': 'G',
29819    '\uA7A0': 'G',
29820    '\uA77D': 'G',
29821    '\uA77E': 'G',
29822    '\u24BD': 'H',
29823    '\uFF28': 'H',
29824    '\u0124': 'H',
29825    '\u1E22': 'H',
29826    '\u1E26': 'H',
29827    '\u021E': 'H',
29828    '\u1E24': 'H',
29829    '\u1E28': 'H',
29830    '\u1E2A': 'H',
29831    '\u0126': 'H',
29832    '\u2C67': 'H',
29833    '\u2C75': 'H',
29834    '\uA78D': 'H',
29835    '\u24BE': 'I',
29836    '\uFF29': 'I',
29837    '\u00CC': 'I',
29838    '\u00CD': 'I',
29839    '\u00CE': 'I',
29840    '\u0128': 'I',
29841    '\u012A': 'I',
29842    '\u012C': 'I',
29843    '\u0130': 'I',
29844    '\u00CF': 'I',
29845    '\u1E2E': 'I',
29846    '\u1EC8': 'I',
29847    '\u01CF': 'I',
29848    '\u0208': 'I',
29849    '\u020A': 'I',
29850    '\u1ECA': 'I',
29851    '\u012E': 'I',
29852    '\u1E2C': 'I',
29853    '\u0197': 'I',
29854    '\u24BF': 'J',
29855    '\uFF2A': 'J',
29856    '\u0134': 'J',
29857    '\u0248': 'J',
29858    '\u24C0': 'K',
29859    '\uFF2B': 'K',
29860    '\u1E30': 'K',
29861    '\u01E8': 'K',
29862    '\u1E32': 'K',
29863    '\u0136': 'K',
29864    '\u1E34': 'K',
29865    '\u0198': 'K',
29866    '\u2C69': 'K',
29867    '\uA740': 'K',
29868    '\uA742': 'K',
29869    '\uA744': 'K',
29870    '\uA7A2': 'K',
29871    '\u24C1': 'L',
29872    '\uFF2C': 'L',
29873    '\u013F': 'L',
29874    '\u0139': 'L',
29875    '\u013D': 'L',
29876    '\u1E36': 'L',
29877    '\u1E38': 'L',
29878    '\u013B': 'L',
29879    '\u1E3C': 'L',
29880    '\u1E3A': 'L',
29881    '\u0141': 'L',
29882    '\u023D': 'L',
29883    '\u2C62': 'L',
29884    '\u2C60': 'L',
29885    '\uA748': 'L',
29886    '\uA746': 'L',
29887    '\uA780': 'L',
29888    '\u01C7': 'LJ',
29889    '\u01C8': 'Lj',
29890    '\u24C2': 'M',
29891    '\uFF2D': 'M',
29892    '\u1E3E': 'M',
29893    '\u1E40': 'M',
29894    '\u1E42': 'M',
29895    '\u2C6E': 'M',
29896    '\u019C': 'M',
29897    '\u24C3': 'N',
29898    '\uFF2E': 'N',
29899    '\u01F8': 'N',
29900    '\u0143': 'N',
29901    '\u00D1': 'N',
29902    '\u1E44': 'N',
29903    '\u0147': 'N',
29904    '\u1E46': 'N',
29905    '\u0145': 'N',
29906    '\u1E4A': 'N',
29907    '\u1E48': 'N',
29908    '\u0220': 'N',
29909    '\u019D': 'N',
29910    '\uA790': 'N',
29911    '\uA7A4': 'N',
29912    '\u01CA': 'NJ',
29913    '\u01CB': 'Nj',
29914    '\u24C4': 'O',
29915    '\uFF2F': 'O',
29916    '\u00D2': 'O',
29917    '\u00D3': 'O',
29918    '\u00D4': 'O',
29919    '\u1ED2': 'O',
29920    '\u1ED0': 'O',
29921    '\u1ED6': 'O',
29922    '\u1ED4': 'O',
29923    '\u00D5': 'O',
29924    '\u1E4C': 'O',
29925    '\u022C': 'O',
29926    '\u1E4E': 'O',
29927    '\u014C': 'O',
29928    '\u1E50': 'O',
29929    '\u1E52': 'O',
29930    '\u014E': 'O',
29931    '\u022E': 'O',
29932    '\u0230': 'O',
29933    '\u00D6': 'O',
29934    '\u022A': 'O',
29935    '\u1ECE': 'O',
29936    '\u0150': 'O',
29937    '\u01D1': 'O',
29938    '\u020C': 'O',
29939    '\u020E': 'O',
29940    '\u01A0': 'O',
29941    '\u1EDC': 'O',
29942    '\u1EDA': 'O',
29943    '\u1EE0': 'O',
29944    '\u1EDE': 'O',
29945    '\u1EE2': 'O',
29946    '\u1ECC': 'O',
29947    '\u1ED8': 'O',
29948    '\u01EA': 'O',
29949    '\u01EC': 'O',
29950    '\u00D8': 'O',
29951    '\u01FE': 'O',
29952    '\u0186': 'O',
29953    '\u019F': 'O',
29954    '\uA74A': 'O',
29955    '\uA74C': 'O',
29956    '\u0152': 'OE',
29957    '\u01A2': 'OI',
29958    '\uA74E': 'OO',
29959    '\u0222': 'OU',
29960    '\u24C5': 'P',
29961    '\uFF30': 'P',
29962    '\u1E54': 'P',
29963    '\u1E56': 'P',
29964    '\u01A4': 'P',
29965    '\u2C63': 'P',
29966    '\uA750': 'P',
29967    '\uA752': 'P',
29968    '\uA754': 'P',
29969    '\u24C6': 'Q',
29970    '\uFF31': 'Q',
29971    '\uA756': 'Q',
29972    '\uA758': 'Q',
29973    '\u024A': 'Q',
29974    '\u24C7': 'R',
29975    '\uFF32': 'R',
29976    '\u0154': 'R',
29977    '\u1E58': 'R',
29978    '\u0158': 'R',
29979    '\u0210': 'R',
29980    '\u0212': 'R',
29981    '\u1E5A': 'R',
29982    '\u1E5C': 'R',
29983    '\u0156': 'R',
29984    '\u1E5E': 'R',
29985    '\u024C': 'R',
29986    '\u2C64': 'R',
29987    '\uA75A': 'R',
29988    '\uA7A6': 'R',
29989    '\uA782': 'R',
29990    '\u24C8': 'S',
29991    '\uFF33': 'S',
29992    '\u1E9E': 'S',
29993    '\u015A': 'S',
29994    '\u1E64': 'S',
29995    '\u015C': 'S',
29996    '\u1E60': 'S',
29997    '\u0160': 'S',
29998    '\u1E66': 'S',
29999    '\u1E62': 'S',
30000    '\u1E68': 'S',
30001    '\u0218': 'S',
30002    '\u015E': 'S',
30003    '\u2C7E': 'S',
30004    '\uA7A8': 'S',
30005    '\uA784': 'S',
30006    '\u24C9': 'T',
30007    '\uFF34': 'T',
30008    '\u1E6A': 'T',
30009    '\u0164': 'T',
30010    '\u1E6C': 'T',
30011    '\u021A': 'T',
30012    '\u0162': 'T',
30013    '\u1E70': 'T',
30014    '\u1E6E': 'T',
30015    '\u0166': 'T',
30016    '\u01AC': 'T',
30017    '\u01AE': 'T',
30018    '\u023E': 'T',
30019    '\uA786': 'T',
30020    '\uA728': 'TZ',
30021    '\u24CA': 'U',
30022    '\uFF35': 'U',
30023    '\u00D9': 'U',
30024    '\u00DA': 'U',
30025    '\u00DB': 'U',
30026    '\u0168': 'U',
30027    '\u1E78': 'U',
30028    '\u016A': 'U',
30029    '\u1E7A': 'U',
30030    '\u016C': 'U',
30031    '\u00DC': 'U',
30032    '\u01DB': 'U',
30033    '\u01D7': 'U',
30034    '\u01D5': 'U',
30035    '\u01D9': 'U',
30036    '\u1EE6': 'U',
30037    '\u016E': 'U',
30038    '\u0170': 'U',
30039    '\u01D3': 'U',
30040    '\u0214': 'U',
30041    '\u0216': 'U',
30042    '\u01AF': 'U',
30043    '\u1EEA': 'U',
30044    '\u1EE8': 'U',
30045    '\u1EEE': 'U',
30046    '\u1EEC': 'U',
30047    '\u1EF0': 'U',
30048    '\u1EE4': 'U',
30049    '\u1E72': 'U',
30050    '\u0172': 'U',
30051    '\u1E76': 'U',
30052    '\u1E74': 'U',
30053    '\u0244': 'U',
30054    '\u24CB': 'V',
30055    '\uFF36': 'V',
30056    '\u1E7C': 'V',
30057    '\u1E7E': 'V',
30058    '\u01B2': 'V',
30059    '\uA75E': 'V',
30060    '\u0245': 'V',
30061    '\uA760': 'VY',
30062    '\u24CC': 'W',
30063    '\uFF37': 'W',
30064    '\u1E80': 'W',
30065    '\u1E82': 'W',
30066    '\u0174': 'W',
30067    '\u1E86': 'W',
30068    '\u1E84': 'W',
30069    '\u1E88': 'W',
30070    '\u2C72': 'W',
30071    '\u24CD': 'X',
30072    '\uFF38': 'X',
30073    '\u1E8A': 'X',
30074    '\u1E8C': 'X',
30075    '\u24CE': 'Y',
30076    '\uFF39': 'Y',
30077    '\u1EF2': 'Y',
30078    '\u00DD': 'Y',
30079    '\u0176': 'Y',
30080    '\u1EF8': 'Y',
30081    '\u0232': 'Y',
30082    '\u1E8E': 'Y',
30083    '\u0178': 'Y',
30084    '\u1EF6': 'Y',
30085    '\u1EF4': 'Y',
30086    '\u01B3': 'Y',
30087    '\u024E': 'Y',
30088    '\u1EFE': 'Y',
30089    '\u24CF': 'Z',
30090    '\uFF3A': 'Z',
30091    '\u0179': 'Z',
30092    '\u1E90': 'Z',
30093    '\u017B': 'Z',
30094    '\u017D': 'Z',
30095    '\u1E92': 'Z',
30096    '\u1E94': 'Z',
30097    '\u01B5': 'Z',
30098    '\u0224': 'Z',
30099    '\u2C7F': 'Z',
30100    '\u2C6B': 'Z',
30101    '\uA762': 'Z',
30102    '\u24D0': 'a',
30103    '\uFF41': 'a',
30104    '\u1E9A': 'a',
30105    '\u00E0': 'a',
30106    '\u00E1': 'a',
30107    '\u00E2': 'a',
30108    '\u1EA7': 'a',
30109    '\u1EA5': 'a',
30110    '\u1EAB': 'a',
30111    '\u1EA9': 'a',
30112    '\u00E3': 'a',
30113    '\u0101': 'a',
30114    '\u0103': 'a',
30115    '\u1EB1': 'a',
30116    '\u1EAF': 'a',
30117    '\u1EB5': 'a',
30118    '\u1EB3': 'a',
30119    '\u0227': 'a',
30120    '\u01E1': 'a',
30121    '\u00E4': 'a',
30122    '\u01DF': 'a',
30123    '\u1EA3': 'a',
30124    '\u00E5': 'a',
30125    '\u01FB': 'a',
30126    '\u01CE': 'a',
30127    '\u0201': 'a',
30128    '\u0203': 'a',
30129    '\u1EA1': 'a',
30130    '\u1EAD': 'a',
30131    '\u1EB7': 'a',
30132    '\u1E01': 'a',
30133    '\u0105': 'a',
30134    '\u2C65': 'a',
30135    '\u0250': 'a',
30136    '\uA733': 'aa',
30137    '\u00E6': 'ae',
30138    '\u01FD': 'ae',
30139    '\u01E3': 'ae',
30140    '\uA735': 'ao',
30141    '\uA737': 'au',
30142    '\uA739': 'av',
30143    '\uA73B': 'av',
30144    '\uA73D': 'ay',
30145    '\u24D1': 'b',
30146    '\uFF42': 'b',
30147    '\u1E03': 'b',
30148    '\u1E05': 'b',
30149    '\u1E07': 'b',
30150    '\u0180': 'b',
30151    '\u0183': 'b',
30152    '\u0253': 'b',
30153    '\u24D2': 'c',
30154    '\uFF43': 'c',
30155    '\u0107': 'c',
30156    '\u0109': 'c',
30157    '\u010B': 'c',
30158    '\u010D': 'c',
30159    '\u00E7': 'c',
30160    '\u1E09': 'c',
30161    '\u0188': 'c',
30162    '\u023C': 'c',
30163    '\uA73F': 'c',
30164    '\u2184': 'c',
30165    '\u24D3': 'd',
30166    '\uFF44': 'd',
30167    '\u1E0B': 'd',
30168    '\u010F': 'd',
30169    '\u1E0D': 'd',
30170    '\u1E11': 'd',
30171    '\u1E13': 'd',
30172    '\u1E0F': 'd',
30173    '\u0111': 'd',
30174    '\u018C': 'd',
30175    '\u0256': 'd',
30176    '\u0257': 'd',
30177    '\uA77A': 'd',
30178    '\u01F3': 'dz',
30179    '\u01C6': 'dz',
30180    '\u24D4': 'e',
30181    '\uFF45': 'e',
30182    '\u00E8': 'e',
30183    '\u00E9': 'e',
30184    '\u00EA': 'e',
30185    '\u1EC1': 'e',
30186    '\u1EBF': 'e',
30187    '\u1EC5': 'e',
30188    '\u1EC3': 'e',
30189    '\u1EBD': 'e',
30190    '\u0113': 'e',
30191    '\u1E15': 'e',
30192    '\u1E17': 'e',
30193    '\u0115': 'e',
30194    '\u0117': 'e',
30195    '\u00EB': 'e',
30196    '\u1EBB': 'e',
30197    '\u011B': 'e',
30198    '\u0205': 'e',
30199    '\u0207': 'e',
30200    '\u1EB9': 'e',
30201    '\u1EC7': 'e',
30202    '\u0229': 'e',
30203    '\u1E1D': 'e',
30204    '\u0119': 'e',
30205    '\u1E19': 'e',
30206    '\u1E1B': 'e',
30207    '\u0247': 'e',
30208    '\u025B': 'e',
30209    '\u01DD': 'e',
30210    '\u24D5': 'f',
30211    '\uFF46': 'f',
30212    '\u1E1F': 'f',
30213    '\u0192': 'f',
30214    '\uA77C': 'f',
30215    '\u24D6': 'g',
30216    '\uFF47': 'g',
30217    '\u01F5': 'g',
30218    '\u011D': 'g',
30219    '\u1E21': 'g',
30220    '\u011F': 'g',
30221    '\u0121': 'g',
30222    '\u01E7': 'g',
30223    '\u0123': 'g',
30224    '\u01E5': 'g',
30225    '\u0260': 'g',
30226    '\uA7A1': 'g',
30227    '\u1D79': 'g',
30228    '\uA77F': 'g',
30229    '\u24D7': 'h',
30230    '\uFF48': 'h',
30231    '\u0125': 'h',
30232    '\u1E23': 'h',
30233    '\u1E27': 'h',
30234    '\u021F': 'h',
30235    '\u1E25': 'h',
30236    '\u1E29': 'h',
30237    '\u1E2B': 'h',
30238    '\u1E96': 'h',
30239    '\u0127': 'h',
30240    '\u2C68': 'h',
30241    '\u2C76': 'h',
30242    '\u0265': 'h',
30243    '\u0195': 'hv',
30244    '\u24D8': 'i',
30245    '\uFF49': 'i',
30246    '\u00EC': 'i',
30247    '\u00ED': 'i',
30248    '\u00EE': 'i',
30249    '\u0129': 'i',
30250    '\u012B': 'i',
30251    '\u012D': 'i',
30252    '\u00EF': 'i',
30253    '\u1E2F': 'i',
30254    '\u1EC9': 'i',
30255    '\u01D0': 'i',
30256    '\u0209': 'i',
30257    '\u020B': 'i',
30258    '\u1ECB': 'i',
30259    '\u012F': 'i',
30260    '\u1E2D': 'i',
30261    '\u0268': 'i',
30262    '\u0131': 'i',
30263    '\u24D9': 'j',
30264    '\uFF4A': 'j',
30265    '\u0135': 'j',
30266    '\u01F0': 'j',
30267    '\u0249': 'j',
30268    '\u24DA': 'k',
30269    '\uFF4B': 'k',
30270    '\u1E31': 'k',
30271    '\u01E9': 'k',
30272    '\u1E33': 'k',
30273    '\u0137': 'k',
30274    '\u1E35': 'k',
30275    '\u0199': 'k',
30276    '\u2C6A': 'k',
30277    '\uA741': 'k',
30278    '\uA743': 'k',
30279    '\uA745': 'k',
30280    '\uA7A3': 'k',
30281    '\u24DB': 'l',
30282    '\uFF4C': 'l',
30283    '\u0140': 'l',
30284    '\u013A': 'l',
30285    '\u013E': 'l',
30286    '\u1E37': 'l',
30287    '\u1E39': 'l',
30288    '\u013C': 'l',
30289    '\u1E3D': 'l',
30290    '\u1E3B': 'l',
30291    '\u017F': 'l',
30292    '\u0142': 'l',
30293    '\u019A': 'l',
30294    '\u026B': 'l',
30295    '\u2C61': 'l',
30296    '\uA749': 'l',
30297    '\uA781': 'l',
30298    '\uA747': 'l',
30299    '\u01C9': 'lj',
30300    '\u24DC': 'm',
30301    '\uFF4D': 'm',
30302    '\u1E3F': 'm',
30303    '\u1E41': 'm',
30304    '\u1E43': 'm',
30305    '\u0271': 'm',
30306    '\u026F': 'm',
30307    '\u24DD': 'n',
30308    '\uFF4E': 'n',
30309    '\u01F9': 'n',
30310    '\u0144': 'n',
30311    '\u00F1': 'n',
30312    '\u1E45': 'n',
30313    '\u0148': 'n',
30314    '\u1E47': 'n',
30315    '\u0146': 'n',
30316    '\u1E4B': 'n',
30317    '\u1E49': 'n',
30318    '\u019E': 'n',
30319    '\u0272': 'n',
30320    '\u0149': 'n',
30321    '\uA791': 'n',
30322    '\uA7A5': 'n',
30323    '\u01CC': 'nj',
30324    '\u24DE': 'o',
30325    '\uFF4F': 'o',
30326    '\u00F2': 'o',
30327    '\u00F3': 'o',
30328    '\u00F4': 'o',
30329    '\u1ED3': 'o',
30330    '\u1ED1': 'o',
30331    '\u1ED7': 'o',
30332    '\u1ED5': 'o',
30333    '\u00F5': 'o',
30334    '\u1E4D': 'o',
30335    '\u022D': 'o',
30336    '\u1E4F': 'o',
30337    '\u014D': 'o',
30338    '\u1E51': 'o',
30339    '\u1E53': 'o',
30340    '\u014F': 'o',
30341    '\u022F': 'o',
30342    '\u0231': 'o',
30343    '\u00F6': 'o',
30344    '\u022B': 'o',
30345    '\u1ECF': 'o',
30346    '\u0151': 'o',
30347    '\u01D2': 'o',
30348    '\u020D': 'o',
30349    '\u020F': 'o',
30350    '\u01A1': 'o',
30351    '\u1EDD': 'o',
30352    '\u1EDB': 'o',
30353    '\u1EE1': 'o',
30354    '\u1EDF': 'o',
30355    '\u1EE3': 'o',
30356    '\u1ECD': 'o',
30357    '\u1ED9': 'o',
30358    '\u01EB': 'o',
30359    '\u01ED': 'o',
30360    '\u00F8': 'o',
30361    '\u01FF': 'o',
30362    '\u0254': 'o',
30363    '\uA74B': 'o',
30364    '\uA74D': 'o',
30365    '\u0275': 'o',
30366    '\u0153': 'oe',
30367    '\u01A3': 'oi',
30368    '\u0223': 'ou',
30369    '\uA74F': 'oo',
30370    '\u24DF': 'p',
30371    '\uFF50': 'p',
30372    '\u1E55': 'p',
30373    '\u1E57': 'p',
30374    '\u01A5': 'p',
30375    '\u1D7D': 'p',
30376    '\uA751': 'p',
30377    '\uA753': 'p',
30378    '\uA755': 'p',
30379    '\u24E0': 'q',
30380    '\uFF51': 'q',
30381    '\u024B': 'q',
30382    '\uA757': 'q',
30383    '\uA759': 'q',
30384    '\u24E1': 'r',
30385    '\uFF52': 'r',
30386    '\u0155': 'r',
30387    '\u1E59': 'r',
30388    '\u0159': 'r',
30389    '\u0211': 'r',
30390    '\u0213': 'r',
30391    '\u1E5B': 'r',
30392    '\u1E5D': 'r',
30393    '\u0157': 'r',
30394    '\u1E5F': 'r',
30395    '\u024D': 'r',
30396    '\u027D': 'r',
30397    '\uA75B': 'r',
30398    '\uA7A7': 'r',
30399    '\uA783': 'r',
30400    '\u24E2': 's',
30401    '\uFF53': 's',
30402    '\u00DF': 's',
30403    '\u015B': 's',
30404    '\u1E65': 's',
30405    '\u015D': 's',
30406    '\u1E61': 's',
30407    '\u0161': 's',
30408    '\u1E67': 's',
30409    '\u1E63': 's',
30410    '\u1E69': 's',
30411    '\u0219': 's',
30412    '\u015F': 's',
30413    '\u023F': 's',
30414    '\uA7A9': 's',
30415    '\uA785': 's',
30416    '\u1E9B': 's',
30417    '\u24E3': 't',
30418    '\uFF54': 't',
30419    '\u1E6B': 't',
30420    '\u1E97': 't',
30421    '\u0165': 't',
30422    '\u1E6D': 't',
30423    '\u021B': 't',
30424    '\u0163': 't',
30425    '\u1E71': 't',
30426    '\u1E6F': 't',
30427    '\u0167': 't',
30428    '\u01AD': 't',
30429    '\u0288': 't',
30430    '\u2C66': 't',
30431    '\uA787': 't',
30432    '\uA729': 'tz',
30433    '\u24E4': 'u',
30434    '\uFF55': 'u',
30435    '\u00F9': 'u',
30436    '\u00FA': 'u',
30437    '\u00FB': 'u',
30438    '\u0169': 'u',
30439    '\u1E79': 'u',
30440    '\u016B': 'u',
30441    '\u1E7B': 'u',
30442    '\u016D': 'u',
30443    '\u00FC': 'u',
30444    '\u01DC': 'u',
30445    '\u01D8': 'u',
30446    '\u01D6': 'u',
30447    '\u01DA': 'u',
30448    '\u1EE7': 'u',
30449    '\u016F': 'u',
30450    '\u0171': 'u',
30451    '\u01D4': 'u',
30452    '\u0215': 'u',
30453    '\u0217': 'u',
30454    '\u01B0': 'u',
30455    '\u1EEB': 'u',
30456    '\u1EE9': 'u',
30457    '\u1EEF': 'u',
30458    '\u1EED': 'u',
30459    '\u1EF1': 'u',
30460    '\u1EE5': 'u',
30461    '\u1E73': 'u',
30462    '\u0173': 'u',
30463    '\u1E77': 'u',
30464    '\u1E75': 'u',
30465    '\u0289': 'u',
30466    '\u24E5': 'v',
30467    '\uFF56': 'v',
30468    '\u1E7D': 'v',
30469    '\u1E7F': 'v',
30470    '\u028B': 'v',
30471    '\uA75F': 'v',
30472    '\u028C': 'v',
30473    '\uA761': 'vy',
30474    '\u24E6': 'w',
30475    '\uFF57': 'w',
30476    '\u1E81': 'w',
30477    '\u1E83': 'w',
30478    '\u0175': 'w',
30479    '\u1E87': 'w',
30480    '\u1E85': 'w',
30481    '\u1E98': 'w',
30482    '\u1E89': 'w',
30483    '\u2C73': 'w',
30484    '\u24E7': 'x',
30485    '\uFF58': 'x',
30486    '\u1E8B': 'x',
30487    '\u1E8D': 'x',
30488    '\u24E8': 'y',
30489    '\uFF59': 'y',
30490    '\u1EF3': 'y',
30491    '\u00FD': 'y',
30492    '\u0177': 'y',
30493    '\u1EF9': 'y',
30494    '\u0233': 'y',
30495    '\u1E8F': 'y',
30496    '\u00FF': 'y',
30497    '\u1EF7': 'y',
30498    '\u1E99': 'y',
30499    '\u1EF5': 'y',
30500    '\u01B4': 'y',
30501    '\u024F': 'y',
30502    '\u1EFF': 'y',
30503    '\u24E9': 'z',
30504    '\uFF5A': 'z',
30505    '\u017A': 'z',
30506    '\u1E91': 'z',
30507    '\u017C': 'z',
30508    '\u017E': 'z',
30509    '\u1E93': 'z',
30510    '\u1E95': 'z',
30511    '\u01B6': 'z',
30512    '\u0225': 'z',
30513    '\u0240': 'z',
30514    '\u2C6C': 'z',
30515    '\uA763': 'z',
30516    '\u0386': '\u0391',
30517    '\u0388': '\u0395',
30518    '\u0389': '\u0397',
30519    '\u038A': '\u0399',
30520    '\u03AA': '\u0399',
30521    '\u038C': '\u039F',
30522    '\u038E': '\u03A5',
30523    '\u03AB': '\u03A5',
30524    '\u038F': '\u03A9',
30525    '\u03AC': '\u03B1',
30526    '\u03AD': '\u03B5',
30527    '\u03AE': '\u03B7',
30528    '\u03AF': '\u03B9',
30529    '\u03CA': '\u03B9',
30530    '\u0390': '\u03B9',
30531    '\u03CC': '\u03BF',
30532    '\u03CD': '\u03C5',
30533    '\u03CB': '\u03C5',
30534    '\u03B0': '\u03C5',
30535    '\u03CE': '\u03C9',
30536    '\u03C2': '\u03C3',
30537    '\u2019': '\''
30538  };
30539
30540  return diacritics;
30541});
30542
30543S2.define('select2/data/base',[
30544  '../utils'
30545], function (Utils) {
30546  function BaseAdapter ($element, options) {
30547    BaseAdapter.__super__.constructor.call(this);
30548  }
30549
30550  Utils.Extend(BaseAdapter, Utils.Observable);
30551
30552  BaseAdapter.prototype.current = function (callback) {
30553    throw new Error('The `current` method must be defined in child classes.');
30554  };
30555
30556  BaseAdapter.prototype.query = function (params, callback) {
30557    throw new Error('The `query` method must be defined in child classes.');
30558  };
30559
30560  BaseAdapter.prototype.bind = function (container, $container) {
30561    // Can be implemented in subclasses
30562  };
30563
30564  BaseAdapter.prototype.destroy = function () {
30565    // Can be implemented in subclasses
30566  };
30567
30568  BaseAdapter.prototype.generateResultId = function (container, data) {
30569    var id = container.id + '-result-';
30570
30571    id += Utils.generateChars(4);
30572
30573    if (data.id != null) {
30574      id += '-' + data.id.toString();
30575    } else {
30576      id += '-' + Utils.generateChars(4);
30577    }
30578    return id;
30579  };
30580
30581  return BaseAdapter;
30582});
30583
30584S2.define('select2/data/select',[
30585  './base',
30586  '../utils',
30587  'jquery'
30588], function (BaseAdapter, Utils, $) {
30589  function SelectAdapter ($element, options) {
30590    this.$element = $element;
30591    this.options = options;
30592
30593    SelectAdapter.__super__.constructor.call(this);
30594  }
30595
30596  Utils.Extend(SelectAdapter, BaseAdapter);
30597
30598  SelectAdapter.prototype.current = function (callback) {
30599    var data = [];
30600    var self = this;
30601
30602    this.$element.find(':selected').each(function () {
30603      var $option = $(this);
30604
30605      var option = self.item($option);
30606
30607      data.push(option);
30608    });
30609
30610    callback(data);
30611  };
30612
30613  SelectAdapter.prototype.select = function (data) {
30614    var self = this;
30615
30616    data.selected = true;
30617
30618    // If data.element is a DOM node, use it instead
30619    if ($(data.element).is('option')) {
30620      data.element.selected = true;
30621
30622      this.$element.trigger('change');
30623
30624      return;
30625    }
30626
30627    if (this.$element.prop('multiple')) {
30628      this.current(function (currentData) {
30629        var val = [];
30630
30631        data = [data];
30632        data.push.apply(data, currentData);
30633
30634        for (var d = 0; d < data.length; d++) {
30635          var id = data[d].id;
30636
30637          if ($.inArray(id, val) === -1) {
30638            val.push(id);
30639          }
30640        }
30641
30642        self.$element.val(val);
30643        self.$element.trigger('change');
30644      });
30645    } else {
30646      var val = data.id;
30647
30648      this.$element.val(val);
30649      this.$element.trigger('change');
30650    }
30651  };
30652
30653  SelectAdapter.prototype.unselect = function (data) {
30654    var self = this;
30655
30656    if (!this.$element.prop('multiple')) {
30657      return;
30658    }
30659
30660    data.selected = false;
30661
30662    if ($(data.element).is('option')) {
30663      data.element.selected = false;
30664
30665      this.$element.trigger('change');
30666
30667      return;
30668    }
30669
30670    this.current(function (currentData) {
30671      var val = [];
30672
30673      for (var d = 0; d < currentData.length; d++) {
30674        var id = currentData[d].id;
30675
30676        if (id !== data.id && $.inArray(id, val) === -1) {
30677          val.push(id);
30678        }
30679      }
30680
30681      self.$element.val(val);
30682
30683      self.$element.trigger('change');
30684    });
30685  };
30686
30687  SelectAdapter.prototype.bind = function (container, $container) {
30688    var self = this;
30689
30690    this.container = container;
30691
30692    container.on('select', function (params) {
30693      self.select(params.data);
30694    });
30695
30696    container.on('unselect', function (params) {
30697      self.unselect(params.data);
30698    });
30699  };
30700
30701  SelectAdapter.prototype.destroy = function () {
30702    // Remove anything added to child elements
30703    this.$element.find('*').each(function () {
30704      // Remove any custom data set by Select2
30705      Utils.RemoveData(this);
30706    });
30707  };
30708
30709  SelectAdapter.prototype.query = function (params, callback) {
30710    var data = [];
30711    var self = this;
30712
30713    var $options = this.$element.children();
30714
30715    $options.each(function () {
30716      var $option = $(this);
30717
30718      if (!$option.is('option') && !$option.is('optgroup')) {
30719        return;
30720      }
30721
30722      var option = self.item($option);
30723
30724      var matches = self.matches(params, option);
30725
30726      if (matches !== null) {
30727        data.push(matches);
30728      }
30729    });
30730
30731    callback({
30732      results: data
30733    });
30734  };
30735
30736  SelectAdapter.prototype.addOptions = function ($options) {
30737    Utils.appendMany(this.$element, $options);
30738  };
30739
30740  SelectAdapter.prototype.option = function (data) {
30741    var option;
30742
30743    if (data.children) {
30744      option = document.createElement('optgroup');
30745      option.label = data.text;
30746    } else {
30747      option = document.createElement('option');
30748
30749      if (option.textContent !== undefined) {
30750        option.textContent = data.text;
30751      } else {
30752        option.innerText = data.text;
30753      }
30754    }
30755
30756    if (data.id !== undefined) {
30757      option.value = data.id;
30758    }
30759
30760    if (data.disabled) {
30761      option.disabled = true;
30762    }
30763
30764    if (data.selected) {
30765      option.selected = true;
30766    }
30767
30768    if (data.title) {
30769      option.title = data.title;
30770    }
30771
30772    var $option = $(option);
30773
30774    var normalizedData = this._normalizeItem(data);
30775    normalizedData.element = option;
30776
30777    // Override the option's data with the combined data
30778    Utils.StoreData(option, 'data', normalizedData);
30779
30780    return $option;
30781  };
30782
30783  SelectAdapter.prototype.item = function ($option) {
30784    var data = {};
30785
30786    data = Utils.GetData($option[0], 'data');
30787
30788    if (data != null) {
30789      return data;
30790    }
30791
30792    if ($option.is('option')) {
30793      data = {
30794        id: $option.val(),
30795        text: $option.text(),
30796        disabled: $option.prop('disabled'),
30797        selected: $option.prop('selected'),
30798        title: $option.prop('title')
30799      };
30800    } else if ($option.is('optgroup')) {
30801      data = {
30802        text: $option.prop('label'),
30803        children: [],
30804        title: $option.prop('title')
30805      };
30806
30807      var $children = $option.children('option');
30808      var children = [];
30809
30810      for (var c = 0; c < $children.length; c++) {
30811        var $child = $($children[c]);
30812
30813        var child = this.item($child);
30814
30815        children.push(child);
30816      }
30817
30818      data.children = children;
30819    }
30820
30821    data = this._normalizeItem(data);
30822    data.element = $option[0];
30823
30824    Utils.StoreData($option[0], 'data', data);
30825
30826    return data;
30827  };
30828
30829  SelectAdapter.prototype._normalizeItem = function (item) {
30830    if (item !== Object(item)) {
30831      item = {
30832        id: item,
30833        text: item
30834      };
30835    }
30836
30837    item = $.extend({}, {
30838      text: ''
30839    }, item);
30840
30841    var defaults = {
30842      selected: false,
30843      disabled: false
30844    };
30845
30846    if (item.id != null) {
30847      item.id = item.id.toString();
30848    }
30849
30850    if (item.text != null) {
30851      item.text = item.text.toString();
30852    }
30853
30854    if (item._resultId == null && item.id && this.container != null) {
30855      item._resultId = this.generateResultId(this.container, item);
30856    }
30857
30858    return $.extend({}, defaults, item);
30859  };
30860
30861  SelectAdapter.prototype.matches = function (params, data) {
30862    var matcher = this.options.get('matcher');
30863
30864    return matcher(params, data);
30865  };
30866
30867  return SelectAdapter;
30868});
30869
30870S2.define('select2/data/array',[
30871  './select',
30872  '../utils',
30873  'jquery'
30874], function (SelectAdapter, Utils, $) {
30875  function ArrayAdapter ($element, options) {
30876    var data = options.get('data') || [];
30877
30878    ArrayAdapter.__super__.constructor.call(this, $element, options);
30879
30880    this.addOptions(this.convertToOptions(data));
30881  }
30882
30883  Utils.Extend(ArrayAdapter, SelectAdapter);
30884
30885  ArrayAdapter.prototype.select = function (data) {
30886    var $option = this.$element.find('option').filter(function (i, elm) {
30887      return elm.value == data.id.toString();
30888    });
30889
30890    if ($option.length === 0) {
30891      $option = this.option(data);
30892
30893      this.addOptions($option);
30894    }
30895
30896    ArrayAdapter.__super__.select.call(this, data);
30897  };
30898
30899  ArrayAdapter.prototype.convertToOptions = function (data) {
30900    var self = this;
30901
30902    var $existing = this.$element.find('option');
30903    var existingIds = $existing.map(function () {
30904      return self.item($(this)).id;
30905    }).get();
30906
30907    var $options = [];
30908
30909    // Filter out all items except for the one passed in the argument
30910    function onlyItem (item) {
30911      return function () {
30912        return $(this).val() == item.id;
30913      };
30914    }
30915
30916    for (var d = 0; d < data.length; d++) {
30917      var item = this._normalizeItem(data[d]);
30918
30919      // Skip items which were pre-loaded, only merge the data
30920      if ($.inArray(item.id, existingIds) >= 0) {
30921        var $existingOption = $existing.filter(onlyItem(item));
30922
30923        var existingData = this.item($existingOption);
30924        var newData = $.extend(true, {}, item, existingData);
30925
30926        var $newOption = this.option(newData);
30927
30928        $existingOption.replaceWith($newOption);
30929
30930        continue;
30931      }
30932
30933      var $option = this.option(item);
30934
30935      if (item.children) {
30936        var $children = this.convertToOptions(item.children);
30937
30938        Utils.appendMany($option, $children);
30939      }
30940
30941      $options.push($option);
30942    }
30943
30944    return $options;
30945  };
30946
30947  return ArrayAdapter;
30948});
30949
30950S2.define('select2/data/ajax',[
30951  './array',
30952  '../utils',
30953  'jquery'
30954], function (ArrayAdapter, Utils, $) {
30955  function AjaxAdapter ($element, options) {
30956    this.ajaxOptions = this._applyDefaults(options.get('ajax'));
30957
30958    if (this.ajaxOptions.processResults != null) {
30959      this.processResults = this.ajaxOptions.processResults;
30960    }
30961
30962    AjaxAdapter.__super__.constructor.call(this, $element, options);
30963  }
30964
30965  Utils.Extend(AjaxAdapter, ArrayAdapter);
30966
30967  AjaxAdapter.prototype._applyDefaults = function (options) {
30968    var defaults = {
30969      data: function (params) {
30970        return $.extend({}, params, {
30971          q: params.term
30972        });
30973      },
30974      transport: function (params, success, failure) {
30975        var $request = $.ajax(params);
30976
30977        $request.then(success);
30978        $request.fail(failure);
30979
30980        return $request;
30981      }
30982    };
30983
30984    return $.extend({}, defaults, options, true);
30985  };
30986
30987  AjaxAdapter.prototype.processResults = function (results) {
30988    return results;
30989  };
30990
30991  AjaxAdapter.prototype.query = function (params, callback) {
30992    var matches = [];
30993    var self = this;
30994
30995    if (this._request != null) {
30996      // JSONP requests cannot always be aborted
30997      if ($.isFunction(this._request.abort)) {
30998        this._request.abort();
30999      }
31000
31001      this._request = null;
31002    }
31003
31004    var options = $.extend({
31005      type: 'GET'
31006    }, this.ajaxOptions);
31007
31008    if (typeof options.url === 'function') {
31009      options.url = options.url.call(this.$element, params);
31010    }
31011
31012    if (typeof options.data === 'function') {
31013      options.data = options.data.call(this.$element, params);
31014    }
31015
31016    function request () {
31017      var $request = options.transport(options, function (data) {
31018        var results = self.processResults(data, params);
31019
31020        if (self.options.get('debug') && window.console && console.error) {
31021          // Check to make sure that the response included a `results` key.
31022          if (!results || !results.results || !$.isArray(results.results)) {
31023            console.error(
31024              'Select2: The AJAX results did not return an array in the ' +
31025              '`results` key of the response.'
31026            );
31027          }
31028        }
31029
31030        callback(results);
31031      }, function () {
31032        // Attempt to detect if a request was aborted
31033        // Only works if the transport exposes a status property
31034        if ('status' in $request &&
31035            ($request.status === 0 || $request.status === '0')) {
31036          return;
31037        }
31038
31039        self.trigger('results:message', {
31040          message: 'errorLoading'
31041        });
31042      });
31043
31044      self._request = $request;
31045    }
31046
31047    if (this.ajaxOptions.delay && params.term != null) {
31048      if (this._queryTimeout) {
31049        window.clearTimeout(this._queryTimeout);
31050      }
31051
31052      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
31053    } else {
31054      request();
31055    }
31056  };
31057
31058  return AjaxAdapter;
31059});
31060
31061S2.define('select2/data/tags',[
31062  'jquery'
31063], function ($) {
31064  function Tags (decorated, $element, options) {
31065    var tags = options.get('tags');
31066
31067    var createTag = options.get('createTag');
31068
31069    if (createTag !== undefined) {
31070      this.createTag = createTag;
31071    }
31072
31073    var insertTag = options.get('insertTag');
31074
31075    if (insertTag !== undefined) {
31076        this.insertTag = insertTag;
31077    }
31078
31079    decorated.call(this, $element, options);
31080
31081    if ($.isArray(tags)) {
31082      for (var t = 0; t < tags.length; t++) {
31083        var tag = tags[t];
31084        var item = this._normalizeItem(tag);
31085
31086        var $option = this.option(item);
31087
31088        this.$element.append($option);
31089      }
31090    }
31091  }
31092
31093  Tags.prototype.query = function (decorated, params, callback) {
31094    var self = this;
31095
31096    this._removeOldTags();
31097
31098    if (params.term == null || params.page != null) {
31099      decorated.call(this, params, callback);
31100      return;
31101    }
31102
31103    function wrapper (obj, child) {
31104      var data = obj.results;
31105
31106      for (var i = 0; i < data.length; i++) {
31107        var option = data[i];
31108
31109        var checkChildren = (
31110          option.children != null &&
31111          !wrapper({
31112            results: option.children
31113          }, true)
31114        );
31115
31116        var optionText = (option.text || '').toUpperCase();
31117        var paramsTerm = (params.term || '').toUpperCase();
31118
31119        var checkText = optionText === paramsTerm;
31120
31121        if (checkText || checkChildren) {
31122          if (child) {
31123            return false;
31124          }
31125
31126          obj.data = data;
31127          callback(obj);
31128
31129          return;
31130        }
31131      }
31132
31133      if (child) {
31134        return true;
31135      }
31136
31137      var tag = self.createTag(params);
31138
31139      if (tag != null) {
31140        var $option = self.option(tag);
31141        $option.attr('data-select2-tag', true);
31142
31143        self.addOptions([$option]);
31144
31145        self.insertTag(data, tag);
31146      }
31147
31148      obj.results = data;
31149
31150      callback(obj);
31151    }
31152
31153    decorated.call(this, params, wrapper);
31154  };
31155
31156  Tags.prototype.createTag = function (decorated, params) {
31157    var term = $.trim(params.term);
31158
31159    if (term === '') {
31160      return null;
31161    }
31162
31163    return {
31164      id: term,
31165      text: term
31166    };
31167  };
31168
31169  Tags.prototype.insertTag = function (_, data, tag) {
31170    data.unshift(tag);
31171  };
31172
31173  Tags.prototype._removeOldTags = function (_) {
31174    var tag = this._lastTag;
31175
31176    var $options = this.$element.find('option[data-select2-tag]');
31177
31178    $options.each(function () {
31179      if (this.selected) {
31180        return;
31181      }
31182
31183      $(this).remove();
31184    });
31185  };
31186
31187  return Tags;
31188});
31189
31190S2.define('select2/data/tokenizer',[
31191  'jquery'
31192], function ($) {
31193  function Tokenizer (decorated, $element, options) {
31194    var tokenizer = options.get('tokenizer');
31195
31196    if (tokenizer !== undefined) {
31197      this.tokenizer = tokenizer;
31198    }
31199
31200    decorated.call(this, $element, options);
31201  }
31202
31203  Tokenizer.prototype.bind = function (decorated, container, $container) {
31204    decorated.call(this, container, $container);
31205
31206    this.$search =  container.dropdown.$search || container.selection.$search ||
31207      $container.find('.select2-search__field');
31208  };
31209
31210  Tokenizer.prototype.query = function (decorated, params, callback) {
31211    var self = this;
31212
31213    function createAndSelect (data) {
31214      // Normalize the data object so we can use it for checks
31215      var item = self._normalizeItem(data);
31216
31217      // Check if the data object already exists as a tag
31218      // Select it if it doesn't
31219      var $existingOptions = self.$element.find('option').filter(function () {
31220        return $(this).val() === item.id;
31221      });
31222
31223      // If an existing option wasn't found for it, create the option
31224      if (!$existingOptions.length) {
31225        var $option = self.option(item);
31226        $option.attr('data-select2-tag', true);
31227
31228        self._removeOldTags();
31229        self.addOptions([$option]);
31230      }
31231
31232      // Select the item, now that we know there is an option for it
31233      select(item);
31234    }
31235
31236    function select (data) {
31237      self.trigger('select', {
31238        data: data
31239      });
31240    }
31241
31242    params.term = params.term || '';
31243
31244    var tokenData = this.tokenizer(params, this.options, createAndSelect);
31245
31246    if (tokenData.term !== params.term) {
31247      // Replace the search term if we have the search box
31248      if (this.$search.length) {
31249        this.$search.val(tokenData.term);
31250        this.$search.trigger('focus');
31251      }
31252
31253      params.term = tokenData.term;
31254    }
31255
31256    decorated.call(this, params, callback);
31257  };
31258
31259  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
31260    var separators = options.get('tokenSeparators') || [];
31261    var term = params.term;
31262    var i = 0;
31263
31264    var createTag = this.createTag || function (params) {
31265      return {
31266        id: params.term,
31267        text: params.term
31268      };
31269    };
31270
31271    while (i < term.length) {
31272      var termChar = term[i];
31273
31274      if ($.inArray(termChar, separators) === -1) {
31275        i++;
31276
31277        continue;
31278      }
31279
31280      var part = term.substr(0, i);
31281      var partParams = $.extend({}, params, {
31282        term: part
31283      });
31284
31285      var data = createTag(partParams);
31286
31287      if (data == null) {
31288        i++;
31289        continue;
31290      }
31291
31292      callback(data);
31293
31294      // Reset the term to not include the tokenized portion
31295      term = term.substr(i + 1) || '';
31296      i = 0;
31297    }
31298
31299    return {
31300      term: term
31301    };
31302  };
31303
31304  return Tokenizer;
31305});
31306
31307S2.define('select2/data/minimumInputLength',[
31308
31309], function () {
31310  function MinimumInputLength (decorated, $e, options) {
31311    this.minimumInputLength = options.get('minimumInputLength');
31312
31313    decorated.call(this, $e, options);
31314  }
31315
31316  MinimumInputLength.prototype.query = function (decorated, params, callback) {
31317    params.term = params.term || '';
31318
31319    if (params.term.length < this.minimumInputLength) {
31320      this.trigger('results:message', {
31321        message: 'inputTooShort',
31322        args: {
31323          minimum: this.minimumInputLength,
31324          input: params.term,
31325          params: params
31326        }
31327      });
31328
31329      return;
31330    }
31331
31332    decorated.call(this, params, callback);
31333  };
31334
31335  return MinimumInputLength;
31336});
31337
31338S2.define('select2/data/maximumInputLength',[
31339
31340], function () {
31341  function MaximumInputLength (decorated, $e, options) {
31342    this.maximumInputLength = options.get('maximumInputLength');
31343
31344    decorated.call(this, $e, options);
31345  }
31346
31347  MaximumInputLength.prototype.query = function (decorated, params, callback) {
31348    params.term = params.term || '';
31349
31350    if (this.maximumInputLength > 0 &&
31351        params.term.length > this.maximumInputLength) {
31352      this.trigger('results:message', {
31353        message: 'inputTooLong',
31354        args: {
31355          maximum: this.maximumInputLength,
31356          input: params.term,
31357          params: params
31358        }
31359      });
31360
31361      return;
31362    }
31363
31364    decorated.call(this, params, callback);
31365  };
31366
31367  return MaximumInputLength;
31368});
31369
31370S2.define('select2/data/maximumSelectionLength',[
31371
31372], function (){
31373  function MaximumSelectionLength (decorated, $e, options) {
31374    this.maximumSelectionLength = options.get('maximumSelectionLength');
31375
31376    decorated.call(this, $e, options);
31377  }
31378
31379  MaximumSelectionLength.prototype.query =
31380    function (decorated, params, callback) {
31381      var self = this;
31382
31383      this.current(function (currentData) {
31384        var count = currentData != null ? currentData.length : 0;
31385        if (self.maximumSelectionLength > 0 &&
31386          count >= self.maximumSelectionLength) {
31387          self.trigger('results:message', {
31388            message: 'maximumSelected',
31389            args: {
31390              maximum: self.maximumSelectionLength
31391            }
31392          });
31393          return;
31394        }
31395        decorated.call(self, params, callback);
31396      });
31397  };
31398
31399  return MaximumSelectionLength;
31400});
31401
31402S2.define('select2/dropdown',[
31403  'jquery',
31404  './utils'
31405], function ($, Utils) {
31406  function Dropdown ($element, options) {
31407    this.$element = $element;
31408    this.options = options;
31409
31410    Dropdown.__super__.constructor.call(this);
31411  }
31412
31413  Utils.Extend(Dropdown, Utils.Observable);
31414
31415  Dropdown.prototype.render = function () {
31416    var $dropdown = $(
31417      '<span class="select2-dropdown">' +
31418        '<span class="select2-results"></span>' +
31419      '</span>'
31420    );
31421
31422    $dropdown.attr('dir', this.options.get('dir'));
31423
31424    this.$dropdown = $dropdown;
31425
31426    return $dropdown;
31427  };
31428
31429  Dropdown.prototype.bind = function () {
31430    // Should be implemented in subclasses
31431  };
31432
31433  Dropdown.prototype.position = function ($dropdown, $container) {
31434    // Should be implemented in subclasses
31435  };
31436
31437  Dropdown.prototype.destroy = function () {
31438    // Remove the dropdown from the DOM
31439    this.$dropdown.remove();
31440  };
31441
31442  return Dropdown;
31443});
31444
31445S2.define('select2/dropdown/search',[
31446  'jquery',
31447  '../utils'
31448], function ($, Utils) {
31449  function Search () { }
31450
31451  Search.prototype.render = function (decorated) {
31452    var $rendered = decorated.call(this);
31453
31454    var $search = $(
31455      '<span class="select2-search select2-search--dropdown">' +
31456        '<input class="select2-search__field" type="search" tabindex="-1"' +
31457        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
31458        ' spellcheck="false" role="textbox" />' +
31459      '</span>'
31460    );
31461
31462    this.$searchContainer = $search;
31463    this.$search = $search.find('input');
31464
31465    $rendered.prepend($search);
31466
31467    return $rendered;
31468  };
31469
31470  Search.prototype.bind = function (decorated, container, $container) {
31471    var self = this;
31472
31473    decorated.call(this, container, $container);
31474
31475    this.$search.on('keydown', function (evt) {
31476      self.trigger('keypress', evt);
31477
31478      self._keyUpPrevented = evt.isDefaultPrevented();
31479    });
31480
31481    // Workaround for browsers which do not support the `input` event
31482    // This will prevent double-triggering of events for browsers which support
31483    // both the `keyup` and `input` events.
31484    this.$search.on('input', function (evt) {
31485      // Unbind the duplicated `keyup` event
31486      $(this).off('keyup');
31487    });
31488
31489    this.$search.on('keyup input', function (evt) {
31490      self.handleSearch(evt);
31491    });
31492
31493    container.on('open', function () {
31494      self.$search.attr('tabindex', 0);
31495
31496      self.$search.trigger('focus');
31497
31498      window.setTimeout(function () {
31499        self.$search.trigger('focus');
31500      }, 0);
31501    });
31502
31503    container.on('close', function () {
31504      self.$search.attr('tabindex', -1);
31505
31506      self.$search.val('');
31507      self.$search.trigger('blur');
31508    });
31509
31510    container.on('focus', function () {
31511      if (!container.isOpen()) {
31512        self.$search.trigger('focus');
31513      }
31514    });
31515
31516    container.on('results:all', function (params) {
31517      if (params.query.term == null || params.query.term === '') {
31518        var showSearch = self.showSearch(params);
31519
31520        if (showSearch) {
31521          self.$searchContainer.removeClass('select2-search--hide');
31522        } else {
31523          self.$searchContainer.addClass('select2-search--hide');
31524        }
31525      }
31526    });
31527  };
31528
31529  Search.prototype.handleSearch = function (evt) {
31530    if (!this._keyUpPrevented) {
31531      var input = this.$search.val();
31532
31533      this.trigger('query', {
31534        term: input
31535      });
31536    }
31537
31538    this._keyUpPrevented = false;
31539  };
31540
31541  Search.prototype.showSearch = function (_, params) {
31542    return true;
31543  };
31544
31545  return Search;
31546});
31547
31548S2.define('select2/dropdown/hidePlaceholder',[
31549
31550], function () {
31551  function HidePlaceholder (decorated, $element, options, dataAdapter) {
31552    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
31553
31554    decorated.call(this, $element, options, dataAdapter);
31555  }
31556
31557  HidePlaceholder.prototype.append = function (decorated, data) {
31558    data.results = this.removePlaceholder(data.results);
31559
31560    decorated.call(this, data);
31561  };
31562
31563  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
31564    if (typeof placeholder === 'string') {
31565      placeholder = {
31566        id: '',
31567        text: placeholder
31568      };
31569    }
31570
31571    return placeholder;
31572  };
31573
31574  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
31575    var modifiedData = data.slice(0);
31576
31577    for (var d = data.length - 1; d >= 0; d--) {
31578      var item = data[d];
31579
31580      if (this.placeholder.id === item.id) {
31581        modifiedData.splice(d, 1);
31582      }
31583    }
31584
31585    return modifiedData;
31586  };
31587
31588  return HidePlaceholder;
31589});
31590
31591S2.define('select2/dropdown/infiniteScroll',[
31592  'jquery'
31593], function ($) {
31594  function InfiniteScroll (decorated, $element, options, dataAdapter) {
31595    this.lastParams = {};
31596
31597    decorated.call(this, $element, options, dataAdapter);
31598
31599    this.$loadingMore = this.createLoadingMore();
31600    this.loading = false;
31601  }
31602
31603  InfiniteScroll.prototype.append = function (decorated, data) {
31604    this.$loadingMore.remove();
31605    this.loading = false;
31606
31607    decorated.call(this, data);
31608
31609    if (this.showLoadingMore(data)) {
31610      this.$results.append(this.$loadingMore);
31611      this.loadMoreIfNeeded();
31612    }
31613  };
31614
31615  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
31616    var self = this;
31617
31618    decorated.call(this, container, $container);
31619
31620    container.on('query', function (params) {
31621      self.lastParams = params;
31622      self.loading = true;
31623    });
31624
31625    container.on('query:append', function (params) {
31626      self.lastParams = params;
31627      self.loading = true;
31628    });
31629
31630    this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
31631  };
31632
31633  InfiniteScroll.prototype.loadMoreIfNeeded = function () {
31634    var isLoadMoreVisible = $.contains(
31635      document.documentElement,
31636      this.$loadingMore[0]
31637    );
31638
31639    if (this.loading || !isLoadMoreVisible) {
31640      return;
31641    }
31642
31643    var currentOffset = this.$results.offset().top +
31644      this.$results.outerHeight(false);
31645    var loadingMoreOffset = this.$loadingMore.offset().top +
31646      this.$loadingMore.outerHeight(false);
31647
31648    if (currentOffset + 50 >= loadingMoreOffset) {
31649      this.loadMore();
31650    }
31651  };
31652
31653  InfiniteScroll.prototype.loadMore = function () {
31654    this.loading = true;
31655
31656    var params = $.extend({}, {page: 1}, this.lastParams);
31657
31658    params.page++;
31659
31660    this.trigger('query:append', params);
31661  };
31662
31663  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
31664    return data.pagination && data.pagination.more;
31665  };
31666
31667  InfiniteScroll.prototype.createLoadingMore = function () {
31668    var $option = $(
31669      '<li ' +
31670      'class="select2-results__option select2-results__option--load-more"' +
31671      'role="treeitem" aria-disabled="true"></li>'
31672    );
31673
31674    var message = this.options.get('translations').get('loadingMore');
31675
31676    $option.html(message(this.lastParams));
31677
31678    return $option;
31679  };
31680
31681  return InfiniteScroll;
31682});
31683
31684S2.define('select2/dropdown/attachBody',[
31685  'jquery',
31686  '../utils'
31687], function ($, Utils) {
31688  function AttachBody (decorated, $element, options) {
31689    this.$dropdownParent = options.get('dropdownParent') || $(document.body);
31690
31691    decorated.call(this, $element, options);
31692  }
31693
31694  AttachBody.prototype.bind = function (decorated, container, $container) {
31695    var self = this;
31696
31697    var setupResultsEvents = false;
31698
31699    decorated.call(this, container, $container);
31700
31701    container.on('open', function () {
31702      self._showDropdown();
31703      self._attachPositioningHandler(container);
31704
31705      if (!setupResultsEvents) {
31706        setupResultsEvents = true;
31707
31708        container.on('results:all', function () {
31709          self._positionDropdown();
31710          self._resizeDropdown();
31711        });
31712
31713        container.on('results:append', function () {
31714          self._positionDropdown();
31715          self._resizeDropdown();
31716        });
31717      }
31718    });
31719
31720    container.on('close', function () {
31721      self._hideDropdown();
31722      self._detachPositioningHandler(container);
31723    });
31724
31725    this.$dropdownContainer.on('mousedown', function (evt) {
31726      evt.stopPropagation();
31727    });
31728  };
31729
31730  AttachBody.prototype.destroy = function (decorated) {
31731    decorated.call(this);
31732
31733    this.$dropdownContainer.remove();
31734  };
31735
31736  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
31737    // Clone all of the container classes
31738    $dropdown.attr('class', $container.attr('class'));
31739
31740    $dropdown.removeClass('select2');
31741    $dropdown.addClass('select2-container--open');
31742
31743    $dropdown.css({
31744      position: 'absolute',
31745      top: -999999
31746    });
31747
31748    this.$container = $container;
31749  };
31750
31751  AttachBody.prototype.render = function (decorated) {
31752    var $container = $('<span></span>');
31753
31754    var $dropdown = decorated.call(this);
31755    $container.append($dropdown);
31756
31757    this.$dropdownContainer = $container;
31758
31759    return $container;
31760  };
31761
31762  AttachBody.prototype._hideDropdown = function (decorated) {
31763    this.$dropdownContainer.detach();
31764  };
31765
31766  AttachBody.prototype._attachPositioningHandler =
31767      function (decorated, container) {
31768    var self = this;
31769
31770    var scrollEvent = 'scroll.select2.' + container.id;
31771    var resizeEvent = 'resize.select2.' + container.id;
31772    var orientationEvent = 'orientationchange.select2.' + container.id;
31773
31774    var $watchers = this.$container.parents().filter(Utils.hasScroll);
31775    $watchers.each(function () {
31776      Utils.StoreData(this, 'select2-scroll-position', {
31777        x: $(this).scrollLeft(),
31778        y: $(this).scrollTop()
31779      });
31780    });
31781
31782    $watchers.on(scrollEvent, function (ev) {
31783      var position = Utils.GetData(this, 'select2-scroll-position');
31784      $(this).scrollTop(position.y);
31785    });
31786
31787    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
31788      function (e) {
31789      self._positionDropdown();
31790      self._resizeDropdown();
31791    });
31792  };
31793
31794  AttachBody.prototype._detachPositioningHandler =
31795      function (decorated, container) {
31796    var scrollEvent = 'scroll.select2.' + container.id;
31797    var resizeEvent = 'resize.select2.' + container.id;
31798    var orientationEvent = 'orientationchange.select2.' + container.id;
31799
31800    var $watchers = this.$container.parents().filter(Utils.hasScroll);
31801    $watchers.off(scrollEvent);
31802
31803    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
31804  };
31805
31806  AttachBody.prototype._positionDropdown = function () {
31807    var $window = $(window);
31808
31809    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
31810    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
31811
31812    var newDirection = null;
31813
31814    var offset = this.$container.offset();
31815
31816    offset.bottom = offset.top + this.$container.outerHeight(false);
31817
31818    var container = {
31819      height: this.$container.outerHeight(false)
31820    };
31821
31822    container.top = offset.top;
31823    container.bottom = offset.top + container.height;
31824
31825    var dropdown = {
31826      height: this.$dropdown.outerHeight(false)
31827    };
31828
31829    var viewport = {
31830      top: $window.scrollTop(),
31831      bottom: $window.scrollTop() + $window.height()
31832    };
31833
31834    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
31835    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
31836
31837    var css = {
31838      left: offset.left,
31839      top: container.bottom
31840    };
31841
31842    // Determine what the parent element is to use for calculating the offset
31843    var $offsetParent = this.$dropdownParent;
31844
31845    // For statically positioned elements, we need to get the element
31846    // that is determining the offset
31847    if ($offsetParent.css('position') === 'static') {
31848      $offsetParent = $offsetParent.offsetParent();
31849    }
31850
31851    var parentOffset = $offsetParent.offset();
31852
31853    css.top -= parentOffset.top;
31854    css.left -= parentOffset.left;
31855
31856    if (!isCurrentlyAbove && !isCurrentlyBelow) {
31857      newDirection = 'below';
31858    }
31859
31860    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
31861      newDirection = 'above';
31862    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
31863      newDirection = 'below';
31864    }
31865
31866    if (newDirection == 'above' ||
31867      (isCurrentlyAbove && newDirection !== 'below')) {
31868      css.top = container.top - parentOffset.top - dropdown.height;
31869    }
31870
31871    if (newDirection != null) {
31872      this.$dropdown
31873        .removeClass('select2-dropdown--below select2-dropdown--above')
31874        .addClass('select2-dropdown--' + newDirection);
31875      this.$container
31876        .removeClass('select2-container--below select2-container--above')
31877        .addClass('select2-container--' + newDirection);
31878    }
31879
31880    this.$dropdownContainer.css(css);
31881  };
31882
31883  AttachBody.prototype._resizeDropdown = function () {
31884    var css = {
31885      width: this.$container.outerWidth(false) + 'px'
31886    };
31887
31888    if (this.options.get('dropdownAutoWidth')) {
31889      css.minWidth = css.width;
31890      css.position = 'relative';
31891      css.width = 'auto';
31892    }
31893
31894    this.$dropdown.css(css);
31895  };
31896
31897  AttachBody.prototype._showDropdown = function (decorated) {
31898    this.$dropdownContainer.appendTo(this.$dropdownParent);
31899
31900    this._positionDropdown();
31901    this._resizeDropdown();
31902  };
31903
31904  return AttachBody;
31905});
31906
31907S2.define('select2/dropdown/minimumResultsForSearch',[
31908
31909], function () {
31910  function countResults (data) {
31911    var count = 0;
31912
31913    for (var d = 0; d < data.length; d++) {
31914      var item = data[d];
31915
31916      if (item.children) {
31917        count += countResults(item.children);
31918      } else {
31919        count++;
31920      }
31921    }
31922
31923    return count;
31924  }
31925
31926  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
31927    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
31928
31929    if (this.minimumResultsForSearch < 0) {
31930      this.minimumResultsForSearch = Infinity;
31931    }
31932
31933    decorated.call(this, $element, options, dataAdapter);
31934  }
31935
31936  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
31937    if (countResults(params.data.results) < this.minimumResultsForSearch) {
31938      return false;
vendor: 3,261 bytes, lines 31939-32077
31939    }
31940
31941    return decorated.call(this, params);
31942  };
31943
31944  return MinimumResultsForSearch;
31945});
31946
31947S2.define('select2/dropdown/selectOnClose',[
31948  '../utils'
31949], function (Utils) {
31950  function SelectOnClose () { }
31951
31952  SelectOnClose.prototype.bind = function (decorated, container, $container) {
31953    var self = this;
31954
31955    decorated.call(this, container, $container);
31956
31957    container.on('close', function (params) {
31958      self._handleSelectOnClose(params);
31959    });
31960  };
31961
31962  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
31963    if (params && params.originalSelect2Event != null) {
31964      var event = params.originalSelect2Event;
31965
31966      // Don't select an item if the close event was triggered from a select or
31967      // unselect event
31968      if (event._type === 'select' || event._type === 'unselect') {
31969        return;
31970      }
31971    }
31972
31973    var $highlightedResults = this.getHighlightedResults();
31974
31975    // Only select highlighted results
31976    if ($highlightedResults.length < 1) {
31977      return;
31978    }
31979
31980    var data = Utils.GetData($highlightedResults[0], 'data');
31981
31982    // Don't re-select already selected resulte
31983    if (
31984      (data.element != null && data.element.selected) ||
31985      (data.element == null && data.selected)
31986    ) {
31987      return;
31988    }
31989
31990    this.trigger('select', {
31991        data: data
31992    });
31993  };
31994
31995  return SelectOnClose;
31996});
31997
31998S2.define('select2/dropdown/closeOnSelect',[
31999
32000], function () {
32001  function CloseOnSelect () { }
32002
32003  CloseOnSelect.prototype.bind = function (decorated, container, $container) {
32004    var self = this;
32005
32006    decorated.call(this, container, $container);
32007
32008    container.on('select', function (evt) {
32009      self._selectTriggered(evt);
32010    });
32011
32012    container.on('unselect', function (evt) {
32013      self._selectTriggered(evt);
32014    });
32015  };
32016
32017  CloseOnSelect.prototype._selectTriggered = function (_, evt) {
32018    var originalEvent = evt.originalEvent;
32019
32020    // Don't close if the control key is being held
32021    if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
32022      return;
32023    }
32024
32025    this.trigger('close', {
32026      originalEvent: originalEvent,
32027      originalSelect2Event: evt
32028    });
32029  };
32030
32031  return CloseOnSelect;
32032});
32033
32034S2.define('select2/i18n/en',[],function () {
32035  // English
32036  return {
32037    errorLoading: function () {
32038      return 'The results could not be loaded.';
32039    },
32040    inputTooLong: function (args) {
32041      var overChars = args.input.length - args.maximum;
32042
32043      var message = 'Please delete ' + overChars + ' character';
32044
32045      if (overChars != 1) {
32046        message += 's';
32047      }
32048
32049      return message;
32050    },
32051    inputTooShort: function (args) {
32052      var remainingChars = args.minimum - args.input.length;
32053
32054      var message = 'Please enter ' + remainingChars + ' or more characters';
32055
32056      return message;
32057    },
32058    loadingMore: function () {
32059      return 'Loading more results…';
32060    },
32061    maximumSelected: function (args) {
32062      var message = 'You can only select ' + args.maximum + ' item';
32063
32064      if (args.maximum != 1) {
32065        message += 's';
32066      }
32067
32068      return message;
32069    },
32070    noResults: function () {
32071      return 'No results found';
32072    },
32073    searching: function () {
32074      return 'Searching…';
32075    },
32076    removeAllItems: function () {
32077      return 'Remove all items
vendor: 10,072 bytes, lines 32077-32449
32077';
32078    }
32079  };
32080});
32081
32082S2.define('select2/defaults',[
32083  'jquery',
32084  'require',
32085
32086  './results',
32087
32088  './selection/single',
32089  './selection/multiple',
32090  './selection/placeholder',
32091  './selection/allowClear',
32092  './selection/search',
32093  './selection/eventRelay',
32094
32095  './utils',
32096  './translation',
32097  './diacritics',
32098
32099  './data/select',
32100  './data/array',
32101  './data/ajax',
32102  './data/tags',
32103  './data/tokenizer',
32104  './data/minimumInputLength',
32105  './data/maximumInputLength',
32106  './data/maximumSelectionLength',
32107
32108  './dropdown',
32109  './dropdown/search',
32110  './dropdown/hidePlaceholder',
32111  './dropdown/infiniteScroll',
32112  './dropdown/attachBody',
32113  './dropdown/minimumResultsForSearch',
32114  './dropdown/selectOnClose',
32115  './dropdown/closeOnSelect',
32116
32117  './i18n/en'
32118], function ($, require,
32119
32120             ResultsList,
32121
32122             SingleSelection, MultipleSelection, Placeholder, AllowClear,
32123             SelectionSearch, EventRelay,
32124
32125             Utils, Translation, DIACRITICS,
32126
32127             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
32128             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
32129
32130             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
32131             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
32132
32133             EnglishTranslation) {
32134  function Defaults () {
32135    this.reset();
32136  }
32137
32138  Defaults.prototype.apply = function (options) {
32139    options = $.extend(true, {}, this.defaults, options);
32140
32141    if (options.dataAdapter == null) {
32142      if (options.ajax != null) {
32143        options.dataAdapter = AjaxData;
32144      } else if (options.data != null) {
32145        options.dataAdapter = ArrayData;
32146      } else {
32147        options.dataAdapter = SelectData;
32148      }
32149
32150      if (options.minimumInputLength > 0) {
32151        options.dataAdapter = Utils.Decorate(
32152          options.dataAdapter,
32153          MinimumInputLength
32154        );
32155      }
32156
32157      if (options.maximumInputLength > 0) {
32158        options.dataAdapter = Utils.Decorate(
32159          options.dataAdapter,
32160          MaximumInputLength
32161        );
32162      }
32163
32164      if (options.maximumSelectionLength > 0) {
32165        options.dataAdapter = Utils.Decorate(
32166          options.dataAdapter,
32167          MaximumSelectionLength
32168        );
32169      }
32170
32171      if (options.tags) {
32172        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
32173      }
32174
32175      if (options.tokenSeparators != null || options.tokenizer != null) {
32176        options.dataAdapter = Utils.Decorate(
32177          options.dataAdapter,
32178          Tokenizer
32179        );
32180      }
32181
32182      if (options.query != null) {
32183        var Query = require(options.amdBase + 'compat/query');
32184
32185        options.dataAdapter = Utils.Decorate(
32186          options.dataAdapter,
32187          Query
32188        );
32189      }
32190
32191      if (options.initSelection != null) {
32192        var InitSelection = require(options.amdBase + 'compat/initSelection');
32193
32194        options.dataAdapter = Utils.Decorate(
32195          options.dataAdapter,
32196          InitSelection
32197        );
32198      }
32199    }
32200
32201    if (options.resultsAdapter == null) {
32202      options.resultsAdapter = ResultsList;
32203
32204      if (options.ajax != null) {
32205        options.resultsAdapter = Utils.Decorate(
32206          options.resultsAdapter,
32207          InfiniteScroll
32208        );
32209      }
32210
32211      if (options.placeholder != null) {
32212        options.resultsAdapter = Utils.Decorate(
32213          options.resultsAdapter,
32214          HidePlaceholder
32215        );
32216      }
32217
32218      if (options.selectOnClose) {
32219        options.resultsAdapter = Utils.Decorate(
32220          options.resultsAdapter,
32221          SelectOnClose
32222        );
32223      }
32224    }
32225
32226    if (options.dropdownAdapter == null) {
32227      if (options.multiple) {
32228        options.dropdownAdapter = Dropdown;
32229      } else {
32230        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
32231
32232        options.dropdownAdapter = SearchableDropdown;
32233      }
32234
32235      if (options.minimumResultsForSearch !== 0) {
32236        options.dropdownAdapter = Utils.Decorate(
32237          options.dropdownAdapter,
32238          MinimumResultsForSearch
32239        );
32240      }
32241
32242      if (options.closeOnSelect) {
32243        options.dropdownAdapter = Utils.Decorate(
32244          options.dropdownAdapter,
32245          CloseOnSelect
32246        );
32247      }
32248
32249      if (
32250        options.dropdownCssClass != null ||
32251        options.dropdownCss != null ||
32252        options.adaptDropdownCssClass != null
32253      ) {
32254        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
32255
32256        options.dropdownAdapter = Utils.Decorate(
32257          options.dropdownAdapter,
32258          DropdownCSS
32259        );
32260      }
32261
32262      options.dropdownAdapter = Utils.Decorate(
32263        options.dropdownAdapter,
32264        AttachBody
32265      );
32266    }
32267
32268    if (options.selectionAdapter == null) {
32269      if (options.multiple) {
32270        options.selectionAdapter = MultipleSelection;
32271      } else {
32272        options.selectionAdapter = SingleSelection;
32273      }
32274
32275      // Add the placeholder mixin if a placeholder was specified
32276      if (options.placeholder != null) {
32277        options.selectionAdapter = Utils.Decorate(
32278          options.selectionAdapter,
32279          Placeholder
32280        );
32281      }
32282
32283      if (options.allowClear) {
32284        options.selectionAdapter = Utils.Decorate(
32285          options.selectionAdapter,
32286          AllowClear
32287        );
32288      }
32289
32290      if (options.multiple) {
32291        options.selectionAdapter = Utils.Decorate(
32292          options.selectionAdapter,
32293          SelectionSearch
32294        );
32295      }
32296
32297      if (
32298        options.containerCssClass != null ||
32299        options.containerCss != null ||
32300        options.adaptContainerCssClass != null
32301      ) {
32302        var ContainerCSS = require(options.amdBase + 'compat/containerCss');
32303
32304        options.selectionAdapter = Utils.Decorate(
32305          options.selectionAdapter,
32306          ContainerCSS
32307        );
32308      }
32309
32310      options.selectionAdapter = Utils.Decorate(
32311        options.selectionAdapter,
32312        EventRelay
32313      );
32314    }
32315
32316    if (typeof options.language === 'string') {
32317      // Check if the language is specified with a region
32318      if (options.language.indexOf('-') > 0) {
32319        // Extract the region information if it is included
32320        var languageParts = options.language.split('-');
32321        var baseLanguage = languageParts[0];
32322
32323        options.language = [options.language, baseLanguage];
32324      } else {
32325        options.language = [options.language];
32326      }
32327    }
32328
32329    if ($.isArray(options.language)) {
32330      var languages = new Translation();
32331      options.language.push('en');
32332
32333      var languageNames = options.language;
32334
32335      for (var l = 0; l < languageNames.length; l++) {
32336        var name = languageNames[l];
32337        var language = {};
32338
32339        try {
32340          // Try to load it with the original name
32341          language = Translation.loadPath(name);
32342        } catch (e) {
32343          try {
32344            // If we couldn't load it, check if it wasn't the full path
32345            name = this.defaults.amdLanguageBase + name;
32346            language = Translation.loadPath(name);
32347          } catch (ex) {
32348            // The translation could not be loaded at all. Sometimes this is
32349            // because of a configuration problem, other times this can be
32350            // because of how Select2 helps load all possible translation files.
32351            if (options.debug && window.console && console.warn) {
32352              console.warn(
32353                'Select2: The language file for "' + name + '" could not be ' +
32354                'automatically loaded. A fallback will be used instead.'
32355              );
32356            }
32357
32358            continue;
32359          }
32360        }
32361
32362        languages.extend(language);
32363      }
32364
32365      options.translations = languages;
32366    } else {
32367      var baseTranslation = Translation.loadPath(
32368        this.defaults.amdLanguageBase + 'en'
32369      );
32370      var customTranslation = new Translation(options.language);
32371
32372      customTranslation.extend(baseTranslation);
32373
32374      options.translations = customTranslation;
32375    }
32376
32377    return options;
32378  };
32379
32380  Defaults.prototype.reset = function () {
32381    function stripDiacritics (text) {
32382      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
32383      function match(a) {
32384        return DIACRITICS[a] || a;
32385      }
32386
32387      return text.replace(/[^\u0000-\u007E]/g, match);
32388    }
32389
32390    function matcher (params, data) {
32391      // Always return the object if there is nothing to compare
32392      if ($.trim(params.term) === '') {
32393        return data;
32394      }
32395
32396      // Do a recursive check for options with children
32397      if (data.children && data.children.length > 0) {
32398        // Clone the data object if there are children
32399        // This is required as we modify the object to remove any non-matches
32400        var match = $.extend(true, {}, data);
32401
32402        // Check each child of the option
32403        for (var c = data.children.length - 1; c >= 0; c--) {
32404          var child = data.children[c];
32405
32406          var matches = matcher(params, child);
32407
32408          // If there wasn't a match, remove the object in the array
32409          if (matches == null) {
32410            match.children.splice(c, 1);
32411          }
32412        }
32413
32414        // If any children matched, return the new object
32415        if (match.children.length > 0) {
32416          return match;
32417        }
32418
32419        // If there were no matching children, check just the plain object
32420        return matcher(params, match);
32421      }
32422
32423      var original = stripDiacritics(data.text).toUpperCase();
32424      var term = stripDiacritics(params.term).toUpperCase();
32425
32426      // Check if the text contains the term
32427      if (original.indexOf(term) > -1) {
32428        return data;
32429      }
32430
32431      // If it doesn't contain the term, don't return anything
32432      return null;
32433    }
32434
32435    this.defaults = {
32436      amdBase: './',
32437      amdLanguageBase: './i18n/',
32438      closeOnSelect: true,
32439      debug: false,
32440      dropdownAutoWidth: false,
32441      escapeMarkup: Utils.escapeMarkup,
32442      language: EnglishTranslation,
32443      matcher: matcher,
32444      minimumInputLength: 0,
32445      maximumInputLength: 0,
32446      maximumSelectionLength: 0,
32447      minimumResultsForSearch: 0,
32448      selectOnClose: false,
32449      s
vendor: 20,708 bytes, lines 32449-33244
32449crollAfterSelect: false,
32450      sorter: function (data) {
32451        return data;
32452      },
32453      templateResult: function (result) {
32454        return result.text;
32455      },
32456      templateSelection: function (selection) {
32457        return selection.text;
32458      },
32459      theme: 'default',
32460      width: 'resolve'
32461    };
32462  };
32463
32464  Defaults.prototype.set = function (key, value) {
32465    var camelKey = $.camelCase(key);
32466
32467    var data = {};
32468    data[camelKey] = value;
32469
32470    var convertedData = Utils._convertData(data);
32471
32472    $.extend(true, this.defaults, convertedData);
32473  };
32474
32475  var defaults = new Defaults();
32476
32477  return defaults;
32478});
32479
32480S2.define('select2/options',[
32481  'require',
32482  'jquery',
32483  './defaults',
32484  './utils'
32485], function (require, $, Defaults, Utils) {
32486  function Options (options, $element) {
32487    this.options = options;
32488
32489    if ($element != null) {
32490      this.fromElement($element);
32491    }
32492
32493    this.options = Defaults.apply(this.options);
32494
32495    if ($element && $element.is('input')) {
32496      var InputCompat = require(this.get('amdBase') + 'compat/inputData');
32497
32498      this.options.dataAdapter = Utils.Decorate(
32499        this.options.dataAdapter,
32500        InputCompat
32501      );
32502    }
32503  }
32504
32505  Options.prototype.fromElement = function ($e) {
32506    var excludedData = ['select2'];
32507
32508    if (this.options.multiple == null) {
32509      this.options.multiple = $e.prop('multiple');
32510    }
32511
32512    if (this.options.disabled == null) {
32513      this.options.disabled = $e.prop('disabled');
32514    }
32515
32516    if (this.options.language == null) {
32517      if ($e.prop('lang')) {
32518        this.options.language = $e.prop('lang').toLowerCase();
32519      } else if ($e.closest('[lang]').prop('lang')) {
32520        this.options.language = $e.closest('[lang]').prop('lang');
32521      }
32522    }
32523
32524    if (this.options.dir == null) {
32525      if ($e.prop('dir')) {
32526        this.options.dir = $e.prop('dir');
32527      } else if ($e.closest('[dir]').prop('dir')) {
32528        this.options.dir = $e.closest('[dir]').prop('dir');
32529      } else {
32530        this.options.dir = 'ltr';
32531      }
32532    }
32533
32534    $e.prop('disabled', this.options.disabled);
32535    $e.prop('multiple', this.options.multiple);
32536
32537    if (Utils.GetData($e[0], 'select2Tags')) {
32538      if (this.options.debug && window.console && console.warn) {
32539        console.warn(
32540          'Select2: The `data-select2-tags` attribute has been changed to ' +
32541          'use the `data-data` and `data-tags="true"` attributes and will be ' +
32542          'removed in future versions of Select2.'
32543        );
32544      }
32545
32546      Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
32547      Utils.StoreData($e[0], 'tags', true);
32548    }
32549
32550    if (Utils.GetData($e[0], 'ajaxUrl')) {
32551      if (this.options.debug && window.console && console.warn) {
32552        console.warn(
32553          'Select2: The `data-ajax-url` attribute has been changed to ' +
32554          '`data-ajax--url` and support for the old attribute will be removed' +
32555          ' in future versions of Select2.'
32556        );
32557      }
32558
32559      $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
32560      Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
32561    }
32562
32563    var dataset = {};
32564
32565    function upperCaseLetter(_, letter) {
32566      return letter.toUpperCase();
32567    }
32568
32569    // Pre-load all of the attributes which are prefixed with `data-`
32570    for (var attr = 0; attr < $e[0].attributes.length; attr++) {
32571      var attributeName = $e[0].attributes[attr].name;
32572      var prefix = 'data-';
32573
32574      if (attributeName.substr(0, prefix.length) == prefix) {
32575        // Get the contents of the attribute after `data-`
32576        var dataName = attributeName.substring(prefix.length);
32577
32578        // Get the data contents from the consistent source
32579        // This is more than likely the jQuery data helper
32580        var dataValue = Utils.GetData($e[0], dataName);
32581
32582        // camelCase the attribute name to match the spec
32583        var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
32584
32585        // Store the data attribute contents into the dataset since
32586        dataset[camelDataName] = dataValue;
32587      }
32588    }
32589
32590    // Prefer the element's `dataset` attribute if it exists
32591    // jQuery 1.x does not correctly handle data attributes with multiple dashes
32592    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
32593      dataset = $.extend(true, {}, $e[0].dataset, dataset);
32594    }
32595
32596    // Prefer our internal data cache if it exists
32597    var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
32598
32599    data = Utils._convertData(data);
32600
32601    for (var key in data) {
32602      if ($.inArray(key, excludedData) > -1) {
32603        continue;
32604      }
32605
32606      if ($.isPlainObject(this.options[key])) {
32607        $.extend(this.options[key], data[key]);
32608      } else {
32609        this.options[key] = data[key];
32610      }
32611    }
32612
32613    return this;
32614  };
32615
32616  Options.prototype.get = function (key) {
32617    return this.options[key];
32618  };
32619
32620  Options.prototype.set = function (key, val) {
32621    this.options[key] = val;
32622  };
32623
32624  return Options;
32625});
32626
32627S2.define('select2/core',[
32628  'jquery',
32629  './options',
32630  './utils',
32631  './keys'
32632], function ($, Options, Utils, KEYS) {
32633  var Select2 = function ($element, options) {
32634    if (Utils.GetData($element[0], 'select2') != null) {
32635      Utils.GetData($element[0], 'select2').destroy();
32636    }
32637
32638    this.$element = $element;
32639
32640    this.id = this._generateId($element);
32641
32642    options = options || {};
32643
32644    this.options = new Options(options, $element);
32645
32646    Select2.__super__.constructor.call(this);
32647
32648    // Set up the tabindex
32649
32650    var tabindex = $element.attr('tabindex') || 0;
32651    Utils.StoreData($element[0], 'old-tabindex', tabindex);
32652    $element.attr('tabindex', '-1');
32653
32654    // Set up containers and adapters
32655
32656    var DataAdapter = this.options.get('dataAdapter');
32657    this.dataAdapter = new DataAdapter($element, this.options);
32658
32659    var $container = this.render();
32660
32661    this._placeContainer($container);
32662
32663    var SelectionAdapter = this.options.get('selectionAdapter');
32664    this.selection = new SelectionAdapter($element, this.options);
32665    this.$selection = this.selection.render();
32666
32667    this.selection.position(this.$selection, $container);
32668
32669    var DropdownAdapter = this.options.get('dropdownAdapter');
32670    this.dropdown = new DropdownAdapter($element, this.options);
32671    this.$dropdown = this.dropdown.render();
32672
32673    this.dropdown.position(this.$dropdown, $container);
32674
32675    var ResultsAdapter = this.options.get('resultsAdapter');
32676    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
32677    this.$results = this.results.render();
32678
32679    this.results.position(this.$results, this.$dropdown);
32680
32681    // Bind events
32682
32683    var self = this;
32684
32685    // Bind the container to all of the adapters
32686    this._bindAdapters();
32687
32688    // Register any DOM event handlers
32689    this._registerDomEvents();
32690
32691    // Register any internal event handlers
32692    this._registerDataEvents();
32693    this._registerSelectionEvents();
32694    this._registerDropdownEvents();
32695    this._registerResultsEvents();
32696    this._registerEvents();
32697
32698    // Set the initial state
32699    this.dataAdapter.current(function (initialData) {
32700      self.trigger('selection:update', {
32701        data: initialData
32702      });
32703    });
32704
32705    // Hide the original select
32706    $element.addClass('select2-hidden-accessible');
32707    $element.attr('aria-hidden', 'true');
32708
32709    // Synchronize any monitored attributes
32710    this._syncAttributes();
32711
32712    Utils.StoreData($element[0], 'select2', this);
32713
32714    // Ensure backwards compatibility with $element.data('select2').
32715    $element.data('select2', this);
32716  };
32717
32718  Utils.Extend(Select2, Utils.Observable);
32719
32720  Select2.prototype._generateId = function ($element) {
32721    var id = '';
32722
32723    if ($element.attr('id') != null) {
32724      id = $element.attr('id');
32725    } else if ($element.attr('name') != null) {
32726      id = $element.attr('name') + '-' + Utils.generateChars(2);
32727    } else {
32728      id = Utils.generateChars(4);
32729    }
32730
32731    id = id.replace(/(:|\.|\[|\]|,)/g, '');
32732    id = 'select2-' + id;
32733
32734    return id;
32735  };
32736
32737  Select2.prototype._placeContainer = function ($container) {
32738    $container.insertAfter(this.$element);
32739
32740    var width = this._resolveWidth(this.$element, this.options.get('width'));
32741
32742    if (width != null) {
32743      $container.css('width', width);
32744    }
32745  };
32746
32747  Select2.prototype._resolveWidth = function ($element, method) {
32748    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
32749
32750    if (method == 'resolve') {
32751      var styleWidth = this._resolveWidth($element, 'style');
32752
32753      if (styleWidth != null) {
32754        return styleWidth;
32755      }
32756
32757      return this._resolveWidth($element, 'element');
32758    }
32759
32760    if (method == 'element') {
32761      var elementWidth = $element.outerWidth(false);
32762
32763      if (elementWidth <= 0) {
32764        return 'auto';
32765      }
32766
32767      return elementWidth + 'px';
32768    }
32769
32770    if (method == 'style') {
32771      var style = $element.attr('style');
32772
32773      if (typeof(style) !== 'string') {
32774        return null;
32775      }
32776
32777      var attrs = style.split(';');
32778
32779      for (var i = 0, l = attrs.length; i < l; i = i + 1) {
32780        var attr = attrs[i].replace(/\s/g, '');
32781        var matches = attr.match(WIDTH);
32782
32783        if (matches !== null && matches.length >= 1) {
32784          return matches[1];
32785        }
32786      }
32787
32788      return null;
32789    }
32790
32791    if (method == 'computedstyle') {
32792      var computedStyle = window.getComputedStyle($element[0]);
32793
32794      return computedStyle.width;
32795    }
32796
32797    return method;
32798  };
32799
32800  Select2.prototype._bindAdapters = function () {
32801    this.dataAdapter.bind(this, this.$container);
32802    this.selection.bind(this, this.$container);
32803
32804    this.dropdown.bind(this, this.$container);
32805    this.results.bind(this, this.$container);
32806  };
32807
32808  Select2.prototype._registerDomEvents = function () {
32809    var self = this;
32810
32811    this.$element.on('change.select2', function () {
32812      self.dataAdapter.current(function (data) {
32813        self.trigger('selection:update', {
32814          data: data
32815        });
32816      });
32817    });
32818
32819    this.$element.on('focus.select2', function (evt) {
32820      self.trigger('focus', evt);
32821    });
32822
32823    this._syncA = Utils.bind(this._syncAttributes, this);
32824    this._syncS = Utils.bind(this._syncSubtree, this);
32825
32826    if (this.$element[0].attachEvent) {
32827      this.$element[0].attachEvent('onpropertychange', this._syncA);
32828    }
32829
32830    var observer = window.MutationObserver ||
32831      window.WebKitMutationObserver ||
32832      window.MozMutationObserver
32833    ;
32834
32835    if (observer != null) {
32836      this._observer = new observer(function (mutations) {
32837        $.each(mutations, self._syncA);
32838        $.each(mutations, self._syncS);
32839      });
32840      this._observer.observe(this.$element[0], {
32841        attributes: true,
32842        childList: true,
32843        subtree: false
32844      });
32845    } else if (this.$element[0].addEventListener) {
32846      this.$element[0].addEventListener(
32847        'DOMAttrModified',
32848        self._syncA,
32849        false
32850      );
32851      this.$element[0].addEventListener(
32852        'DOMNodeInserted',
32853        self._syncS,
32854        false
32855      );
32856      this.$element[0].addEventListener(
32857        'DOMNodeRemoved',
32858        self._syncS,
32859        false
32860      );
32861    }
32862  };
32863
32864  Select2.prototype._registerDataEvents = function () {
32865    var self = this;
32866
32867    this.dataAdapter.on('*', function (name, params) {
32868      self.trigger(name, params);
32869    });
32870  };
32871
32872  Select2.prototype._registerSelectionEvents = function () {
32873    var self = this;
32874    var nonRelayEvents = ['toggle', 'focus'];
32875
32876    this.selection.on('toggle', function () {
32877      self.toggleDropdown();
32878    });
32879
32880    this.selection.on('focus', function (params) {
32881      self.focus(params);
32882    });
32883
32884    this.selection.on('*', function (name, params) {
32885      if ($.inArray(name, nonRelayEvents) !== -1) {
32886        return;
32887      }
32888
32889      self.trigger(name, params);
32890    });
32891  };
32892
32893  Select2.prototype._registerDropdownEvents = function () {
32894    var self = this;
32895
32896    this.dropdown.on('*', function (name, params) {
32897      self.trigger(name, params);
32898    });
32899  };
32900
32901  Select2.prototype._registerResultsEvents = function () {
32902    var self = this;
32903
32904    this.results.on('*', function (name, params) {
32905      self.trigger(name, params);
32906    });
32907  };
32908
32909  Select2.prototype._registerEvents = function () {
32910    var self = this;
32911
32912    this.on('open', function () {
32913      self.$container.addClass('select2-container--open');
32914    });
32915
32916    this.on('close', function () {
32917      self.$container.removeClass('select2-container--open');
32918    });
32919
32920    this.on('enable', function () {
32921      self.$container.removeClass('select2-container--disabled');
32922    });
32923
32924    this.on('disable', function () {
32925      self.$container.addClass('select2-container--disabled');
32926    });
32927
32928    this.on('blur', function () {
32929      self.$container.removeClass('select2-container--focus');
32930    });
32931
32932    this.on('query', function (params) {
32933      if (!self.isOpen()) {
32934        self.trigger('open', {});
32935      }
32936
32937      this.dataAdapter.query(params, function (data) {
32938        self.trigger('results:all', {
32939          data: data,
32940          query: params
32941        });
32942      });
32943    });
32944
32945    this.on('query:append', function (params) {
32946      this.dataAdapter.query(params, function (data) {
32947        self.trigger('results:append', {
32948          data: data,
32949          query: params
32950        });
32951      });
32952    });
32953
32954    this.on('keypress', function (evt) {
32955      var key = evt.which;
32956
32957      if (self.isOpen()) {
32958        if (key === KEYS.ESC || key === KEYS.TAB ||
32959            (key === KEYS.UP && evt.altKey)) {
32960          self.close();
32961
32962          evt.preventDefault();
32963        } else if (key === KEYS.ENTER) {
32964          self.trigger('results:select', {});
32965
32966          evt.preventDefault();
32967        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
32968          self.trigger('results:toggle', {});
32969
32970          evt.preventDefault();
32971        } else if (key === KEYS.UP) {
32972          self.trigger('results:previous', {});
32973
32974          evt.preventDefault();
32975        } else if (key === KEYS.DOWN) {
32976          self.trigger('results:next', {});
32977
32978          evt.preventDefault();
32979        }
32980      } else {
32981        if (key === KEYS.ENTER || key === KEYS.SPACE ||
32982            (key === KEYS.DOWN && evt.altKey)) {
32983          self.open();
32984
32985          evt.preventDefault();
32986        }
32987      }
32988    });
32989  };
32990
32991  Select2.prototype._syncAttributes = function () {
32992    this.options.set('disabled', this.$element.prop('disabled'));
32993
32994    if (this.options.get('disabled')) {
32995      if (this.isOpen()) {
32996        this.close();
32997      }
32998
32999      this.trigger('disable', {});
33000    } else {
33001      this.trigger('enable', {});
33002    }
33003  };
33004
33005  Select2.prototype._syncSubtree = function (evt, mutations) {
33006    var changed = false;
33007    var self = this;
33008
33009    // Ignore any mutation events raised for elements that aren't options or
33010    // optgroups. This handles the case when the select element is destroyed
33011    if (
33012      evt && evt.target && (
33013        evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
33014      )
33015    ) {
33016      return;
33017    }
33018
33019    if (!mutations) {
33020      // If mutation events aren't supported, then we can only assume that the
33021      // change affected the selections
33022      changed = true;
33023    } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
33024      for (var n = 0; n < mutations.addedNodes.length; n++) {
33025        var node = mutations.addedNodes[n];
33026
33027        if (node.selected) {
33028          changed = true;
33029        }
33030      }
33031    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
33032      changed = true;
33033    }
33034
33035    // Only re-pull the data if we think there is a change
33036    if (changed) {
33037      this.dataAdapter.current(function (currentData) {
33038        self.trigger('selection:update', {
33039          data: currentData
33040        });
33041      });
33042    }
33043  };
33044
33045  /**
33046   * Override the trigger method to automatically trigger pre-events when
33047   * there are events that can be prevented.
33048   */
33049  Select2.prototype.trigger = function (name, args) {
33050    var actualTrigger = Select2.__super__.trigger;
33051    var preTriggerMap = {
33052      'open': 'opening',
33053      'close': 'closing',
33054      'select': 'selecting',
33055      'unselect': 'unselecting',
33056      'clear': 'clearing'
33057    };
33058
33059    if (args === undefined) {
33060      args = {};
33061    }
33062
33063    if (name in preTriggerMap) {
33064      var preTriggerName = preTriggerMap[name];
33065      var preTriggerArgs = {
33066        prevented: false,
33067        name: name,
33068        args: args
33069      };
33070
33071      actualTrigger.call(this, preTriggerName, preTriggerArgs);
33072
33073      if (preTriggerArgs.prevented) {
33074        args.prevented = true;
33075
33076        return;
33077      }
33078    }
33079
33080    actualTrigger.call(this, name, args);
33081  };
33082
33083  Select2.prototype.toggleDropdown = function () {
33084    if (this.options.get('disabled')) {
33085      return;
33086    }
33087
33088    if (this.isOpen()) {
33089      this.close();
33090    } else {
33091      this.open();
33092    }
33093  };
33094
33095  Select2.prototype.open = function () {
33096    if (this.isOpen()) {
33097      return;
33098    }
33099
33100    this.trigger('query', {});
33101  };
33102
33103  Select2.prototype.close = function () {
33104    if (!this.isOpen()) {
33105      return;
33106    }
33107
33108    this.trigger('close', {});
33109  };
33110
33111  Select2.prototype.isOpen = function () {
33112    return this.$container.hasClass('select2-container--open');
33113  };
33114
33115  Select2.prototype.hasFocus = function () {
33116    return this.$container.hasClass('select2-container--focus');
33117  };
33118
33119  Select2.prototype.focus = function (data) {
33120    // No need to re-trigger focus events if we are already focused
33121    if (this.hasFocus()) {
33122      return;
33123    }
33124
33125    this.$container.addClass('select2-container--focus');
33126    this.trigger('focus', {});
33127  };
33128
33129  Select2.prototype.enable = function (args) {
33130    if (this.options.get('debug') && window.console && console.warn) {
33131      console.warn(
33132        'Select2: The `select2("enable")` method has been deprecated and will' +
33133        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
33134        ' instead.'
33135      );
33136    }
33137
33138    if (args == null || args.length === 0) {
33139      args = [true];
33140    }
33141
33142    var disabled = !args[0];
33143
33144    this.$element.prop('disabled', disabled);
33145  };
33146
33147  Select2.prototype.data = function () {
33148    if (this.options.get('debug') &&
33149        arguments.length > 0 && window.console && console.warn) {
33150      console.warn(
33151        'Select2: Data can no longer be set using `select2("data")`. You ' +
33152        'should consider setting the value instead using `$element.val()`.'
33153      );
33154    }
33155
33156    var data = [];
33157
33158    this.dataAdapter.current(function (currentData) {
33159      data = currentData;
33160    });
33161
33162    return data;
33163  };
33164
33165  Select2.prototype.val = function (args) {
33166    if (this.options.get('debug') && window.console && console.warn) {
33167      console.warn(
33168        'Select2: The `select2("val")` method has been deprecated and will be' +
33169        ' removed in later Select2 versions. Use $element.val() instead.'
33170      );
33171    }
33172
33173    if (args == null || args.length === 0) {
33174      return this.$element.val();
33175    }
33176
33177    var newVal = args[0];
33178
33179    if ($.isArray(newVal)) {
33180      newVal = $.map(newVal, function (obj) {
33181        return obj.toString();
33182      });
33183    }
33184
33185    this.$element.val(newVal).trigger('change');
33186  };
33187
33188  Select2.prototype.destroy = function () {
33189    this.$container.remove();
33190
33191    if (this.$element[0].detachEvent) {
33192      this.$element[0].detachEvent('onpropertychange', this._syncA);
33193    }
33194
33195    if (this._observer != null) {
33196      this._observer.disconnect();
33197      this._observer = null;
33198    } else if (this.$element[0].removeEventListener) {
33199      this.$element[0]
33200        .removeEventListener('DOMAttrModified', this._syncA, false);
33201      this.$element[0]
33202        .removeEventListener('DOMNodeInserted', this._syncS, false);
33203      this.$element[0]
33204        .removeEventListener('DOMNodeRemoved', this._syncS, false);
33205    }
33206
33207    this._syncA = null;
33208    this._syncS = null;
33209
33210    this.$element.off('.select2');
33211    this.$element.attr('tabindex',
33212    Utils.GetData(this.$element[0], 'old-tabindex'));
33213
33214    this.$element.removeClass('select2-hidden-accessible');
33215    this.$element.attr('aria-hidden', 'false');
33216    Utils.RemoveData(this.$element[0]);
33217    this.$element.removeData('select2');
33218
33219    this.dataAdapter.destroy();
33220    this.selection.destroy();
33221    this.dropdown.destroy();
33222    this.results.destroy();
33223
33224    this.dataAdapter = null;
33225    this.selection = null;
33226    this.dropdown = null;
33227    this.results = null;
33228  };
33229
33230  Select2.prototype.render = function () {
33231    var $container = $(
33232      '<span class="select2 select2-container">' +
33233        '<span class="selection"></span>' +
33234        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
33235      '</span>'
33236    );
33237
33238    $container.attr('dir', this.options.get('dir'));
33239
33240    this.$container = $container;
33241
33242    this.$container.addClass('select2-container--' + this.options.get('theme'));
33243
33244    Utils.StoreData($container[0], 
vendor: 5,228 bytes, lines 33244-33454
33244'element', this.$element);
33245
33246    return $container;
33247  };
33248
33249  return Select2;
33250});
33251
33252S2.define('select2/compat/utils',[
33253  'jquery'
33254], function ($) {
33255  function syncCssClasses ($dest, $src, adapter) {
33256    var classes, replacements = [], adapted;
33257
33258    classes = $.trim($dest.attr('class'));
33259
33260    if (classes) {
33261      classes = '' + classes; // for IE which returns object
33262
33263      $(classes.split(/\s+/)).each(function () {
33264        // Save all Select2 classes
33265        if (this.indexOf('select2-') === 0) {
33266          replacements.push(this);
33267        }
33268      });
33269    }
33270
33271    classes = $.trim($src.attr('class'));
33272
33273    if (classes) {
33274      classes = '' + classes; // for IE which returns object
33275
33276      $(classes.split(/\s+/)).each(function () {
33277        // Only adapt non-Select2 classes
33278        if (this.indexOf('select2-') !== 0) {
33279          adapted = adapter(this);
33280
33281          if (adapted != null) {
33282            replacements.push(adapted);
33283          }
33284        }
33285      });
33286    }
33287
33288    $dest.attr('class', replacements.join(' '));
33289  }
33290
33291  return {
33292    syncCssClasses: syncCssClasses
33293  };
33294});
33295
33296S2.define('select2/compat/containerCss',[
33297  'jquery',
33298  './utils'
33299], function ($, CompatUtils) {
33300  // No-op CSS adapter that discards all classes by default
33301  function _containerAdapter (clazz) {
33302    return null;
33303  }
33304
33305  function ContainerCSS () { }
33306
33307  ContainerCSS.prototype.render = function (decorated) {
33308    var $container = decorated.call(this);
33309
33310    var containerCssClass = this.options.get('containerCssClass') || '';
33311
33312    if ($.isFunction(containerCssClass)) {
33313      containerCssClass = containerCssClass(this.$element);
33314    }
33315
33316    var containerCssAdapter = this.options.get('adaptContainerCssClass');
33317    containerCssAdapter = containerCssAdapter || _containerAdapter;
33318
33319    if (containerCssClass.indexOf(':all:') !== -1) {
33320      containerCssClass = containerCssClass.replace(':all:', '');
33321
33322      var _cssAdapter = containerCssAdapter;
33323
33324      containerCssAdapter = function (clazz) {
33325        var adapted = _cssAdapter(clazz);
33326
33327        if (adapted != null) {
33328          // Append the old one along with the adapted one
33329          return adapted + ' ' + clazz;
33330        }
33331
33332        return clazz;
33333      };
33334    }
33335
33336    var containerCss = this.options.get('containerCss') || {};
33337
33338    if ($.isFunction(containerCss)) {
33339      containerCss = containerCss(this.$element);
33340    }
33341
33342    CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
33343
33344    $container.css(containerCss);
33345    $container.addClass(containerCssClass);
33346
33347    return $container;
33348  };
33349
33350  return ContainerCSS;
33351});
33352
33353S2.define('select2/compat/dropdownCss',[
33354  'jquery',
33355  './utils'
33356], function ($, CompatUtils) {
33357  // No-op CSS adapter that discards all classes by default
33358  function _dropdownAdapter (clazz) {
33359    return null;
33360  }
33361
33362  function DropdownCSS () { }
33363
33364  DropdownCSS.prototype.render = function (decorated) {
33365    var $dropdown = decorated.call(this);
33366
33367    var dropdownCssClass = this.options.get('dropdownCssClass') || '';
33368
33369    if ($.isFunction(dropdownCssClass)) {
33370      dropdownCssClass = dropdownCssClass(this.$element);
33371    }
33372
33373    var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
33374    dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
33375
33376    if (dropdownCssClass.indexOf(':all:') !== -1) {
33377      dropdownCssClass = dropdownCssClass.replace(':all:', '');
33378
33379      var _cssAdapter = dropdownCssAdapter;
33380
33381      dropdownCssAdapter = function (clazz) {
33382        var adapted = _cssAdapter(clazz);
33383
33384        if (adapted != null) {
33385          // Append the old one along with the adapted one
33386          return adapted + ' ' + clazz;
33387        }
33388
33389        return clazz;
33390      };
33391    }
33392
33393    var dropdownCss = this.options.get('dropdownCss') || {};
33394
33395    if ($.isFunction(dropdownCss)) {
33396      dropdownCss = dropdownCss(this.$element);
33397    }
33398
33399    CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
33400
33401    $dropdown.css(dropdownCss);
33402    $dropdown.addClass(dropdownCssClass);
33403
33404    return $dropdown;
33405  };
33406
33407  return DropdownCSS;
33408});
33409
33410S2.define('select2/compat/initSelection',[
33411  'jquery'
33412], function ($) {
33413  function InitSelection (decorated, $element, options) {
33414    if (options.get('debug') && window.console && console.warn) {
33415      console.warn(
33416        'Select2: The `initSelection` option has been deprecated in favor' +
33417        ' of a custom data adapter that overrides the `current` method. ' +
33418        'This method is now called multiple times instead of a single ' +
33419        'time when the instance is initialized. Support will be removed ' +
33420        'for the `initSelection` option in future versions of Select2'
33421      );
33422    }
33423
33424    this.initSelection = options.get('initSelection');
33425    this._isInitialized = false;
33426
33427    decorated.call(this, $element, options);
33428  }
33429
33430  InitSelection.prototype.current = function (decorated, callback) {
33431    var self = this;
33432
33433    if (this._isInitialized) {
33434      decorated.call(this, callback);
33435
33436      return;
33437    }
33438
33439    this.initSelection.call(null, this.$element, function (data) {
33440      self._isInitialized = true;
33441
33442      if (!$.isArray(data)) {
33443        data = [data];
33444      }
33445
33446      callback(data);
33447    });
33448  };
33449
33450  return InitSelection;
33451});
33452
33453S2.define('select2/compat/inputData',[
33454  'jquery'
vendor: 2,840 bytes, lines 33454-33573
33454,
33455  '../utils'
33456], function ($, Utils) {
33457  function InputData (decorated, $element, options) {
33458    this._currentData = [];
33459    this._valueSeparator = options.get('valueSeparator') || ',';
33460
33461    if ($element.prop('type') === 'hidden') {
33462      if (options.get('debug') && console && console.warn) {
33463        console.warn(
33464          'Select2: Using a hidden input with Select2 is no longer ' +
33465          'supported and may stop working in the future. It is recommended ' +
33466          'to use a `<select>` element instead.'
33467        );
33468      }
33469    }
33470
33471    decorated.call(this, $element, options);
33472  }
33473
33474  InputData.prototype.current = function (_, callback) {
33475    function getSelected (data, selectedIds) {
33476      var selected = [];
33477
33478      if (data.selected || $.inArray(data.id, selectedIds) !== -1) {
33479        data.selected = true;
33480        selected.push(data);
33481      } else {
33482        data.selected = false;
33483      }
33484
33485      if (data.children) {
33486        selected.push.apply(selected, getSelected(data.children, selectedIds));
33487      }
33488
33489      return selected;
33490    }
33491
33492    var selected = [];
33493
33494    for (var d = 0; d < this._currentData.length; d++) {
33495      var data = this._currentData[d];
33496
33497      selected.push.apply(
33498        selected,
33499        getSelected(
33500          data,
33501          this.$element.val().split(
33502            this._valueSeparator
33503          )
33504        )
33505      );
33506    }
33507
33508    callback(selected);
33509  };
33510
33511  InputData.prototype.select = function (_, data) {
33512    if (!this.options.get('multiple')) {
33513      this.current(function (allData) {
33514        $.map(allData, function (data) {
33515          data.selected = false;
33516        });
33517      });
33518
33519      this.$element.val(data.id);
33520      this.$element.trigger('change');
33521    } else {
33522      var value = this.$element.val();
33523      value += this._valueSeparator + data.id;
33524
33525      this.$element.val(value);
33526      this.$element.trigger('change');
33527    }
33528  };
33529
33530  InputData.prototype.unselect = function (_, data) {
33531    var self = this;
33532
33533    data.selected = false;
33534
33535    this.current(function (allData) {
33536      var values = [];
33537
33538      for (var d = 0; d < allData.length; d++) {
33539        var item = allData[d];
33540
33541        if (data.id == item.id) {
33542          continue;
33543        }
33544
33545        values.push(item.id);
33546      }
33547
33548      self.$element.val(values.join(self._valueSeparator));
33549      self.$element.trigger('change');
33550    });
33551  };
33552
33553  InputData.prototype.query = function (_, params, callback) {
33554    var results = [];
33555
33556    for (var d = 0; d < this._currentData.length; d++) {
33557      var data = this._currentData[d];
33558
33559      var matches = this.matches(params, data);
33560
33561      if (matches !== null) {
33562        results.push(matches);
33563      }
33564    }
33565
33566    callback({
33567      results: results
33568    });
33569  };
33570
33571  InputData.prototype.addOptions = function (_, $options) {
33572    var options = $.map($options, function ($option) {
33573      return Utils.GetD
vendor: 12,180 bytes, lines 33573-33976
33573ata($option[0], 'data');
33574    });
33575
33576    this._currentData.push.apply(this._currentData, options);
33577  };
33578
33579  return InputData;
33580});
33581
33582S2.define('select2/compat/matcher',[
33583  'jquery'
33584], function ($) {
33585  function oldMatcher (matcher) {
33586    function wrappedMatcher (params, data) {
33587      var match = $.extend(true, {}, data);
33588
33589      if (params.term == null || $.trim(params.term) === '') {
33590        return match;
33591      }
33592
33593      if (data.children) {
33594        for (var c = data.children.length - 1; c >= 0; c--) {
33595          var child = data.children[c];
33596
33597          // Check if the child object matches
33598          // The old matcher returned a boolean true or false
33599          var doesMatch = matcher(params.term, child.text, child);
33600
33601          // If the child didn't match, pop it off
33602          if (!doesMatch) {
33603            match.children.splice(c, 1);
33604          }
33605        }
33606
33607        if (match.children.length > 0) {
33608          return match;
33609        }
33610      }
33611
33612      if (matcher(params.term, data.text, data)) {
33613        return match;
33614      }
33615
33616      return null;
33617    }
33618
33619    return wrappedMatcher;
33620  }
33621
33622  return oldMatcher;
33623});
33624
33625S2.define('select2/compat/query',[
33626
33627], function () {
33628  function Query (decorated, $element, options) {
33629    if (options.get('debug') && window.console && console.warn) {
33630      console.warn(
33631        'Select2: The `query` option has been deprecated in favor of a ' +
33632        'custom data adapter that overrides the `query` method. Support ' +
33633        'will be removed for the `query` option in future versions of ' +
33634        'Select2.'
33635      );
33636    }
33637
33638    decorated.call(this, $element, options);
33639  }
33640
33641  Query.prototype.query = function (_, params, callback) {
33642    params.callback = callback;
33643
33644    var query = this.options.get('query');
33645
33646    query.call(null, params);
33647  };
33648
33649  return Query;
33650});
33651
33652S2.define('select2/dropdown/attachContainer',[
33653
33654], function () {
33655  function AttachContainer (decorated, $element, options) {
33656    decorated.call(this, $element, options);
33657  }
33658
33659  AttachContainer.prototype.position =
33660    function (decorated, $dropdown, $container) {
33661    var $dropdownContainer = $container.find('.dropdown-wrapper');
33662    $dropdownContainer.append($dropdown);
33663
33664    $dropdown.addClass('select2-dropdown--below');
33665    $container.addClass('select2-container--below');
33666  };
33667
33668  return AttachContainer;
33669});
33670
33671S2.define('select2/dropdown/stopPropagation',[
33672
33673], function () {
33674  function StopPropagation () { }
33675
33676  StopPropagation.prototype.bind = function (decorated, container, $container) {
33677    decorated.call(this, container, $container);
33678
33679    var stoppedEvents = [
33680    'blur',
33681    'change',
33682    'click',
33683    'dblclick',
33684    'focus',
33685    'focusin',
33686    'focusout',
33687    'input',
33688    'keydown',
33689    'keyup',
33690    'keypress',
33691    'mousedown',
33692    'mouseenter',
33693    'mouseleave',
33694    'mousemove',
33695    'mouseover',
33696    'mouseup',
33697    'search',
33698    'touchend',
33699    'touchstart'
33700    ];
33701
33702    this.$dropdown.on(stoppedEvents.join(' '), function (evt) {
33703      evt.stopPropagation();
33704    });
33705  };
33706
33707  return StopPropagation;
33708});
33709
33710S2.define('select2/selection/stopPropagation',[
33711
33712], function () {
33713  function StopPropagation () { }
33714
33715  StopPropagation.prototype.bind = function (decorated, container, $container) {
33716    decorated.call(this, container, $container);
33717
33718    var stoppedEvents = [
33719      'blur',
33720      'change',
33721      'click',
33722      'dblclick',
33723      'focus',
33724      'focusin',
33725      'focusout',
33726      'input',
33727      'keydown',
33728      'keyup',
33729      'keypress',
33730      'mousedown',
33731      'mouseenter',
33732      'mouseleave',
33733      'mousemove',
33734      'mouseover',
33735      'mouseup',
33736      'search',
33737      'touchend',
33738      'touchstart'
33739    ];
33740
33741    this.$selection.on(stoppedEvents.join(' '), function (evt) {
33742      evt.stopPropagation();
33743    });
33744  };
33745
33746  return StopPropagation;
33747});
33748
33749/*!
33750 * jQuery Mousewheel 3.1.13
33751 *
33752 * Copyright jQuery Foundation and other contributors
33753 * Released under the MIT license
33754 * http://jquery.org/license
33755 */
33756
33757(function (factory) {
33758    if ( typeof S2.define === 'function' && S2.define.amd ) {
33759        // AMD. Register as an anonymous module.
33760        S2.define('jquery-mousewheel',['jquery'], factory);
33761    } else if (typeof exports === 'object') {
33762        // Node/CommonJS style for Browserify
33763        module.exports = factory;
33764    } else {
33765        // Browser globals
33766        factory(jQuery);
33767    }
33768}(function ($) {
33769
33770    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
33771        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
33772                    ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
33773        slice  = Array.prototype.slice,
33774        nullLowestDeltaTimeout, lowestDelta;
33775
33776    if ( $.event.fixHooks ) {
33777        for ( var i = toFix.length; i; ) {
33778            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
33779        }
33780    }
33781
33782    var special = $.event.special.mousewheel = {
33783        version: '3.1.12',
33784
33785        setup: function() {
33786            if ( this.addEventListener ) {
33787                for ( var i = toBind.length; i; ) {
33788                    this.addEventListener( toBind[--i], handler, false );
33789                }
33790            } else {
33791                this.onmousewheel = handler;
33792            }
33793            // Store the line height and page height for this particular element
33794            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
33795            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
33796        },
33797
33798        teardown: function() {
33799            if ( this.removeEventListener ) {
33800                for ( var i = toBind.length; i; ) {
33801                    this.removeEventListener( toBind[--i], handler, false );
33802                }
33803            } else {
33804                this.onmousewheel = null;
33805            }
33806            // Clean up the data we added to the element
33807            $.removeData(this, 'mousewheel-line-height');
33808            $.removeData(this, 'mousewheel-page-height');
33809        },
33810
33811        getLineHeight: function(elem) {
33812            var $elem = $(elem),
33813                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
33814            if (!$parent.length) {
33815                $parent = $('body');
33816            }
33817            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
33818        },
33819
33820        getPageHeight: function(elem) {
33821            return $(elem).height();
33822        },
33823
33824        settings: {
33825            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
33826            normalizeOffset: true  // calls getBoundingClientRect for each event
33827        }
33828    };
33829
33830    $.fn.extend({
33831        mousewheel: function(fn) {
33832            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
33833        },
33834
33835        unmousewheel: function(fn) {
33836            return this.unbind('mousewheel', fn);
33837        }
33838    });
33839
33840
33841    function handler(event) {
33842        var orgEvent   = event || window.event,
33843            args       = slice.call(arguments, 1),
33844            delta      = 0,
33845            deltaX     = 0,
33846            deltaY     = 0,
33847            absDelta   = 0,
33848            offsetX    = 0,
33849            offsetY    = 0;
33850        event = $.event.fix(orgEvent);
33851        event.type = 'mousewheel';
33852
33853        // Old school scrollwheel delta
33854        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
33855        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
33856        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
33857        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
33858
33859        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
33860        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
33861            deltaX = deltaY * -1;
33862            deltaY = 0;
33863        }
33864
33865        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
33866        delta = deltaY === 0 ? deltaX : deltaY;
33867
33868        // New school wheel delta (wheel event)
33869        if ( 'deltaY' in orgEvent ) {
33870            deltaY = orgEvent.deltaY * -1;
33871            delta  = deltaY;
33872        }
33873        if ( 'deltaX' in orgEvent ) {
33874            deltaX = orgEvent.deltaX;
33875            if ( deltaY === 0 ) { delta  = deltaX * -1; }
33876        }
33877
33878        // No change actually happened, no reason to go any further
33879        if ( deltaY === 0 && deltaX === 0 ) { return; }
33880
33881        // Need to convert lines and pages to pixels if we aren't already in pixels
33882        // There are three delta modes:
33883        //   * deltaMode 0 is by pixels, nothing to do
33884        //   * deltaMode 1 is by lines
33885        //   * deltaMode 2 is by pages
33886        if ( orgEvent.deltaMode === 1 ) {
33887            var lineHeight = $.data(this, 'mousewheel-line-height');
33888            delta  *= lineHeight;
33889            deltaY *= lineHeight;
33890            deltaX *= lineHeight;
33891        } else if ( orgEvent.deltaMode === 2 ) {
33892            var pageHeight = $.data(this, 'mousewheel-page-height');
33893            delta  *= pageHeight;
33894            deltaY *= pageHeight;
33895            deltaX *= pageHeight;
33896        }
33897
33898        // Store lowest absolute delta to normalize the delta values
33899        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
33900
33901        if ( !lowestDelta || absDelta < lowestDelta ) {
33902            lowestDelta = absDelta;
33903
33904            // Adjust older deltas if necessary
33905            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
33906                lowestDelta /= 40;
33907            }
33908        }
33909
33910        // Adjust older deltas if necessary
33911        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
33912            // Divide all the things by 40!
33913            delta  /= 40;
33914            deltaX /= 40;
33915            deltaY /= 40;
33916        }
33917
33918        // Get a whole, normalized value for the deltas
33919        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
33920        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
33921        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
33922
33923        // Normalise offsetX and offsetY properties
33924        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
33925            var boundingRect = this.getBoundingClientRect();
33926            offsetX = event.clientX - boundingRect.left;
33927            offsetY = event.clientY - boundingRect.top;
33928        }
33929
33930        // Add information to the event object
33931        event.deltaX = deltaX;
33932        event.deltaY = deltaY;
33933        event.deltaFactor = lowestDelta;
33934        event.offsetX = offsetX;
33935        event.offsetY = offsetY;
33936        // Go ahead and set deltaMode to 0 since we converted to pixels
33937        // Although this is a little odd since we overwrite the deltaX/Y
33938        // properties with normalized deltas.
33939        event.deltaMode = 0;
33940
33941        // Add event and delta to the front of the arguments
33942        args.unshift(event, delta, deltaX, deltaY);
33943
33944        // Clearout lowestDelta after sometime to better
33945        // handle multiple device types that give different
33946        // a different lowestDelta
33947        // Ex: trackpad = 3 and mouse wheel = 120
33948        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
33949        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
33950
33951        return ($.event.dispatch || $.event.handle).apply(this, args);
33952    }
33953
33954    function nullLowestDelta() {
33955        lowestDelta = null;
33956    }
33957
33958    function shouldAdjustOldDeltas(orgEvent, absDelta) {
33959        // If this is an older event and the delta is divisable by 120,
33960        // then we are assuming that the browser is treating this as an
33961        // older mouse wheel event and that we should divide the deltas
33962        // by 40 to try and get a more usable deltaFactor.
33963        // Side note, this actually impacts the reported scroll distance
33964        // in older browsers and can cause scrolling to be slower than native.
33965        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
33966        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
33967    }
33968
33969}));
33970
33971S2.define('jquery.select2',[
33972  'jquery',
33973  'jquery-mousewheel',
33974
33975  './select2/core',
33976  './select2/defaults'
33976,
33977  './select2/utils'
33978], function ($, _, Select2, Defaults, Utils) {
33979  if ($.fn.select2 == null) {
33980    // All methods that should return the element
33981    var thisMethods = ['open', 'close', 'destroy'];
33982
33983    $.fn.select2 = function (options) {
33984      options = options || {};
33985
33986      if (typeof options === 'object') {
33987        this.each(function () {
33988          var instanceOptions = $.extend(true, {}, options);
33989
33990          var instance = new Select2($(this), instanceOptions);
33991        });
33992
33993        return this;
33994      } else if (typeof options === 'string') {
33995        var ret;
33996        var args = Array.prototype.slice.call(arguments, 1);
33997
33998        this.each(function () {
33999          var instance = Utils.GetData(this, 'select2');
34000
34001          if (instance == null && window.console && console.error) {
34002            console.error(
34003              'The select2(\'' + options + '\') method was called on an ' +
34004              'element that is not using Select2.'
34005            );
34006          }
34007
34008          ret = instance[options].apply(instance, args);
34009        });
34010
34011        // Check if we should be returning `this`
34012        if ($.inArray(options, thisMethods) > -1) {
34013          return this;
34014        }
34015
34016        return ret;
34017      } else {
34018        throw new Error('Invalid arguments for Select2: ' + options);
34019      }
34020    };
34021  }
34022
34023  if ($.fn.select2.defaults == null) {
34024    $.fn.select2.defaults = Defaults;
34025  }
34026
34027  return Select2;
34028});
34029
34030  // Return the AMD loader configuration so it can be used outside of this file
34031  return {
34032    define: S2.define,
34033    require: S2.require
34034  };
34035}());
34036
34037  // Autoload the jQuery bindings
34038  // We know that all of the modules exist above this, so we're safe
34039  var select2 = S2.require('jquery.select2');
34040
34041  // Hold the AMD module references on the jQuery function that was just loaded
34042  // This allows Select2 to use the internal loader outside of this file, such
34043  // as in the language files.
34044  jQuery.fn.select2.amd = S2;
34045
34046  // Return the Select2 instance for anyone who is importing it.
34047  return select2;
34048}));
34049/**
34050 * sifter.js
34051 * Copyright (c) 2013 Brian Reavis & contributors
34052 *
34053 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
34054 * file except in compliance with the License. You may obtain a copy of the License at:
34055 * http://www.apache.org/licenses/LICENSE-2.0
34056 *
34057 * Unless required by applicable law or agreed to in writing, software distributed under
34058 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
34059 * ANY KIND, either express or implied. See the License for the specific language
34060 * governing permissions and limitations under the License.
34061 *
34062 * @author Brian Reavis <[email protected]>
34063 */
34064
34065(function(root, factory) {
34066  if (typeof define === 'function' && define.amd) {
34067    define('sifter', factory);
34068  } else if (typeof exports === 'object') {
34069    module.exports = factory();
34070  } else {
34071    root.Sifter = factory();
34072  }
34073}(this, function() {
34074
34075  /**
34076   * Textually searches arrays and hashes of objects
34077   * by property (or multiple properties). Designed
34078   * specifically for autocomplete.
34079   *
34080   * @constructor
34081   * @param {array|object} items
34082   * @param {object} items
34083   */
34084  var Sifter = function(items, settings) {
34085    this.items = items;
34086    this.settings = settings || {diacritics: true};
34087  };
34088
34089  /**
34090   * Splits a search string into an array of individual
34091   * regexps to be used to match results.
34092   *
34093   * @param {string} query
34094   * @returns {array}
34095   */
34096  Sifter.prototype.tokenize = function(query) {
34097    query = trim(String(query || '').toLowerCase());
34098    if (!query || !query.length) return [];
34099
34100    var i, n, regex, letter;
34101    var tokens = [];
34102    var words = query.split(/ +/);
34103
34104    for (i = 0, n = words.length; i < n; i++) {
34105      regex = escape_regex(words[i]);
34106      if (this.settings.diacritics) {
34107        for (letter in DIACRITICS) {
34108          if (DIACRITICS.hasOwnProperty(letter)) {
34109            regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]);
34110          }
34111        }
34112      }
34113      tokens.push({
vendor: 23,539 bytes, lines 34114-34923
34114        string : words[i],
34115        regex  : new RegExp(regex, 'i')
34116      });
34117    }
34118
34119    return tokens;
34120  };
34121
34122  /**
34123   * Iterates over arrays and hashes.
34124   *
34125   * ```
34126   * this.iterator(this.items, function(item, id) {
34127   *    // invoked for each item
34128   * });
34129   * ```
34130   *
34131   * @param {array|object} object
34132   */
34133  Sifter.prototype.iterator = function(object, callback) {
34134    var iterator;
34135    if (is_array(object)) {
34136      iterator = Array.prototype.forEach || function(callback) {
34137        for (var i = 0, n = this.length; i < n; i++) {
34138          callback(this[i], i, this);
34139        }
34140      };
34141    } else {
34142      iterator = function(callback) {
34143        for (var key in this) {
34144          if (this.hasOwnProperty(key)) {
34145            callback(this[key], key, this);
34146          }
34147        }
34148      };
34149    }
34150
34151    iterator.apply(object, [callback]);
34152  };
34153
34154  /**
34155   * Returns a function to be used to score individual results.
34156   *
34157   * Good matches will have a higher score than poor matches.
34158   * If an item is not a match, 0 will be returned by the function.
34159   *
34160   * @param {object|string} search
34161   * @param {object} options (optional)
34162   * @returns {function}
34163   */
34164  Sifter.prototype.getScoreFunction = function(search, options) {
34165    var self, fields, tokens, token_count, nesting;
34166
34167    self        = this;
34168    search      = self.prepareSearch(search, options);
34169    tokens      = search.tokens;
34170    fields      = search.options.fields;
34171    token_count = tokens.length;
34172    nesting     = search.options.nesting;
34173
34174    /**
34175     * Calculates how close of a match the
34176     * given value is against a search token.
34177     *
34178     * @param {mixed} value
34179     * @param {object} token
34180     * @return {number}
34181     */
34182    var scoreValue = function(value, token) {
34183      var score, pos;
34184
34185      if (!value) return 0;
34186      value = String(value || '');
34187      pos = value.search(token.regex);
34188      if (pos === -1) return 0;
34189      score = token.string.length / value.length;
34190      if (pos === 0) score += 0.5;
34191      return score;
34192    };
34193
34194    /**
34195     * Calculates the score of an object
34196     * against the search query.
34197     *
34198     * @param {object} token
34199     * @param {object} data
34200     * @return {number}
34201     */
34202    var scoreObject = (function() {
34203      var field_count = fields.length;
34204      if (!field_count) {
34205        return function() { return 0; };
34206      }
34207      if (field_count === 1) {
34208        return function(token, data) {
34209          return scoreValue(getattr(data, fields[0], nesting), token);
34210        };
34211      }
34212      return function(token, data) {
34213        for (var i = 0, sum = 0; i < field_count; i++) {
34214          sum += scoreValue(getattr(data, fields[i], nesting), token);
34215        }
34216        return sum / field_count;
34217      };
34218    })();
34219
34220    if (!token_count) {
34221      return function() { return 0; };
34222    }
34223    if (token_count === 1) {
34224      return function(data) {
34225        return scoreObject(tokens[0], data);
34226      };
34227    }
34228
34229    if (search.options.conjunction === 'and') {
34230      return function(data) {
34231        var score;
34232        for (var i = 0, sum = 0; i < token_count; i++) {
34233          score = scoreObject(tokens[i], data);
34234          if (score <= 0) return 0;
34235          sum += score;
34236        }
34237        return sum / token_count;
34238      };
34239    } else {
34240      return function(data) {
34241        for (var i = 0, sum = 0; i < token_count; i++) {
34242          sum += scoreObject(tokens[i], data);
34243        }
34244        return sum / token_count;
34245      };
34246    }
34247  };
34248
34249  /**
34250   * Returns a function that can be used to compare two
34251   * results, for sorting purposes. If no sorting should
34252   * be performed, `null` will be returned.
34253   *
34254   * @param {string|object} search
34255   * @param {object} options
34256   * @return function(a,b)
34257   */
34258  Sifter.prototype.getSortFunction = function(search, options) {
34259    var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort;
34260
34261    self   = this;
34262    search = self.prepareSearch(search, options);
34263    sort   = (!search.query && options.sort_empty) || options.sort;
34264
34265    /**
34266     * Fetches the specified sort field value
34267     * from a search result item.
34268     *
34269     * @param  {string} name
34270     * @param  {object} result
34271     * @return {mixed}
34272     */
34273    get_field = function(name, result) {
34274      if (name === '$score') return result.score;
34275      return getattr(self.items[result.id], name, options.nesting);
34276    };
34277
34278    // parse options
34279    fields = [];
34280    if (sort) {
34281      for (i = 0, n = sort.length; i < n; i++) {
34282        if (search.query || sort[i].field !== '$score') {
34283          fields.push(sort[i]);
34284        }
34285      }
34286    }
34287
34288    // the "$score" field is implied to be the primary
34289    // sort field, unless it's manually specified
34290    if (search.query) {
34291      implicit_score = true;
34292      for (i = 0, n = fields.length; i < n; i++) {
34293        if (fields[i].field === '$score') {
34294          implicit_score = false;
34295          break;
34296        }
34297      }
34298      if (implicit_score) {
34299        fields.unshift({field: '$score', direction: 'desc'});
34300      }
34301    } else {
34302      for (i = 0, n = fields.length; i < n; i++) {
34303        if (fields[i].field === '$score') {
34304          fields.splice(i, 1);
34305          break;
34306        }
34307      }
34308    }
34309
34310    multipliers = [];
34311    for (i = 0, n = fields.length; i < n; i++) {
34312      multipliers.push(fields[i].direction === 'desc' ? -1 : 1);
34313    }
34314
34315    // build function
34316    fields_count = fields.length;
34317    if (!fields_count) {
34318      return null;
34319    } else if (fields_count === 1) {
34320      field = fields[0].field;
34321      multiplier = multipliers[0];
34322      return function(a, b) {
34323        return multiplier * cmp(
34324          get_field(field, a),
34325          get_field(field, b)
34326        );
34327      };
34328    } else {
34329      return function(a, b) {
34330        var i, result, a_value, b_value, field;
34331        for (i = 0; i < fields_count; i++) {
34332          field = fields[i].field;
34333          result = multipliers[i] * cmp(
34334            get_field(field, a),
34335            get_field(field, b)
34336          );
34337          if (result) return result;
34338        }
34339        return 0;
34340      };
34341    }
34342  };
34343
34344  /**
34345   * Parses a search query and returns an object
34346   * with tokens and fields ready to be populated
34347   * with results.
34348   *
34349   * @param {string} query
34350   * @param {object} options
34351   * @returns {object}
34352   */
34353  Sifter.prototype.prepareSearch = function(query, options) {
34354    if (typeof query === 'object') return query;
34355
34356    options = extend({}, options);
34357
34358    var option_fields     = options.fields;
34359    var option_sort       = options.sort;
34360    var option_sort_empty = options.sort_empty;
34361
34362    if (option_fields && !is_array(option_fields)) options.fields = [option_fields];
34363    if (option_sort && !is_array(option_sort)) options.sort = [option_sort];
34364    if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty];
34365
34366    return {
34367      options : options,
34368      query   : String(query || '').toLowerCase(),
34369      tokens  : this.tokenize(query),
34370      total   : 0,
34371      items   : []
34372    };
34373  };
34374
34375  /**
34376   * Searches through all items and returns a sorted array of matches.
34377   *
34378   * The `options` parameter can contain:
34379   *
34380   *   - fields {string|array}
34381   *   - sort {array}
34382   *   - score {function}
34383   *   - filter {bool}
34384   *   - limit {integer}
34385   *
34386   * Returns an object containing:
34387   *
34388   *   - options {object}
34389   *   - query {string}
34390   *   - tokens {array}
34391   *   - total {int}
34392   *   - items {array}
34393   *
34394   * @param {string} query
34395   * @param {object} options
34396   * @returns {object}
34397   */
34398  Sifter.prototype.search = function(query, options) {
34399    var self = this, value, score, search, calculateScore;
34400    var fn_sort;
34401    var fn_score;
34402
34403    search  = this.prepareSearch(query, options);
34404    options = search.options;
34405    query   = search.query;
34406
34407    // generate result scoring function
34408    fn_score = options.score || self.getScoreFunction(search);
34409
34410    // perform search and sort
34411    if (query.length) {
34412      self.iterator(self.items, function(item, id) {
34413        score = fn_score(item);
34414        if (options.filter === false || score > 0) {
34415          search.items.push({'score': score, 'id': id});
34416        }
34417      });
34418    } else {
34419      self.iterator(self.items, function(item, id) {
34420        search.items.push({'score': 1, 'id': id});
34421      });
34422    }
34423
34424    fn_sort = self.getSortFunction(search, options);
34425    if (fn_sort) search.items.sort(fn_sort);
34426
34427    // apply limits
34428    search.total = search.items.length;
34429    if (typeof options.limit === 'number') {
34430      search.items = search.items.slice(0, options.limit);
34431    }
34432
34433    return search;
34434  };
34435
34436  // utilities
34437  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34438
34439  var cmp = function(a, b) {
34440    if (typeof a === 'number' && typeof b === 'number') {
34441      return a > b ? 1 : (a < b ? -1 : 0);
34442    }
34443    a = asciifold(String(a || ''));
34444    b = asciifold(String(b || ''));
34445    if (a > b) return 1;
34446    if (b > a) return -1;
34447    return 0;
34448  };
34449
34450  var extend = function(a, b) {
34451    var i, n, k, object;
34452    for (i = 1, n = arguments.length; i < n; i++) {
34453      object = arguments[i];
34454      if (!object) continue;
34455      for (k in object) {
34456        if (object.hasOwnProperty(k)) {
34457          a[k] = object[k];
34458        }
34459      }
34460    }
34461    return a;
34462  };
34463
34464  /**
34465   * A property getter resolving dot-notation
34466   * @param  {Object}  obj     The root object to fetch property on
34467   * @param  {String}  name    The optionally dotted property name to fetch
34468   * @param  {Boolean} nesting Handle nesting or not
34469   * @return {Object}          The resolved property value
34470   */
34471  var getattr = function(obj, name, nesting) {
34472      if (!obj || !name) return;
34473      if (!nesting) return obj[name];
34474      var names = name.split(".");
34475      while(names.length && (obj = obj[names.shift()]));
34476      return obj;
34477  };
34478
34479  var trim = function(str) {
34480    return (str + '').replace(/^\s+|\s+$|/g, '');
34481  };
34482
34483  var escape_regex = function(str) {
34484    return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
34485  };
34486
34487  var is_array = Array.isArray || (typeof $ !== 'undefined' && $.isArray) || function(object) {
34488    return Object.prototype.toString.call(object) === '[object Array]';
34489  };
34490
34491  var DIACRITICS = {
34492    'a': '[aḀḁĂăÂâǍǎȺⱥȦȧẠạÄäÀàÁáĀāÃãÅåąĄÃąĄ]',
34493    'b': '[b␢βΒB฿𐌁ᛒ]',
34494    'c': '[cĆćĈĉČčĊċC̄c̄ÇçḈḉȻȼƇƈɕᴄCc]',
34495    'd': '[dĎďḊḋḐḑḌḍḒḓḎḏĐđD̦d̦ƉɖƊɗƋƌᵭᶁᶑȡᴅDdð]',
34496    'e': '[eÉéÈèÊêḘḙĚěĔĕẼẽḚḛẺẻĖėËëĒēȨȩĘęᶒɆɇȄȅẾếỀềỄễỂểḜḝḖḗḔḕȆȇẸẹỆệⱸᴇEeɘǝƏƐε]',
34497    'f': '[fƑƒḞḟ]',
34498    'g': '[gɢ₲ǤǥĜĝĞğĢģƓɠĠġ]',
34499    'h': '[hĤĥĦħḨḩẖẖḤḥḢḣɦʰǶƕ]',
34500    'i': '[iÍíÌìĬĭÎîǏǐÏïḮḯĨĩĮįĪīỈỉȈȉȊȋỊịḬḭƗɨɨ̆ᵻᶖİiIıɪIi]',
34501    'j': '[jȷĴĵɈɉʝɟʲ]',
34502    'k': '[kƘƙꝀꝁḰḱǨǩḲḳḴḵκϰ₭]',
34503    'l': '[lŁłĽľĻļĹĺḶḷḸḹḼḽḺḻĿŀȽƚⱠⱡⱢɫɬᶅɭȴʟLl]',
34504    'n': '[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲȠƞᵰᶇɳȵɴNnŊŋ]',
34505    'o': '[oØøÖöÓóÒòÔôǑǒŐőŎŏȮȯỌọƟɵƠơỎỏŌōÕõǪǫȌȍՕօ]',
34506    'p': '[pṔṕṖṗⱣᵽƤƥᵱ]',
34507    'q': '[qꝖꝗʠɊɋꝘꝙq̃]',
34508    'r': '[rŔŕɌɍŘřŖŗṘṙȐȑȒȓṚṛⱤɽ]',
34509    's': '[sŚśṠṡṢṣꞨꞩŜŝŠšŞşȘșS̈s̈]',
34510    't': '[tŤťṪṫŢţṬṭƮʈȚțṰṱṮṯƬƭ]',
34511    'u': '[uŬŭɄʉỤụÜüÚúÙùÛûǓǔŰűŬŭƯưỦủŪūŨũŲųȔȕ∪]',
34512    'v': '[vṼṽṾṿƲʋꝞꝟⱱʋ]',
34513    'w': '[wẂẃẀẁŴŵẄẅẆẇẈẉ]',
34514    'x': '[xẌẍẊẋχ]',
34515    'y': '[yÝýỲỳŶŷŸÿỸỹẎẏỴỵɎɏƳƴ]',
34516    'z': '[zŹźẐẑŽžŻżẒẓẔẕƵƶ]'
34517  };
34518
34519  var asciifold = (function() {
34520    var i, n, k, chunk;
34521    var foreignletters = '';
34522    var lookup = {};
34523    for (k in DIACRITICS) {
34524      if (DIACRITICS.hasOwnProperty(k)) {
34525        chunk = DIACRITICS[k].substring(2, DIACRITICS[k].length - 1);
34526        foreignletters += chunk;
34527        for (i = 0, n = chunk.length; i < n; i++) {
34528          lookup[chunk.charAt(i)] = k;
34529        }
34530      }
34531    }
34532    var regexp = new RegExp('[' +  foreignletters + ']', 'g');
34533    return function(str) {
34534      return str.replace(regexp, function(foreignletter) {
34535        return lookup[foreignletter];
34536      }).toLowerCase();
34537    };
34538  })();
34539
34540
34541  // export
34542  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34543
34544  return Sifter;
34545}));
34546
34547
34548
34549/**
34550 * microplugin.js
34551 * Copyright (c) 2013 Brian Reavis & contributors
34552 *
34553 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
34554 * file except in compliance with the License. You may obtain a copy of the License at:
34555 * http://www.apache.org/licenses/LICENSE-2.0
34556 *
34557 * Unless required by applicable law or agreed to in writing, software distributed under
34558 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
34559 * ANY KIND, either express or implied. See the License for the specific language
34560 * governing permissions and limitations under the License.
34561 *
34562 * @author Brian Reavis <[email protected]>
34563 */
34564
34565(function(root, factory) {
34566  if (typeof define === 'function' && define.amd) {
34567    define('microplugin', factory);
34568  } else if (typeof exports === 'object') {
34569    module.exports = factory();
34570  } else {
34571    root.MicroPlugin = factory();
34572  }
34573}(this, function() {
34574  var MicroPlugin = {};
34575
34576  MicroPlugin.mixin = function(Interface) {
34577    Interface.plugins = {};
34578
34579    /**
34580     * Initializes the listed plugins (with options).
34581     * Acceptable formats:
34582     *
34583     * List (without options):
34584     *   ['a', 'b', 'c']
34585     *
34586     * List (with options):
34587     *   [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
34588     *
34589     * Hash (with options):
34590     *   {'a': { ... }, 'b': { ... }, 'c': { ... }}
34591     *
34592     * @param {mixed} plugins
34593     */
34594    Interface.prototype.initializePlugins = function(plugins) {
34595      var i, n, key;
34596      var self  = this;
34597      var queue = [];
34598
34599      self.plugins = {
34600        names     : [],
34601        settings  : {},
34602        requested : {},
34603        loaded    : {}
34604      };
34605
34606      if (utils.isArray(plugins)) {
34607        for (i = 0, n = plugins.length; i < n; i++) {
34608          if (typeof plugins[i] === 'string') {
34609            queue.push(plugins[i]);
34610          } else {
34611            self.plugins.settings[plugins[i].name] = plugins[i].options;
34612            queue.push(plugins[i].name);
34613          }
34614        }
34615      } else if (plugins) {
34616        for (key in plugins) {
34617          if (plugins.hasOwnProperty(key)) {
34618            self.plugins.settings[key] = plugins[key];
34619            queue.push(key);
34620          }
34621        }
34622      }
34623
34624      while (queue.length) {
34625        self.require(queue.shift());
34626      }
34627    };
34628
34629    Interface.prototype.loadPlugin = function(name) {
34630      var self    = this;
34631      var plugins = self.plugins;
34632      var plugin  = Interface.plugins[name];
34633
34634      if (!Interface.plugins.hasOwnProperty(name)) {
34635        throw new Error('Unable to find "' +  name + '" plugin');
34636      }
34637
34638      plugins.requested[name] = true;
34639      plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
34640      plugins.names.push(name);
34641    };
34642
34643    /**
34644     * Initializes a plugin.
34645     *
34646     * @param {string} name
34647     */
34648    Interface.prototype.require = function(name) {
34649      var self = this;
34650      var plugins = self.plugins;
34651
34652      if (!self.plugins.loaded.hasOwnProperty(name)) {
34653        if (plugins.requested[name]) {
34654          throw new Error('Plugin has circular dependency ("' + name + '")');
34655        }
34656        self.loadPlugin(name);
34657      }
34658
34659      return plugins.loaded[name];
34660    };
34661
34662    /**
34663     * Registers a plugin.
34664     *
34665     * @param {string} name
34666     * @param {function} fn
34667     */
34668    Interface.define = function(name, fn) {
34669      Interface.plugins[name] = {
34670        'name' : name,
34671        'fn'   : fn
34672      };
34673    };
34674  };
34675
34676  var utils = {
34677    isArray: Array.isArray || function(vArg) {
34678      return Object.prototype.toString.call(vArg) === '[object Array]';
34679    }
34680  };
34681
34682  return MicroPlugin;
34683}));
34684
34685/**
34686 * selectize.js (v0.12.6)
34687 * Copyright (c) 2013–2015 Brian Reavis & contributors
34688 *
34689 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
34690 * file except in compliance with the License. You may obtain a copy of the License at:
34691 * http://www.apache.org/licenses/LICENSE-2.0
34692 *
34693 * Unless required by applicable law or agreed to in writing, software distributed under
34694 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
34695 * ANY KIND, either express or implied. See the License for the specific language
34696 * governing permissions and limitations under the License.
34697 *
34698 * @author Brian Reavis <[email protected]>
34699 */
34700
34701/*jshint curly:false */
34702/*jshint browser:true */
34703
34704(function(root, factory) {
34705  if (typeof define === 'function' && define.amd) {
34706    define('selectize', ['jquery','sifter','microplugin'], factory);
34707  } else if (typeof exports === 'object') {
34708    module.exports = factory(require('jquery'), require('sifter'), require('microplugin'));
34709  } else {
34710    root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin);
34711  }
34712}(this, function($, Sifter, MicroPlugin) {
34713  'use strict';
34714
34715  var highlight = function($element, pattern) {
34716    if (typeof pattern === 'string' && !pattern.length) return;
34717    var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern;
34718
34719    var highlight = function(node) {
34720      var skip = 0;
34721      // Wrap matching part of text node with highlighting <span>, e.g.
34722      // Soccer  ->  <span class="highlight">Soc</span>cer  for regex = /soc/i
34723      if (node.nodeType === 3) {
34724        var pos = node.data.search(regex);
34725        if (pos >= 0 && node.data.length > 0) {
34726          var match = node.data.match(regex);
34727          var spannode = document.createElement('span');
34728          spannode.className = 'highlight';
34729          var middlebit = node.splitText(pos);
34730          var endbit = middlebit.splitText(match[0].length);
34731          var middleclone = middlebit.cloneNode(true);
34732          spannode.appendChild(middleclone);
34733          middlebit.parentNode.replaceChild(spannode, middlebit);
34734          skip = 1;
34735        }
34736      }
34737      // Recurse element node, looking for child text nodes to highlight, unless element
34738      // is childless, <script>, <style>, or already highlighted: <span class="hightlight">
34739      else if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && ( node.className !== 'highlight' || node.tagName !== 'SPAN' )) {
34740        for (var i = 0; i < node.childNodes.length; ++i) {
34741          i += highlight(node.childNodes[i]);
34742        }
34743      }
34744      return skip;
34745    };
34746
34747    return $element.each(function() {
34748      highlight(this);
34749    });
34750  };
34751
34752  /**
34753   * removeHighlight fn copied from highlight v5 and
34754   * edited to remove with() and pass js strict mode
34755   */
34756  $.fn.removeHighlight = function() {
34757    return this.find("span.highlight").each(function() {
34758      this.parentNode.firstChild.nodeName;
34759      var parent = this.parentNode;
34760      parent.replaceChild(this.firstChild, this);
34761      parent.normalize();
34762    }).end();
34763  };
34764
34765
34766  var MicroEvent = function() {};
34767  MicroEvent.prototype = {
34768    on: function(event, fct){
34769      this._events = this._events || {};
34770      this._events[event] = this._events[event] || [];
34771      this._events[event].push(fct);
34772    },
34773    off: function(event, fct){
34774      var n = arguments.length;
34775      if (n === 0) return delete this._events;
34776      if (n === 1) return delete this._events[event];
34777
34778      this._events = this._events || {};
34779      if (event in this._events === false) return;
34780      this._events[event].splice(this._events[event].indexOf(fct), 1);
34781    },
34782    trigger: function(event /* , args... */){
34783      this._events = this._events || {};
34784      if (event in this._events === false) return;
34785      for (var i = 0; i < this._events[event].length; i++){
34786        this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
34787      }
34788    }
34789  };
34790
34791  /**
34792   * Mixin will delegate all MicroEvent.js function in the destination object.
34793   *
34794   * - MicroEvent.mixin(Foobar) will make Foobar able to use MicroEvent
34795   *
34796   * @param {object} the object which will support MicroEvent
34797   */
34798  MicroEvent.mixin = function(destObject){
34799    var props = ['on', 'off', 'trigger'];
34800    for (var i = 0; i < props.length; i++){
34801      destObject.prototype[props[i]] = MicroEvent.prototype[props[i]];
34802    }
34803  };
34804
34805  var IS_MAC        = /Mac/.test(navigator.userAgent);
34806
34807  var KEY_A         = 65;
34808  var KEY_COMMA     = 188;
34809  var KEY_RETURN    = 13;
34810  var KEY_ESC       = 27;
34811  var KEY_LEFT      = 37;
34812  var KEY_UP        = 38;
34813  var KEY_P         = 80;
34814  var KEY_RIGHT     = 39;
34815  var KEY_DOWN      = 40;
34816  var KEY_N         = 78;
34817  var KEY_BACKSPACE = 8;
34818  var KEY_DELETE    = 46;
34819  var KEY_SHIFT     = 16;
34820  var KEY_CMD       = IS_MAC ? 91 : 17;
34821  var KEY_CTRL      = IS_MAC ? 18 : 17;
34822  var KEY_TAB       = 9;
34823
34824  var TAG_SELECT    = 1;
34825  var TAG_INPUT     = 2;
34826
34827  // for now, android support in general is too spotty to support validity
34828  var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('input').validity;
34829
34830
34831  var isset = function(object) {
34832    return typeof object !== 'undefined';
34833  };
34834
34835  /**
34836   * Converts a scalar to its best string representation
34837   * for hash keys and HTML attribute values.
34838   *
34839   * Transformations:
34840   *   'str'     -> 'str'
34841   *   null      -> ''
34842   *   undefined -> ''
34843   *   true      -> '1'
34844   *   false     -> '0'
34845   *   0         -> '0'
34846   *   1         -> '1'
34847   *
34848   * @param {string} value
34849   * @returns {string|null}
34850   */
34851  var hash_key = function(value) {
34852    if (typeof value === 'undefined' || value === null) return null;
34853    if (typeof value === 'boolean') return value ? '1' : '0';
34854    return value + '';
34855  };
34856
34857  /**
34858   * Escapes a string for use within HTML.
34859   *
34860   * @param {string} str
34861   * @returns {string}
34862   */
34863  var escape_html = function(str) {
34864    return (str + '')
34865      .replace(/&/g, '&amp;')
34866      .replace(/</g, '&lt;')
34867      .replace(/>/g, '&gt;')
34868      .replace(/"/g, '&quot;');
34869  };
34870
34871  /**
34872   * Escapes "$" characters in replacement strings.
34873   *
34874   * @param {string} str
34875   * @returns {string}
34876   */
34877  var escape_replace = function(str) {
34878    return (str + '').replace(/\$/g, '$$$$');
34879  };
34880
34881  var hook = {};
34882
34883  /**
34884   * Wraps `method` on `self` so that `fn`
34885   * is invoked before the original method.
34886   *
34887   * @param {object} self
34888   * @param {string} method
34889   * @param {function} fn
34890   */
34891  hook.before = function(self, method, fn) {
34892    var original = self[method];
34893    self[method] = function() {
34894      fn.apply(self, arguments);
34895      return original.apply(self, arguments);
34896    };
34897  };
34898
34899  /**
34900   * Wraps `method` on `self` so that `fn`
34901   * is invoked after the original method.
34902   *
34903   * @param {object} self
34904   * @param {string} method
34905   * @param {function} fn
34906   */
34907  hook.after = function(self, method, fn) {
34908    var original = self[method];
34909    self[method] = function() {
34910      var result = original.apply(self, arguments);
34911      fn.apply(self, arguments);
34912      return result;
34913    };
34914  };
34915
34916  /**
34917   * Wraps `fn` so that it can only be invoked once.
34918   *
34919   * @param {function} fn
34920   * @returns {function}
34921   */
34922  var once = function(fn) {
34923    var called = false;
vendor: 92,733 bytes, lines 34924-37996
34924    return function() {
34925      if (called) return;
34926      called = true;
34927      fn.apply(this, arguments);
34928    };
34929  };
34930
34931  /**
34932   * Wraps `fn` so that it can only be called once
34933   * every `delay` milliseconds (invoked on the falling edge).
34934   *
34935   * @param {function} fn
34936   * @param {int} delay
34937   * @returns {function}
34938   */
34939  var debounce = function(fn, delay) {
34940    var timeout;
34941    return function() {
34942      var self = this;
34943      var args = arguments;
34944      window.clearTimeout(timeout);
34945      timeout = window.setTimeout(function() {
34946        fn.apply(self, args);
34947      }, delay);
34948    };
34949  };
34950
34951  /**
34952   * Debounce all fired events types listed in `types`
34953   * while executing the provided `fn`.
34954   *
34955   * @param {object} self
34956   * @param {array} types
34957   * @param {function} fn
34958   */
34959  var debounce_events = function(self, types, fn) {
34960    var type;
34961    var trigger = self.trigger;
34962    var event_args = {};
34963
34964    // override trigger method
34965    self.trigger = function() {
34966      var type = arguments[0];
34967      if (types.indexOf(type) !== -1) {
34968        event_args[type] = arguments;
34969      } else {
34970        return trigger.apply(self, arguments);
34971      }
34972    };
34973
34974    // invoke provided function
34975    fn.apply(self, []);
34976    self.trigger = trigger;
34977
34978    // trigger queued events
34979    for (type in event_args) {
34980      if (event_args.hasOwnProperty(type)) {
34981        trigger.apply(self, event_args[type]);
34982      }
34983    }
34984  };
34985
34986  /**
34987   * A workaround for http://bugs.jquery.com/ticket/6696
34988   *
34989   * @param {object} $parent - Parent element to listen on.
34990   * @param {string} event - Event name.
34991   * @param {string} selector - Descendant selector to filter by.
34992   * @param {function} fn - Event handler.
34993   */
34994  var watchChildEvent = function($parent, event, selector, fn) {
34995    $parent.on(event, selector, function(e) {
34996      var child = e.target;
34997      while (child && child.parentNode !== $parent[0]) {
34998        child = child.parentNode;
34999      }
35000      e.currentTarget = child;
35001      return fn.apply(this, [e]);
35002    });
35003  };
35004
35005  /**
35006   * Determines the current selection within a text input control.
35007   * Returns an object containing:
35008   *   - start
35009   *   - length
35010   *
35011   * @param {object} input
35012   * @returns {object}
35013   */
35014  var getSelection = function(input) {
35015    var result = {};
35016    if ('selectionStart' in input) {
35017      result.start = input.selectionStart;
35018      result.length = input.selectionEnd - result.start;
35019    } else if (document.selection) {
35020      input.focus();
35021      var sel = document.selection.createRange();
35022      var selLen = document.selection.createRange().text.length;
35023      sel.moveStart('character', -input.value.length);
35024      result.start = sel.text.length - selLen;
35025      result.length = selLen;
35026    }
35027    return result;
35028  };
35029
35030  /**
35031   * Copies CSS properties from one element to another.
35032   *
35033   * @param {object} $from
35034   * @param {object} $to
35035   * @param {array} properties
35036   */
35037  var transferStyles = function($from, $to, properties) {
35038    var i, n, styles = {};
35039    if (properties) {
35040      for (i = 0, n = properties.length; i < n; i++) {
35041        styles[properties[i]] = $from.css(properties[i]);
35042      }
35043    } else {
35044      styles = $from.css();
35045    }
35046    $to.css(styles);
35047  };
35048
35049  /**
35050   * Measures the width of a string within a
35051   * parent element (in pixels).
35052   *
35053   * @param {string} str
35054   * @param {object} $parent
35055   * @returns {int}
35056   */
35057  var measureString = function(str, $parent) {
35058    if (!str) {
35059      return 0;
35060    }
35061
35062    if (!Selectize.$testInput) {
35063      Selectize.$testInput = $('<span />').css({
35064        position: 'absolute',
35065        top: -99999,
35066        left: -99999,
35067        width: 'auto',
35068        padding: 0,
35069        whiteSpace: 'pre'
35070      }).appendTo('body');
35071    }
35072
35073    Selectize.$testInput.text(str);
35074
35075    transferStyles($parent, Selectize.$testInput, [
35076      'letterSpacing',
35077      'fontSize',
35078      'fontFamily',
35079      'fontWeight',
35080      'textTransform'
35081    ]);
35082
35083    return Selectize.$testInput.width();
35084  };
35085
35086  /**
35087   * Sets up an input to grow horizontally as the user
35088   * types. If the value is changed manually, you can
35089   * trigger the "update" handler to resize:
35090   *
35091   * $input.trigger('update');
35092   *
35093   * @param {object} $input
35094   */
35095  var autoGrow = function($input) {
35096    var currentWidth = null;
35097
35098    var update = function(e, options) {
35099      var value, keyCode, printable, placeholder, width;
35100      var shift, character, selection;
35101      e = e || window.event || {};
35102      options = options || {};
35103
35104      if (e.metaKey || e.altKey) return;
35105      if (!options.force && $input.data('grow') === false) return;
35106
35107      value = $input.val();
35108      if (e.type && e.type.toLowerCase() === 'keydown') {
35109        keyCode = e.keyCode;
35110        printable = (
35111          (keyCode >= 48 && keyCode <= 57)  || // 0-9
35112          (keyCode >= 65 && keyCode <= 90)   || // a-z
35113          (keyCode >= 96 && keyCode <= 111)  || // numpad 0-9, numeric operators
35114          (keyCode >= 186 && keyCode <= 222) || // semicolon, equal, comma, dash, etc.
35115          keyCode === 32 // space
35116        );
35117
35118        if (keyCode === KEY_DELETE || keyCode === KEY_BACKSPACE) {
35119          selection = getSelection($input[0]);
35120          if (selection.length) {
35121            value = value.substring(0, selection.start) + value.substring(selection.start + selection.length);
35122          } else if (keyCode === KEY_BACKSPACE && selection.start) {
35123            value = value.substring(0, selection.start - 1) + value.substring(selection.start + 1);
35124          } else if (keyCode === KEY_DELETE && typeof selection.start !== 'undefined') {
35125            value = value.substring(0, selection.start) + value.substring(selection.start + 1);
35126          }
35127        } else if (printable) {
35128          shift = e.shiftKey;
35129          character = String.fromCharCode(e.keyCode);
35130          if (shift) character = character.toUpperCase();
35131          else character = character.toLowerCase();
35132          value += character;
35133        }
35134      }
35135
35136      placeholder = $input.attr('placeholder');
35137      if (!value && placeholder) {
35138        value = placeholder;
35139      }
35140
35141      width = measureString(value, $input) + 4;
35142      if (width !== currentWidth) {
35143        currentWidth = width;
35144        $input.width(width);
35145        $input.triggerHandler('resize');
35146      }
35147    };
35148
35149    $input.on('keydown keyup update blur', update);
35150    update();
35151  };
35152
35153  var domToString = function(d) {
35154    var tmp = document.createElement('div');
35155
35156    tmp.appendChild(d.cloneNode(true));
35157
35158    return tmp.innerHTML;
35159  };
35160
35161  var logError = function(message, options){
35162    if(!options) options = {};
35163    var component = "Selectize";
35164
35165    console.error(component + ": " + message)
35166
35167    if(options.explanation){
35168      // console.group is undefined in <IE11
35169      if(console.group) console.group();
35170      console.error(options.explanation);
35171      if(console.group) console.groupEnd();
35172    }
35173  }
35174
35175
35176  var Selectize = function($input, settings) {
35177    var key, i, n, dir, input, self = this;
35178    input = $input[0];
35179    input.selectize = self;
35180
35181    // detect rtl environment
35182    var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);
35183    dir = computedStyle ? computedStyle.getPropertyValue('direction') : input.currentStyle && input.currentStyle.direction;
35184    dir = dir || $input.parents('[dir]:first').attr('dir') || '';
35185
35186    // setup default state
35187    $.extend(self, {
35188      order            : 0,
35189      settings         : settings,
35190      $input           : $input,
35191      tabIndex         : $input.attr('tabindex') || '',
35192      tagType          : input.tagName.toLowerCase() === 'select' ? TAG_SELECT : TAG_INPUT,
35193      rtl              : /rtl/i.test(dir),
35194
35195      eventNS          : '.selectize' + (++Selectize.count),
35196      highlightedValue : null,
35197      isBlurring       : false,
35198      isOpen           : false,
35199      isDisabled       : false,
35200      isRequired       : $input.is('[required]'),
35201      isInvalid        : false,
35202      isLocked         : false,
35203      isFocused        : false,
35204      isInputHidden    : false,
35205      isSetup          : false,
35206      isShiftDown      : false,
35207      isCmdDown        : false,
35208      isCtrlDown       : false,
35209      ignoreFocus      : false,
35210      ignoreBlur       : false,
35211      ignoreHover      : false,
35212      hasOptions       : false,
35213      currentResults   : null,
35214      lastValue        : '',
35215      caretPos         : 0,
35216      loading          : 0,
35217      loadedSearches   : {},
35218
35219      $activeOption    : null,
35220      $activeItems     : [],
35221
35222      optgroups        : {},
35223      options          : {},
35224      userOptions      : {},
35225      items            : [],
35226      renderCache      : {},
35227      onSearchChange   : settings.loadThrottle === null ? self.onSearchChange : debounce(self.onSearchChange, settings.loadThrottle)
35228    });
35229
35230    // search system
35231    self.sifter = new Sifter(this.options, {diacritics: settings.diacritics});
35232
35233    // build options table
35234    if (self.settings.options) {
35235      for (i = 0, n = self.settings.options.length; i < n; i++) {
35236        self.registerOption(self.settings.options[i]);
35237      }
35238      delete self.settings.options;
35239    }
35240
35241    // build optgroup table
35242    if (self.settings.optgroups) {
35243      for (i = 0, n = self.settings.optgroups.length; i < n; i++) {
35244        self.registerOptionGroup(self.settings.optgroups[i]);
35245      }
35246      delete self.settings.optgroups;
35247    }
35248
35249    // option-dependent defaults
35250    self.settings.mode = self.settings.mode || (self.settings.maxItems === 1 ? 'single' : 'multi');
35251    if (typeof self.settings.hideSelected !== 'boolean') {
35252      self.settings.hideSelected = self.settings.mode === 'multi';
35253    }
35254
35255    self.initializePlugins(self.settings.plugins);
35256    self.setupCallbacks();
35257    self.setupTemplates();
35258    self.setup();
35259  };
35260
35261  // mixins
35262  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35263
35264  MicroEvent.mixin(Selectize);
35265
35266  if(typeof MicroPlugin !== "undefined"){
35267    MicroPlugin.mixin(Selectize);
35268  }else{
35269    logError("Dependency MicroPlugin is missing",
35270      {explanation:
35271        "Make sure you either: (1) are using the \"standalone\" "+
35272        "version of Selectize, or (2) require MicroPlugin before you "+
35273        "load Selectize."}
35274    );
35275  }
35276
35277
35278  // methods
35279  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35280
35281  $.extend(Selectize.prototype, {
35282
35283    /**
35284     * Creates all elements and sets up event bindings.
35285     */
35286    setup: function() {
35287      var self      = this;
35288      var settings  = self.settings;
35289      var eventNS   = self.eventNS;
35290      var $window   = $(window);
35291      var $document = $(document);
35292      var $input    = self.$input;
35293
35294      var $wrapper;
35295      var $control;
35296      var $control_input;
35297      var $dropdown;
35298      var $dropdown_content;
35299      var $dropdown_parent;
35300      var inputMode;
35301      var timeout_blur;
35302      var timeout_focus;
35303      var classes;
35304      var classes_plugins;
35305      var inputId;
35306
35307      inputMode         = self.settings.mode;
35308      classes           = $input.attr('class') || '';
35309
35310      $wrapper          = $('<div>').addClass(settings.wrapperClass).addClass(classes).addClass(inputMode);
35311      $control          = $('<div>').addClass(settings.inputClass).addClass('items').appendTo($wrapper);
35312      $control_input    = $('<input type="text" autocomplete="off" />').appendTo($control).attr('tabindex', $input.is(':disabled') ? '-1' : self.tabIndex);
35313      $dropdown_parent  = $(settings.dropdownParent || $wrapper);
35314      $dropdown         = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent);
35315      $dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);
35316
35317      if(inputId = $input.attr('id')) {
35318        $control_input.attr('id', inputId + '-selectized');
35319        $("label[for='"+inputId+"']").attr('for', inputId + '-selectized');
35320      }
35321
35322      if(self.settings.copyClassesToDropdown) {
35323        $dropdown.addClass(classes);
35324      }
35325
35326      $wrapper.css({
35327        width: $input[0].style.width
35328      });
35329
35330      if (self.plugins.names.length) {
35331        classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');
35332        $wrapper.addClass(classes_plugins);
35333        $dropdown.addClass(classes_plugins);
35334      }
35335
35336      if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) {
35337        $input.attr('multiple', 'multiple');
35338      }
35339
35340      if (self.settings.placeholder) {
35341        $control_input.attr('placeholder', settings.placeholder);
35342      }
35343
35344      // if splitOn was not passed in, construct it from the delimiter to allow pasting universally
35345      if (!self.settings.splitOn && self.settings.delimiter) {
35346        var delimiterEscaped = self.settings.delimiter.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
35347        self.settings.splitOn = new RegExp('\\s*' + delimiterEscaped + '+\\s*');
35348      }
35349
35350      if ($input.attr('autocorrect')) {
35351        $control_input.attr('autocorrect', $input.attr('autocorrect'));
35352      }
35353
35354      if ($input.attr('autocapitalize')) {
35355        $control_input.attr('autocapitalize', $input.attr('autocapitalize'));
35356      }
35357      $control_input[0].type = $input[0].type;
35358
35359      self.$wrapper          = $wrapper;
35360      self.$control          = $control;
35361      self.$control_input    = $control_input;
35362      self.$dropdown         = $dropdown;
35363      self.$dropdown_content = $dropdown_content;
35364
35365      $dropdown.on('mouseenter mousedown click', '[data-disabled]>[data-selectable]', function(e) { e.stopImmediatePropagation(); });
35366      $dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); });
35367      $dropdown.on('mousedown click', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); });
35368      watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); });
35369      autoGrow($control_input);
35370
35371      $control.on({
35372        mousedown : function() { return self.onMouseDown.apply(self, arguments); },
35373        click     : function() { return self.onClick.apply(self, arguments); }
35374      });
35375
35376      $control_input.on({
35377        mousedown : function(e) { e.stopPropagation(); },
35378        keydown   : function() { return self.onKeyDown.apply(self, arguments); },
35379        keyup     : function() { return self.onKeyUp.apply(self, arguments); },
35380        keypress  : function() { return self.onKeyPress.apply(self, arguments); },
35381        resize    : function() { self.positionDropdown.apply(self, []); },
35382        blur      : function() { return self.onBlur.apply(self, arguments); },
35383        focus     : function() { self.ignoreBlur = false; return self.onFocus.apply(self, arguments); },
35384        paste     : function() { return self.onPaste.apply(self, arguments); }
35385      });
35386
35387      $document.on('keydown' + eventNS, function(e) {
35388        self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey'];
35389        self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey'];
35390        self.isShiftDown = e.shiftKey;
35391      });
35392
35393      $document.on('keyup' + eventNS, function(e) {
35394        if (e.keyCode === KEY_CTRL) self.isCtrlDown = false;
35395        if (e.keyCode === KEY_SHIFT) self.isShiftDown = false;
35396        if (e.keyCode === KEY_CMD) self.isCmdDown = false;
35397      });
35398
35399      $document.on('mousedown' + eventNS, function(e) {
35400        if (self.isFocused) {
35401          // prevent events on the dropdown scrollbar from causing the control to blur
35402          if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) {
35403            return false;
35404          }
35405          // blur on click outside
35406          if (!self.$control.has(e.target).length && e.target !== self.$control[0]) {
35407            self.blur(e.target);
35408          }
35409        }
35410      });
35411
35412      $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function() {
35413        if (self.isOpen) {
35414          self.positionDropdown.apply(self, arguments);
35415        }
35416      });
35417      $window.on('mousemove' + eventNS, function() {
35418        self.ignoreHover = false;
35419      });
35420
35421      // store original children and tab index so that they can be
35422      // restored when the destroy() method is called.
35423      this.revertSettings = {
35424        $children : $input.children().detach(),
35425        tabindex  : $input.attr('tabindex')
35426      };
35427
35428      $input.attr('tabindex', -1).hide().after(self.$wrapper);
35429
35430      if ($.isArray(settings.items)) {
35431        self.setValue(settings.items);
35432        delete settings.items;
35433      }
35434
35435      // feature detect for the validation API
35436      if (SUPPORTS_VALIDITY_API) {
35437        $input.on('invalid' + eventNS, function(e) {
35438          e.preventDefault();
35439          self.isInvalid = true;
35440          self.refreshState();
35441        });
35442      }
35443
35444      self.updateOriginalInput();
35445      self.refreshItems();
35446      self.refreshState();
35447      self.updatePlaceholder();
35448      self.isSetup = true;
35449
35450      if ($input.is(':disabled')) {
35451        self.disable();
35452      }
35453
35454      self.on('change', this.onChange);
35455
35456      $input.data('selectize', self);
35457      $input.addClass('selectized');
35458      self.trigger('initialize');
35459
35460      // preload options
35461      if (settings.preload === true) {
35462        self.onSearchChange('');
35463      }
35464
35465    },
35466
35467    /**
35468     * Sets up default rendering functions.
35469     */
35470    setupTemplates: function() {
35471      var self = this;
35472      var field_label = self.settings.labelField;
35473      var field_optgroup = self.settings.optgroupLabelField;
35474
35475      var templates = {
35476        'optgroup': function(data) {
35477          return '<div class="optgroup">' + data.html + '</div>';
35478        },
35479        'optgroup_header': function(data, escape) {
35480          return '<div class="optgroup-header">' + escape(data[field_optgroup]) + '</div>';
35481        },
35482        'option': function(data, escape) {
35483          return '<div class="option">' + escape(data[field_label]) + '</div>';
35484        },
35485        'item': function(data, escape) {
35486          return '<div class="item">' + escape(data[field_label]) + '</div>';
35487        },
35488        'option_create': function(data, escape) {
35489          return '<div class="create">Add <strong>' + escape(data.input) + '</strong>&hellip;</div>';
35490        }
35491      };
35492
35493      self.settings.render = $.extend({}, templates, self.settings.render);
35494    },
35495
35496    /**
35497     * Maps fired events to callbacks provided
35498     * in the settings used when creating the control.
35499     */
35500    setupCallbacks: function() {
35501      var key, fn, callbacks = {
35502        'initialize'      : 'onInitialize',
35503        'change'          : 'onChange',
35504        'item_add'        : 'onItemAdd',
35505        'item_remove'     : 'onItemRemove',
35506        'clear'           : 'onClear',
35507        'option_add'      : 'onOptionAdd',
35508        'option_remove'   : 'onOptionRemove',
35509        'option_clear'    : 'onOptionClear',
35510        'optgroup_add'    : 'onOptionGroupAdd',
35511        'optgroup_remove' : 'onOptionGroupRemove',
35512        'optgroup_clear'  : 'onOptionGroupClear',
35513        'dropdown_open'   : 'onDropdownOpen',
35514        'dropdown_close'  : 'onDropdownClose',
35515        'type'            : 'onType',
35516        'load'            : 'onLoad',
35517        'focus'           : 'onFocus',
35518        'blur'            : 'onBlur'
35519      };
35520
35521      for (key in callbacks) {
35522        if (callbacks.hasOwnProperty(key)) {
35523          fn = this.settings[callbacks[key]];
35524          if (fn) this.on(key, fn);
35525        }
35526      }
35527    },
35528
35529    /**
35530     * Triggered when the main control element
35531     * has a click event.
35532     *
35533     * @param {object} e
35534     * @return {boolean}
35535     */
35536    onClick: function(e) {
35537      var self = this;
35538
35539      // necessary for mobile webkit devices (manual focus triggering
35540      // is ignored unless invoked within a click event)
35541      // also necessary to reopen a dropdown that has been closed by
35542      // closeAfterSelect
35543      if (!self.isFocused || !self.isOpen) {
35544        self.focus();
35545        e.preventDefault();
35546      }
35547    },
35548
35549    /**
35550     * Triggered when the main control element
35551     * has a mouse down event.
35552     *
35553     * @param {object} e
35554     * @return {boolean}
35555     */
35556    onMouseDown: function(e) {
35557      var self = this;
35558      var defaultPrevented = e.isDefaultPrevented();
35559      var $target = $(e.target);
35560
35561      if (self.isFocused) {
35562        // retain focus by preventing native handling. if the
35563        // event target is the input it should not be modified.
35564        // otherwise, text selection within the input won't work.
35565        if (e.target !== self.$control_input[0]) {
35566          if (self.settings.mode === 'single') {
35567            // toggle dropdown
35568            self.isOpen ? self.close() : self.open();
35569          } else if (!defaultPrevented) {
35570            self.setActiveItem(null);
35571          }
35572          return false;
35573        }
35574      } else {
35575        // give control focus
35576        if (!defaultPrevented) {
35577          window.setTimeout(function() {
35578            self.focus();
35579          }, 0);
35580        }
35581      }
35582    },
35583
35584    /**
35585     * Triggered when the value of the control has been changed.
35586     * This should propagate the event to the original DOM
35587     * input / select element.
35588     */
35589    onChange: function() {
35590      this.$input.trigger('change');
35591    },
35592
35593    /**
35594     * Triggered on <input> paste.
35595     *
35596     * @param {object} e
35597     * @returns {boolean}
35598     */
35599    onPaste: function(e) {
35600      var self = this;
35601
35602      if (self.isFull() || self.isInputHidden || self.isLocked) {
35603        e.preventDefault();
35604        return;
35605      }
35606
35607      // If a regex or string is included, this will split the pasted
35608      // input and create Items for each separate value
35609      if (self.settings.splitOn) {
35610
35611        // Wait for pasted text to be recognized in value
35612        setTimeout(function() {
35613          var pastedText = self.$control_input.val();
35614          if(!pastedText.match(self.settings.splitOn)){ return }
35615
35616          var splitInput = $.trim(pastedText).split(self.settings.splitOn);
35617          for (var i = 0, n = splitInput.length; i < n; i++) {
35618            self.createItem(splitInput[i]);
35619          }
35620        }, 0);
35621      }
35622    },
35623
35624    /**
35625     * Triggered on <input> keypress.
35626     *
35627     * @param {object} e
35628     * @returns {boolean}
35629     */
35630    onKeyPress: function(e) {
35631      if (this.isLocked) return e && e.preventDefault();
35632      var character = String.fromCharCode(e.keyCode || e.which);
35633      if (this.settings.create && this.settings.mode === 'multi' && character === this.settings.delimiter) {
35634        this.createItem();
35635        e.preventDefault();
35636        return false;
35637      }
35638    },
35639
35640    /**
35641     * Triggered on <input> keydown.
35642     *
35643     * @param {object} e
35644     * @returns {boolean}
35645     */
35646    onKeyDown: function(e) {
35647      var isInput = e.target === this.$control_input[0];
35648      var self = this;
35649
35650      if (self.isLocked) {
35651        if (e.keyCode !== KEY_TAB) {
35652          e.preventDefault();
35653        }
35654        return;
35655      }
35656
35657      switch (e.keyCode) {
35658        case KEY_A:
35659          if (self.isCmdDown) {
35660            self.selectAll();
35661            return;
35662          }
35663          break;
35664        case KEY_ESC:
35665          if (self.isOpen) {
35666            e.preventDefault();
35667            e.stopPropagation();
35668            self.close();
35669          }
35670          return;
35671        case KEY_N:
35672          if (!e.ctrlKey || e.altKey) break;
35673        case KEY_DOWN:
35674          if (!self.isOpen && self.hasOptions) {
35675            self.open();
35676          } else if (self.$activeOption) {
35677            self.ignoreHover = true;
35678            var $next = self.getAdjacentOption(self.$activeOption, 1);
35679            if ($next.length) self.setActiveOption($next, true, true);
35680          }
35681          e.preventDefault();
35682          return;
35683        case KEY_P:
35684          if (!e.ctrlKey || e.altKey) break;
35685        case KEY_UP:
35686          if (self.$activeOption) {
35687            self.ignoreHover = true;
35688            var $prev = self.getAdjacentOption(self.$activeOption, -1);
35689            if ($prev.length) self.setActiveOption($prev, true, true);
35690          }
35691          e.preventDefault();
35692          return;
35693        case KEY_RETURN:
35694          if (self.isOpen && self.$activeOption) {
35695            self.onOptionSelect({currentTarget: self.$activeOption});
35696            e.preventDefault();
35697          }
35698          return;
35699        case KEY_LEFT:
35700          self.advanceSelection(-1, e);
35701          return;
35702        case KEY_RIGHT:
35703          self.advanceSelection(1, e);
35704          return;
35705        case KEY_TAB:
35706          if (self.settings.selectOnTab && self.isOpen && self.$activeOption) {
35707            self.onOptionSelect({currentTarget: self.$activeOption});
35708
35709            // Default behaviour is to jump to the next field, we only want this
35710            // if the current field doesn't accept any more entries
35711            if (!self.isFull()) {
35712              e.preventDefault();
35713            }
35714          }
35715          if (self.settings.create && self.createItem()) {
35716            e.preventDefault();
35717          }
35718          return;
35719        case KEY_BACKSPACE:
35720        case KEY_DELETE:
35721          self.deleteSelection(e);
35722          return;
35723      }
35724
35725      if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) {
35726        e.preventDefault();
35727        return;
35728      }
35729    },
35730
35731    /**
35732     * Triggered on <input> keyup.
35733     *
35734     * @param {object} e
35735     * @returns {boolean}
35736     */
35737    onKeyUp: function(e) {
35738      var self = this;
35739
35740      if (self.isLocked) return e && e.preventDefault();
35741      var value = self.$control_input.val() || '';
35742      if (self.lastValue !== value) {
35743        self.lastValue = value;
35744        self.onSearchChange(value);
35745        self.refreshOptions();
35746        self.trigger('type', value);
35747      }
35748    },
35749
35750    /**
35751     * Invokes the user-provide option provider / loader.
35752     *
35753     * Note: this function is debounced in the Selectize
35754     * constructor (by `settings.loadThrottle` milliseconds)
35755     *
35756     * @param {string} value
35757     */
35758    onSearchChange: function(value) {
35759      var self = this;
35760      var fn = self.settings.load;
35761      if (!fn) return;
35762      if (self.loadedSearches.hasOwnProperty(value)) return;
35763      self.loadedSearches[value] = true;
35764      self.load(function(callback) {
35765        fn.apply(self, [value, callback]);
35766      });
35767    },
35768
35769    /**
35770     * Triggered on <input> focus.
35771     *
35772     * @param {object} e (optional)
35773     * @returns {boolean}
35774     */
35775    onFocus: function(e) {
35776      var self = this;
35777      var wasFocused = self.isFocused;
35778
35779      if (self.isDisabled) {
35780        self.blur();
35781        e && e.preventDefault();
35782        return false;
35783      }
35784
35785      if (self.ignoreFocus) return;
35786      self.isFocused = true;
35787      if (self.settings.preload === 'focus') self.onSearchChange('');
35788
35789      if (!wasFocused) self.trigger('focus');
35790
35791      if (!self.$activeItems.length) {
35792        self.showInput();
35793        self.setActiveItem(null);
35794        self.refreshOptions(!!self.settings.openOnFocus);
35795      }
35796
35797      self.refreshState();
35798    },
35799
35800    /**
35801     * Triggered on <input> blur.
35802     *
35803     * @param {object} e
35804     * @param {Element} dest
35805     */
35806    onBlur: function(e, dest) {
35807      var self = this;
35808      if (!self.isFocused) return;
35809      self.isFocused = false;
35810
35811      if (self.ignoreFocus) {
35812        return;
35813      } else if (!self.ignoreBlur && document.activeElement === self.$dropdown_content[0]) {
35814        // necessary to prevent IE closing the dropdown when the scrollbar is clicked
35815        self.ignoreBlur = true;
35816        self.onFocus(e);
35817        return;
35818      }
35819
35820      var deactivate = function() {
35821        self.close();
35822        self.setTextboxValue('');
35823        self.setActiveItem(null);
35824        self.setActiveOption(null);
35825        self.setCaret(self.items.length);
35826        self.refreshState();
35827
35828        // IE11 bug: element still marked as active
35829        dest && dest.focus && dest.focus();
35830
35831        self.isBlurring = false;
35832        self.ignoreFocus = false;
35833        self.trigger('blur');
35834      };
35835
35836      self.isBlurring = true;
35837      self.ignoreFocus = true;
35838      if (self.settings.create && self.settings.createOnBlur) {
35839        self.createItem(null, false, deactivate);
35840      } else {
35841        deactivate();
35842      }
35843    },
35844
35845    /**
35846     * Triggered when the user rolls over
35847     * an option in the autocomplete dropdown menu.
35848     *
35849     * @param {object} e
35850     * @returns {boolean}
35851     */
35852    onOptionHover: function(e) {
35853      if (this.ignoreHover) return;
35854      this.setActiveOption(e.currentTarget, false);
35855    },
35856
35857    /**
35858     * Triggered when the user clicks on an option
35859     * in the autocomplete dropdown menu.
35860     *
35861     * @param {object} e
35862     * @returns {boolean}
35863     */
35864    onOptionSelect: function(e) {
35865      var value, $target, $option, self = this;
35866
35867      if (e.preventDefault) {
35868        e.preventDefault();
35869        e.stopPropagation();
35870      }
35871
35872      $target = $(e.currentTarget);
35873      if ($target.hasClass('create')) {
35874        self.createItem(null, function() {
35875          if (self.settings.closeAfterSelect) {
35876            self.close();
35877          }
35878        });
35879      } else {
35880        value = $target.attr('data-value');
35881        if (typeof value !== 'undefined') {
35882          self.lastQuery = null;
35883          self.setTextboxValue('');
35884          self.addItem(value);
35885          if (self.settings.closeAfterSelect) {
35886            self.close();
35887          } else if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) {
35888            self.setActiveOption(self.getOption(value));
35889          }
35890        }
35891      }
35892    },
35893
35894    /**
35895     * Triggered when the user clicks on an item
35896     * that has been selected.
35897     *
35898     * @param {object} e
35899     * @returns {boolean}
35900     */
35901    onItemSelect: function(e) {
35902      var self = this;
35903
35904      if (self.isLocked) return;
35905      if (self.settings.mode === 'multi') {
35906        e.preventDefault();
35907        self.setActiveItem(e.currentTarget, e);
35908      }
35909    },
35910
35911    /**
35912     * Invokes the provided method that provides
35913     * results to a callback---which are then added
35914     * as options to the control.
35915     *
35916     * @param {function} fn
35917     */
35918    load: function(fn) {
35919      var self = this;
35920      var $wrapper = self.$wrapper.addClass(self.settings.loadingClass);
35921
35922      self.loading++;
35923      fn.apply(self, [function(results) {
35924        self.loading = Math.max(self.loading - 1, 0);
35925        if (results && results.length) {
35926          self.addOption(results);
35927          self.refreshOptions(self.isFocused && !self.isInputHidden);
35928        }
35929        if (!self.loading) {
35930          $wrapper.removeClass(self.settings.loadingClass);
35931        }
35932        self.trigger('load', results);
35933      }]);
35934    },
35935
35936    /**
35937     * Sets the input field of the control to the specified value.
35938     *
35939     * @param {string} value
35940     */
35941    setTextboxValue: function(value) {
35942      var $input = this.$control_input;
35943      var changed = $input.val() !== value;
35944      if (changed) {
35945        $input.val(value).triggerHandler('update');
35946        this.lastValue = value;
35947      }
35948    },
35949
35950    /**
35951     * Returns the value of the control. If multiple items
35952     * can be selected (e.g. <select multiple>), this returns
35953     * an array. If only one item can be selected, this
35954     * returns a string.
35955     *
35956     * @returns {mixed}
35957     */
35958    getValue: function() {
35959      if (this.tagType === TAG_SELECT && this.$input.attr('multiple')) {
35960        return this.items;
35961      } else {
35962        return this.items.join(this.settings.delimiter);
35963      }
35964    },
35965
35966    /**
35967     * Resets the selected items to the given value.
35968     *
35969     * @param {mixed} value
35970     */
35971    setValue: function(value, silent) {
35972      var events = silent ? [] : ['change'];
35973
35974      debounce_events(this, events, function() {
35975        this.clear(silent);
35976        this.addItems(value, silent);
35977      });
35978    },
35979
35980    /**
35981     * Sets the selected item.
35982     *
35983     * @param {object} $item
35984     * @param {object} e (optional)
35985     */
35986    setActiveItem: function($item, e) {
35987      var self = this;
35988      var eventName;
35989      var i, idx, begin, end, item, swap;
35990      var $last;
35991
35992      if (self.settings.mode === 'single') return;
35993      $item = $($item);
35994
35995      // clear the active selection
35996      if (!$item.length) {
35997        $(self.$activeItems).removeClass('active');
35998        self.$activeItems = [];
35999        if (self.isFocused) {
36000          self.showInput();
36001        }
36002        return;
36003      }
36004
36005      // modify selection
36006      eventName = e && e.type.toLowerCase();
36007
36008      if (eventName === 'mousedown' && self.isShiftDown && self.$activeItems.length) {
36009        $last = self.$control.children('.active:last');
36010        begin = Array.prototype.indexOf.apply(self.$control[0].childNodes, [$last[0]]);
36011        end   = Array.prototype.indexOf.apply(self.$control[0].childNodes, [$item[0]]);
36012        if (begin > end) {
36013          swap  = begin;
36014          begin = end;
36015          end   = swap;
36016        }
36017        for (i = begin; i <= end; i++) {
36018          item = self.$control[0].childNodes[i];
36019          if (self.$activeItems.indexOf(item) === -1) {
36020            $(item).addClass('active');
36021            self.$activeItems.push(item);
36022          }
36023        }
36024        e.preventDefault();
36025      } else if ((eventName === 'mousedown' && self.isCtrlDown) || (eventName === 'keydown' && this.isShiftDown)) {
36026        if ($item.hasClass('active')) {
36027          idx = self.$activeItems.indexOf($item[0]);
36028          self.$activeItems.splice(idx, 1);
36029          $item.removeClass('active');
36030        } else {
36031          self.$activeItems.push($item.addClass('active')[0]);
36032        }
36033      } else {
36034        $(self.$activeItems).removeClass('active');
36035        self.$activeItems = [$item.addClass('active')[0]];
36036      }
36037
36038      // ensure control has focus
36039      self.hideInput();
36040      if (!this.isFocused) {
36041        self.focus();
36042      }
36043    },
36044
36045    /**
36046     * Sets the selected item in the dropdown menu
36047     * of available options.
36048     *
36049     * @param {object} $object
36050     * @param {boolean} scroll
36051     * @param {boolean} animate
36052     */
36053    setActiveOption: function($option, scroll, animate) {
36054      var height_menu, height_item, y;
36055      var scroll_top, scroll_bottom;
36056      var self = this;
36057
36058      if (self.$activeOption) self.$activeOption.removeClass('active');
36059      self.$activeOption = null;
36060
36061      $option = $($option);
36062      if (!$option.length) return;
36063
36064      self.$activeOption = $option.addClass('active');
36065
36066      if (scroll || !isset(scroll)) {
36067
36068        height_menu   = self.$dropdown_content.height();
36069        height_item   = self.$activeOption.outerHeight(true);
36070        scroll        = self.$dropdown_content.scrollTop() || 0;
36071        y             = self.$activeOption.offset().top - self.$dropdown_content.offset().top + scroll;
36072        scroll_top    = y;
36073        scroll_bottom = y - height_menu + height_item;
36074
36075        if (y + height_item > height_menu + scroll) {
36076          self.$dropdown_content.stop().animate({scrollTop: scroll_bottom}, animate ? self.settings.scrollDuration : 0);
36077        } else if (y < scroll) {
36078          self.$dropdown_content.stop().animate({scrollTop: scroll_top}, animate ? self.settings.scrollDuration : 0);
36079        }
36080
36081      }
36082    },
36083
36084    /**
36085     * Selects all items (CTRL + A).
36086     */
36087    selectAll: function() {
36088      var self = this;
36089      if (self.settings.mode === 'single') return;
36090
36091      self.$activeItems = Array.prototype.slice.apply(self.$control.children(':not(input)').addClass('active'));
36092      if (self.$activeItems.length) {
36093        self.hideInput();
36094        self.close();
36095      }
36096      self.focus();
36097    },
36098
36099    /**
36100     * Hides the input element out of view, while
36101     * retaining its focus.
36102     */
36103    hideInput: function() {
36104      var self = this;
36105
36106      self.setTextboxValue('');
36107      self.$control_input.css({opacity: 0, position: 'absolute', left: self.rtl ? 10000 : -10000});
36108      self.isInputHidden = true;
36109    },
36110
36111    /**
36112     * Restores input visibility.
36113     */
36114    showInput: function() {
36115      this.$control_input.css({opacity: 1, position: 'relative', left: 0});
36116      this.isInputHidden = false;
36117    },
36118
36119    /**
36120     * Gives the control focus.
36121     */
36122    focus: function() {
36123      var self = this;
36124      if (self.isDisabled) return;
36125
36126      self.ignoreFocus = true;
36127      self.$control_input[0].focus();
36128      window.setTimeout(function() {
36129        self.ignoreFocus = false;
36130        self.onFocus();
36131      }, 0);
36132    },
36133
36134    /**
36135     * Forces the control out of focus.
36136     *
36137     * @param {Element} dest
36138     */
36139    blur: function(dest) {
36140      this.$control_input[0].blur();
36141      this.onBlur(null, dest);
36142    },
36143
36144    /**
36145     * Returns a function that scores an object
36146     * to show how good of a match it is to the
36147     * provided query.
36148     *
36149     * @param {string} query
36150     * @param {object} options
36151     * @return {function}
36152     */
36153    getScoreFunction: function(query) {
36154      return this.sifter.getScoreFunction(query, this.getSearchOptions());
36155    },
36156
36157    /**
36158     * Returns search options for sifter (the system
36159     * for scoring and sorting results).
36160     *
36161     * @see https://github.com/brianreavis/sifter.js
36162     * @return {object}
36163     */
36164    getSearchOptions: function() {
36165      var settings = this.settings;
36166      var sort = settings.sortField;
36167      if (typeof sort === 'string') {
36168        sort = [{field: sort}];
36169      }
36170
36171      return {
36172        fields      : settings.searchField,
36173        conjunction : settings.searchConjunction,
36174        sort        : sort,
36175        nesting     : settings.nesting
36176      };
36177    },
36178
36179    /**
36180     * Searches through available options and returns
36181     * a sorted array of matches.
36182     *
36183     * Returns an object containing:
36184     *
36185     *   - query {string}
36186     *   - tokens {array}
36187     *   - total {int}
36188     *   - items {array}
36189     *
36190     * @param {string} query
36191     * @returns {object}
36192     */
36193    search: function(query) {
36194      var i, value, score, result, calculateScore;
36195      var self     = this;
36196      var settings = self.settings;
36197      var options  = this.getSearchOptions();
36198
36199      // validate user-provided result scoring function
36200      if (settings.score) {
36201        calculateScore = self.settings.score.apply(this, [query]);
36202        if (typeof calculateScore !== 'function') {
36203          throw new Error('Selectize "score" setting must be a function that returns a function');
36204        }
36205      }
36206
36207      // perform search
36208      if (query !== self.lastQuery) {
36209        self.lastQuery = query;
36210        result = self.sifter.search(query, $.extend(options, {score: calculateScore}));
36211        self.currentResults = result;
36212      } else {
36213        result = $.extend(true, {}, self.currentResults);
36214      }
36215
36216      // filter out selected items
36217      if (settings.hideSelected) {
36218        for (i = result.items.length - 1; i >= 0; i--) {
36219          if (self.items.indexOf(hash_key(result.items[i].id)) !== -1) {
36220            result.items.splice(i, 1);
36221          }
36222        }
36223      }
36224
36225      return result;
36226    },
36227
36228    /**
36229     * Refreshes the list of available options shown
36230     * in the autocomplete dropdown menu.
36231     *
36232     * @param {boolean} triggerDropdown
36233     */
36234    refreshOptions: function(triggerDropdown) {
36235      var i, j, k, n, groups, groups_order, option, option_html, optgroup, optgroups, html, html_children, has_create_option;
36236      var $active, $active_before, $create;
36237
36238      if (typeof triggerDropdown === 'undefined') {
36239        triggerDropdown = true;
36240      }
36241
36242      var self              = this;
36243      var query             = $.trim(self.$control_input.val());
36244      var results           = self.search(query);
36245      var $dropdown_content = self.$dropdown_content;
36246      var active_before     = self.$activeOption && hash_key(self.$activeOption.attr('data-value'));
36247
36248      // build markup
36249      n = results.items.length;
36250      if (typeof self.settings.maxOptions === 'number') {
36251        n = Math.min(n, self.settings.maxOptions);
36252      }
36253
36254      // render and group available options individually
36255      groups = {};
36256      groups_order = [];
36257
36258      for (i = 0; i < n; i++) {
36259        option      = self.options[results.items[i].id];
36260        option_html = self.render('option', option);
36261        optgroup    = option[self.settings.optgroupField] || '';
36262        optgroups   = $.isArray(optgroup) ? optgroup : [optgroup];
36263
36264        for (j = 0, k = optgroups && optgroups.length; j < k; j++) {
36265          optgroup = optgroups[j];
36266          if (!self.optgroups.hasOwnProperty(optgroup)) {
36267            optgroup = '';
36268          }
36269          if (!groups.hasOwnProperty(optgroup)) {
36270            groups[optgroup] = document.createDocumentFragment();
36271            groups_order.push(optgroup);
36272          }
36273          groups[optgroup].appendChild(option_html);
36274        }
36275      }
36276
36277      // sort optgroups
36278      if (this.settings.lockOptgroupOrder) {
36279        groups_order.sort(function(a, b) {
36280          var a_order = self.optgroups[a].$order || 0;
36281          var b_order = self.optgroups[b].$order || 0;
36282          return a_order - b_order;
36283        });
36284      }
36285
36286      // render optgroup headers & join groups
36287      html = document.createDocumentFragment();
36288      for (i = 0, n = groups_order.length; i < n; i++) {
36289        optgroup = groups_order[i];
36290        if (self.optgroups.hasOwnProperty(optgroup) && groups[optgroup].childNodes.length) {
36291          // render the optgroup header and options within it,
36292          // then pass it to the wrapper template
36293          html_children = document.createDocumentFragment();
36294          html_children.appendChild(self.render('optgroup_header', self.optgroups[optgroup]));
36295          html_children.appendChild(groups[optgroup]);
36296
36297          html.appendChild(self.render('optgroup', $.extend({}, self.optgroups[optgroup], {
36298            html: domToString(html_children),
36299            dom:  html_children
36300          })));
36301        } else {
36302          html.appendChild(groups[optgroup]);
36303        }
36304      }
36305
36306      $dropdown_content.html(html);
36307
36308      // highlight matching terms inline
36309      if (self.settings.highlight) {
36310        $dropdown_content.removeHighlight();
36311        if (results.query.length && results.tokens.length) {
36312          for (i = 0, n = results.tokens.length; i < n; i++) {
36313            highlight($dropdown_content, results.tokens[i].regex);
36314          }
36315        }
36316      }
36317
36318      // add "selected" class to selected options
36319      if (!self.settings.hideSelected) {
36320        for (i = 0, n = self.items.length; i < n; i++) {
36321          self.getOption(self.items[i]).addClass('selected');
36322        }
36323      }
36324
36325      // add create option
36326      has_create_option = self.canCreate(query);
36327      if (has_create_option) {
36328        $dropdown_content.prepend(self.render('option_create', {input: query}));
36329        $create = $($dropdown_content[0].childNodes[0]);
36330      }
36331
36332      // activate
36333      self.hasOptions = results.items.length > 0 || has_create_option;
36334      if (self.hasOptions) {
36335        if (results.items.length > 0) {
36336          $active_before = active_before && self.getOption(active_before);
36337          if ($active_before && $active_before.length) {
36338            $active = $active_before;
36339          } else if (self.settings.mode === 'single' && self.items.length) {
36340            $active = self.getOption(self.items[0]);
36341          }
36342          if (!$active || !$active.length) {
36343            if ($create && !self.settings.addPrecedence) {
36344              $active = self.getAdjacentOption($create, 1);
36345            } else {
36346              $active = $dropdown_content.find('[data-selectable]:first');
36347            }
36348          }
36349        } else {
36350          $active = $create;
36351        }
36352        self.setActiveOption($active);
36353        if (triggerDropdown && !self.isOpen) { self.open(); }
36354      } else {
36355        self.setActiveOption(null);
36356        if (triggerDropdown && self.isOpen) { self.close(); }
36357      }
36358    },
36359
36360    /**
36361     * Adds an available option. If it already exists,
36362     * nothing will happen. Note: this does not refresh
36363     * the options list dropdown (use `refreshOptions`
36364     * for that).
36365     *
36366     * Usage:
36367     *
36368     *   this.addOption(data)
36369     *
36370     * @param {object|array} data
36371     */
36372    addOption: function(data) {
36373      var i, n, value, self = this;
36374
36375      if ($.isArray(data)) {
36376        for (i = 0, n = data.length; i < n; i++) {
36377          self.addOption(data[i]);
36378        }
36379        return;
36380      }
36381
36382      if (value = self.registerOption(data)) {
36383        self.userOptions[value] = true;
36384        self.lastQuery = null;
36385        self.trigger('option_add', value, data);
36386      }
36387    },
36388
36389    /**
36390     * Registers an option to the pool of options.
36391     *
36392     * @param {object} data
36393     * @return {boolean|string}
36394     */
36395    registerOption: function(data) {
36396      var key = hash_key(data[this.settings.valueField]);
36397      if (typeof key === 'undefined' || key === null || this.options.hasOwnProperty(key)) return false;
36398      data.$order = data.$order || ++this.order;
36399      this.options[key] = data;
36400      return key;
36401    },
36402
36403    /**
36404     * Registers an option group to the pool of option groups.
36405     *
36406     * @param {object} data
36407     * @return {boolean|string}
36408     */
36409    registerOptionGroup: function(data) {
36410      var key = hash_key(data[this.settings.optgroupValueField]);
36411      if (!key) return false;
36412
36413      data.$order = data.$order || ++this.order;
36414      this.optgroups[key] = data;
36415      return key;
36416    },
36417
36418    /**
36419     * Registers a new optgroup for options
36420     * to be bucketed into.
36421     *
36422     * @param {string} id
36423     * @param {object} data
36424     */
36425    addOptionGroup: function(id, data) {
36426      data[this.settings.optgroupValueField] = id;
36427      if (id = this.registerOptionGroup(data)) {
36428        this.trigger('optgroup_add', id, data);
36429      }
36430    },
36431
36432    /**
36433     * Removes an existing option group.
36434     *
36435     * @param {string} id
36436     */
36437    removeOptionGroup: function(id) {
36438      if (this.optgroups.hasOwnProperty(id)) {
36439        delete this.optgroups[id];
36440        this.renderCache = {};
36441        this.trigger('optgroup_remove', id);
36442      }
36443    },
36444
36445    /**
36446     * Clears all existing option groups.
36447     */
36448    clearOptionGroups: function() {
36449      this.optgroups = {};
36450      this.renderCache = {};
36451      this.trigger('optgroup_clear');
36452    },
36453
36454    /**
36455     * Updates an option available for selection. If
36456     * it is visible in the selected items or options
36457     * dropdown, it will be re-rendered automatically.
36458     *
36459     * @param {string} value
36460     * @param {object} data
36461     */
36462    updateOption: function(value, data) {
36463      var self = this;
36464      var $item, $item_new;
36465      var value_new, index_item, cache_items, cache_options, order_old;
36466
36467      value     = hash_key(value);
36468      value_new = hash_key(data[self.settings.valueField]);
36469
36470      // sanity checks
36471      if (value === null) return;
36472      if (!self.options.hasOwnProperty(value)) return;
36473      if (typeof value_new !== 'string') throw new Error('Value must be set in option data');
36474
36475      order_old = self.options[value].$order;
36476
36477      // update references
36478      if (value_new !== value) {
36479        delete self.options[value];
36480        index_item = self.items.indexOf(value);
36481        if (index_item !== -1) {
36482          self.items.splice(index_item, 1, value_new);
36483        }
36484      }
36485      data.$order = data.$order || order_old;
36486      self.options[value_new] = data;
36487
36488      // invalidate render cache
36489      cache_items = self.renderCache['item'];
36490      cache_options = self.renderCache['option'];
36491
36492      if (cache_items) {
36493        delete cache_items[value];
36494        delete cache_items[value_new];
36495      }
36496      if (cache_options) {
36497        delete cache_options[value];
36498        delete cache_options[value_new];
36499      }
36500
36501      // update the item if it's selected
36502      if (self.items.indexOf(value_new) !== -1) {
36503        $item = self.getItem(value);
36504        $item_new = $(self.render('item', data));
36505        if ($item.hasClass('active')) $item_new.addClass('active');
36506        $item.replaceWith($item_new);
36507      }
36508
36509      // invalidate last query because we might have updated the sortField
36510      self.lastQuery = null;
36511
36512      // update dropdown contents
36513      if (self.isOpen) {
36514        self.refreshOptions(false);
36515      }
36516    },
36517
36518    /**
36519     * Removes a single option.
36520     *
36521     * @param {string} value
36522     * @param {boolean} silent
36523     */
36524    removeOption: function(value, silent) {
36525      var self = this;
36526      value = hash_key(value);
36527
36528      var cache_items = self.renderCache['item'];
36529      var cache_options = self.renderCache['option'];
36530      if (cache_items) delete cache_items[value];
36531      if (cache_options) delete cache_options[value];
36532
36533      delete self.userOptions[value];
36534      delete self.options[value];
36535      self.lastQuery = null;
36536      self.trigger('option_remove', value);
36537      self.removeItem(value, silent);
36538    },
36539
36540    /**
36541     * Clears all options.
36542     */
36543    clearOptions: function() {
36544      var self = this;
36545
36546      self.loadedSearches = {};
36547      self.userOptions = {};
36548      self.renderCache = {};
36549      var options = self.options;
36550      $.each(self.options, function(key, value) {
36551        if(self.items.indexOf(key) == -1) {
36552          delete options[key];
36553        }
36554      });
36555      self.options = self.sifter.items = options;
36556      self.lastQuery = null;
36557      self.trigger('option_clear');
36558    },
36559
36560    /**
36561     * Returns the jQuery element of the option
36562     * matching the given value.
36563     *
36564     * @param {string} value
36565     * @returns {object}
36566     */
36567    getOption: function(value) {
36568      return this.getElementWithValue(value, this.$dropdown_content.find('[data-selectable]'));
36569    },
36570
36571    /**
36572     * Returns the jQuery element of the next or
36573     * previous selectable option.
36574     *
36575     * @param {object} $option
36576     * @param {int} direction  can be 1 for next or -1 for previous
36577     * @return {object}
36578     */
36579    getAdjacentOption: function($option, direction) {
36580      var $options = this.$dropdown.find('[data-selectable]');
36581      var index    = $options.index($option) + direction;
36582
36583      return index >= 0 && index < $options.length ? $options.eq(index) : $();
36584    },
36585
36586    /**
36587     * Finds the first element with a "data-value" attribute
36588     * that matches the given value.
36589     *
36590     * @param {mixed} value
36591     * @param {object} $els
36592     * @return {object}
36593     */
36594    getElementWithValue: function(value, $els) {
36595      value = hash_key(value);
36596
36597      if (typeof value !== 'undefined' && value !== null) {
36598        for (var i = 0, n = $els.length; i < n; i++) {
36599          if ($els[i].getAttribute('data-value') === value) {
36600            return $($els[i]);
36601          }
36602        }
36603      }
36604
36605      return $();
36606    },
36607
36608    /**
36609     * Returns the jQuery element of the item
36610     * matching the given value.
36611     *
36612     * @param {string} value
36613     * @returns {object}
36614     */
36615    getItem: function(value) {
36616      return this.getElementWithValue(value, this.$control.children());
36617    },
36618
36619    /**
36620     * "Selects" multiple items at once. Adds them to the list
36621     * at the current caret position.
36622     *
36623     * @param {string} value
36624     * @param {boolean} silent
36625     */
36626    addItems: function(values, silent) {
36627      this.buffer = document.createDocumentFragment();
36628
36629      var childNodes = this.$control[0].childNodes;
36630      for (var i = 0; i < childNodes.length; i++) {
36631        this.buffer.appendChild(childNodes[i]);
36632      }
36633
36634      var items = $.isArray(values) ? values : [values];
36635      for (var i = 0, n = items.length; i < n; i++) {
36636        this.isPending = (i < n - 1);
36637        this.addItem(items[i], silent);
36638      }
36639
36640      var control = this.$control[0];
36641      control.insertBefore(this.buffer, control.firstChild);
36642
36643      this.buffer = null;
36644    },
36645
36646    /**
36647     * "Selects" an item. Adds it to the list
36648     * at the current caret position.
36649     *
36650     * @param {string} value
36651     * @param {boolean} silent
36652     */
36653    addItem: function(value, silent) {
36654      var events = silent ? [] : ['change'];
36655
36656      debounce_events(this, events, function() {
36657        var $item, $option, $options;
36658        var self = this;
36659        var inputMode = self.settings.mode;
36660        var i, active, value_next, wasFull;
36661        value = hash_key(value);
36662
36663        if (self.items.indexOf(value) !== -1) {
36664          if (inputMode === 'single') self.close();
36665          return;
36666        }
36667
36668        if (!self.options.hasOwnProperty(value)) return;
36669        if (inputMode === 'single') self.clear(silent);
36670        if (inputMode === 'multi' && self.isFull()) return;
36671
36672        $item = $(self.render('item', self.options[value]));
36673        wasFull = self.isFull();
36674        self.items.splice(self.caretPos, 0, value);
36675        self.insertAtCaret($item);
36676        if (!self.isPending || (!wasFull && self.isFull())) {
36677          self.refreshState();
36678        }
36679
36680        if (self.isSetup) {
36681          $options = self.$dropdown_content.find('[data-selectable]');
36682
36683          // update menu / remove the option (if this is not one item being added as part of series)
36684          if (!self.isPending) {
36685            $option = self.getOption(value);
36686            value_next = self.getAdjacentOption($option, 1).attr('data-value');
36687            self.refreshOptions(self.isFocused && inputMode !== 'single');
36688            if (value_next) {
36689              self.setActiveOption(self.getOption(value_next));
36690            }
36691          }
36692
36693          // hide the menu if the maximum number of items have been selected or no options are left
36694          if (!$options.length || self.isFull()) {
36695            self.close();
36696          } else if (!self.isPending) {
36697            self.positionDropdown();
36698          }
36699
36700          self.updatePlaceholder();
36701          self.trigger('item_add', value, $item);
36702
36703          if (!self.isPending) {
36704            self.updateOriginalInput({silent: silent});
36705          }
36706        }
36707      });
36708    },
36709
36710    /**
36711     * Removes the selected item matching
36712     * the provided value.
36713     *
36714     * @param {string} value
36715     */
36716    removeItem: function(value, silent) {
36717      var self = this;
36718      var $item, i, idx;
36719
36720      $item = (value instanceof $) ? value : self.getItem(value);
36721      value = hash_key($item.attr('data-value'));
36722      i = self.items.indexOf(value);
36723
36724      if (i !== -1) {
36725        $item.remove();
36726        if ($item.hasClass('active')) {
36727          idx = self.$activeItems.indexOf($item[0]);
36728          self.$activeItems.splice(idx, 1);
36729        }
36730
36731        self.items.splice(i, 1);
36732        self.lastQuery = null;
36733        if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {
36734          self.removeOption(value, silent);
36735        }
36736
36737        if (i < self.caretPos) {
36738          self.setCaret(self.caretPos - 1);
36739        }
36740
36741        self.refreshState();
36742        self.updatePlaceholder();
36743        self.updateOriginalInput({silent: silent});
36744        self.positionDropdown();
36745        self.trigger('item_remove', value, $item);
36746      }
36747    },
36748
36749    /**
36750     * Invokes the `create` method provided in the
36751     * selectize options that should provide the data
36752     * for the new item, given the user input.
36753     *
36754     * Once this completes, it will be added
36755     * to the item list.
36756     *
36757     * @param {string} value
36758     * @param {boolean} [triggerDropdown]
36759     * @param {function} [callback]
36760     * @return {boolean}
36761     */
36762    createItem: function(input, triggerDropdown) {
36763      var self  = this;
36764      var caret = self.caretPos;
36765      input = input || $.trim(self.$control_input.val() || '');
36766
36767      var callback = arguments[arguments.length - 1];
36768      if (typeof callback !== 'function') callback = function() {};
36769
36770      if (typeof triggerDropdown !== 'boolean') {
36771        triggerDropdown = true;
36772      }
36773
36774      if (!self.canCreate(input)) {
36775        callback();
36776        return false;
36777      }
36778
36779      self.lock();
36780
36781      var setup = (typeof self.settings.create === 'function') ? this.settings.create : function(input) {
36782        var data = {};
36783        data[self.settings.labelField] = input;
36784        data[self.settings.valueField] = input;
36785        return data;
36786      };
36787
36788      var create = once(function(data) {
36789        self.unlock();
36790
36791        if (!data || typeof data !== 'object') return callback();
36792        var value = hash_key(data[self.settings.valueField]);
36793        if (typeof value !== 'string') return callback();
36794
36795        self.setTextboxValue('');
36796        self.addOption(data);
36797        self.setCaret(caret);
36798        self.addItem(value);
36799        self.refreshOptions(triggerDropdown && self.settings.mode !== 'single');
36800        callback(data);
36801      });
36802
36803      var output = setup.apply(this, [input, create]);
36804      if (typeof output !== 'undefined') {
36805        create(output);
36806      }
36807
36808      return true;
36809    },
36810
36811    /**
36812     * Re-renders the selected item lists.
36813     */
36814    refreshItems: function() {
36815      this.lastQuery = null;
36816
36817      if (this.isSetup) {
36818        this.addItem(this.items);
36819      }
36820
36821      this.refreshState();
36822      this.updateOriginalInput();
36823    },
36824
36825    /**
36826     * Updates all state-dependent attributes
36827     * and CSS classes.
36828     */
36829    refreshState: function() {
36830      this.refreshValidityState();
36831      this.refreshClasses();
36832    },
36833
36834    /**
36835     * Update the `required` attribute of both input and control input.
36836     *
36837     * The `required` property needs to be activated on the control input
36838     * for the error to be displayed at the right place. `required` also
36839     * needs to be temporarily deactivated on the input since the input is
36840     * hidden and can't show errors.
36841     */
36842    refreshValidityState: function() {
36843      if (!this.isRequired) return false;
36844
36845      var invalid = !this.items.length;
36846
36847      this.isInvalid = invalid;
36848      this.$control_input.prop('required', invalid);
36849      this.$input.prop('required', !invalid);
36850    },
36851
36852    /**
36853     * Updates all state-dependent CSS classes.
36854     */
36855    refreshClasses: function() {
36856      var self     = this;
36857      var isFull   = self.isFull();
36858      var isLocked = self.isLocked;
36859
36860      self.$wrapper
36861        .toggleClass('rtl', self.rtl);
36862
36863      self.$control
36864        .toggleClass('focus', self.isFocused)
36865        .toggleClass('disabled', self.isDisabled)
36866        .toggleClass('required', self.isRequired)
36867        .toggleClass('invalid', self.isInvalid)
36868        .toggleClass('locked', isLocked)
36869        .toggleClass('full', isFull).toggleClass('not-full', !isFull)
36870        .toggleClass('input-active', self.isFocused && !self.isInputHidden)
36871        .toggleClass('dropdown-active', self.isOpen)
36872        .toggleClass('has-options', !$.isEmptyObject(self.options))
36873        .toggleClass('has-items', self.items.length > 0);
36874
36875      self.$control_input.data('grow', !isFull && !isLocked);
36876    },
36877
36878    /**
36879     * Determines whether or not more items can be added
36880     * to the control without exceeding the user-defined maximum.
36881     *
36882     * @returns {boolean}
36883     */
36884    isFull: function() {
36885      return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;
36886    },
36887
36888    /**
36889     * Refreshes the original <select> or <input>
36890     * element to reflect the current state.
36891     */
36892    updateOriginalInput: function(opts) {
36893      var i, n, options, label, self = this;
36894      opts = opts || {};
36895
36896      if (self.tagType === TAG_SELECT) {
36897        options = [];
36898        for (i = 0, n = self.items.length; i < n; i++) {
36899          label = self.options[self.items[i]][self.settings.labelField] || '';
36900          options.push('<option value="' + escape_html(self.items[i]) + '" selected="selected">' + escape_html(label) + '</option>');
36901        }
36902        if (!options.length && !this.$input.attr('multiple')) {
36903          options.push('<option value="" selected="selected"></option>');
36904        }
36905        self.$input.html(options.join(''));
36906      } else {
36907        self.$input.val(self.getValue());
36908        self.$input.attr('value',self.$input.val());
36909      }
36910
36911      if (self.isSetup) {
36912        if (!opts.silent) {
36913          self.trigger('change', self.$input.val());
36914        }
36915      }
36916    },
36917
36918    /**
36919     * Shows/hide the input placeholder depending
36920     * on if there items in the list already.
36921     */
36922    updatePlaceholder: function() {
36923      if (!this.settings.placeholder) return;
36924      var $input = this.$control_input;
36925
36926      if (this.items.length) {
36927        $input.removeAttr('placeholder');
36928      } else {
36929        $input.attr('placeholder', this.settings.placeholder);
36930      }
36931      $input.triggerHandler('update', {force: true});
36932    },
36933
36934    /**
36935     * Shows the autocomplete dropdown containing
36936     * the available options.
36937     */
36938    open: function() {
36939      var self = this;
36940
36941      if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return;
36942      self.focus();
36943      self.isOpen = true;
36944      self.refreshState();
36945      self.$dropdown.css({visibility: 'hidden', display: 'block'});
36946      self.positionDropdown();
36947      self.$dropdown.css({visibility: 'visible'});
36948      self.trigger('dropdown_open', self.$dropdown);
36949    },
36950
36951    /**
36952     * Closes the autocomplete dropdown menu.
36953     */
36954    close: function() {
36955      var self = this;
36956      var trigger = self.isOpen;
36957
36958      if (self.settings.mode === 'single' && self.items.length) {
36959        self.hideInput();
36960
36961        // Do not trigger blur while inside a blur event,
36962        // this fixes some weird tabbing behavior in FF and IE.
36963        // See #1164
36964        if (!self.isBlurring) {
36965          self.$control_input.blur(); // close keyboard on iOS
36966        }
36967      }
36968
36969      self.isOpen = false;
36970      self.$dropdown.hide();
36971      self.setActiveOption(null);
36972      self.refreshState();
36973
36974      if (trigger) self.trigger('dropdown_close', self.$dropdown);
36975    },
36976
36977    /**
36978     * Calculates and applies the appropriate
36979     * position of the dropdown.
36980     */
36981    positionDropdown: function() {
36982      var $control = this.$control;
36983      var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position();
36984      offset.top += $control.outerHeight(true);
36985
36986      this.$dropdown.css({
36987        width : $control[0].getBoundingClientRect().width,
36988        top   : offset.top,
36989        left  : offset.left
36990      });
36991    },
36992
36993    /**
36994     * Resets / clears all selected items
36995     * from the control.
36996     *
36997     * @param {boolean} silent
36998     */
36999    clear: function(silent) {
37000      var self = this;
37001
37002      if (!self.items.length) return;
37003      self.$control.children(':not(input)').remove();
37004      self.items = [];
37005      self.lastQuery = null;
37006      self.setCaret(0);
37007      self.setActiveItem(null);
37008      self.updatePlaceholder();
37009      self.updateOriginalInput({silent: silent});
37010      self.refreshState();
37011      self.showInput();
37012      self.trigger('clear');
37013    },
37014
37015    /**
37016     * A helper method for inserting an element
37017     * at the current caret position.
37018     *
37019     * @param {object} $el
37020     */
37021    insertAtCaret: function($el) {
37022      var caret = Math.min(this.caretPos, this.items.length);
37023      var el = $el[0];
37024      var target = this.buffer || this.$control[0];
37025
37026      if (caret === 0) {
37027        target.insertBefore(el, target.firstChild);
37028      } else {
37029        target.insertBefore(el, target.childNodes[caret]);
37030      }
37031
37032      this.setCaret(caret + 1);
37033    },
37034
37035    /**
37036     * Removes the current selected item(s).
37037     *
37038     * @param {object} e (optional)
37039     * @returns {boolean}
37040     */
37041    deleteSelection: function(e) {
37042      var i, n, direction, selection, values, caret, option_select, $option_select, $tail;
37043      var self = this;
37044
37045      direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1;
37046      selection = getSelection(self.$control_input[0]);
37047
37048      if (self.$activeOption && !self.settings.hideSelected) {
37049        option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value');
37050      }
37051
37052      // determine items that will be removed
37053      values = [];
37054
37055      if (self.$activeItems.length) {
37056        $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first'));
37057        caret = self.$control.children(':not(input)').index($tail);
37058        if (direction > 0) { caret++; }
37059
37060        for (i = 0, n = self.$activeItems.length; i < n; i++) {
37061          values.push($(self.$activeItems[i]).attr('data-value'));
37062        }
37063        if (e) {
37064          e.preventDefault();
37065          e.stopPropagation();
37066        }
37067      } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {
37068        if (direction < 0 && selection.start === 0 && selection.length === 0) {
37069          values.push(self.items[self.caretPos - 1]);
37070        } else if (direction > 0 && selection.start === self.$control_input.val().length) {
37071          values.push(self.items[self.caretPos]);
37072        }
37073      }
37074
37075      // allow the callback to abort
37076      if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) {
37077        return false;
37078      }
37079
37080      // perform removal
37081      if (typeof caret !== 'undefined') {
37082        self.setCaret(caret);
37083      }
37084      while (values.length) {
37085        self.removeItem(values.pop());
37086      }
37087
37088      self.showInput();
37089      self.positionDropdown();
37090      self.refreshOptions(true);
37091
37092      // select previous option
37093      if (option_select) {
37094        $option_select = self.getOption(option_select);
37095        if ($option_select.length) {
37096          self.setActiveOption($option_select);
37097        }
37098      }
37099
37100      return true;
37101    },
37102
37103    /**
37104     * Selects the previous / next item (depending
37105     * on the `direction` argument).
37106     *
37107     * > 0 - right
37108     * < 0 - left
37109     *
37110     * @param {int} direction
37111     * @param {object} e (optional)
37112     */
37113    advanceSelection: function(direction, e) {
37114      var tail, selection, idx, valueLength, cursorAtEdge, $tail;
37115      var self = this;
37116
37117      if (direction === 0) return;
37118      if (self.rtl) direction *= -1;
37119
37120      tail = direction > 0 ? 'last' : 'first';
37121      selection = getSelection(self.$control_input[0]);
37122
37123      if (self.isFocused && !self.isInputHidden) {
37124        valueLength = self.$control_input.val().length;
37125        cursorAtEdge = direction < 0
37126          ? selection.start === 0 && selection.length === 0
37127          : selection.start === valueLength;
37128
37129        if (cursorAtEdge && !valueLength) {
37130          self.advanceCaret(direction, e);
37131        }
37132      } else {
37133        $tail = self.$control.children('.active:' + tail);
37134        if ($tail.length) {
37135          idx = self.$control.children(':not(input)').index($tail);
37136          self.setActiveItem(null);
37137          self.setCaret(direction > 0 ? idx + 1 : idx);
37138        }
37139      }
37140    },
37141
37142    /**
37143     * Moves the caret left / right.
37144     *
37145     * @param {int} direction
37146     * @param {object} e (optional)
37147     */
37148    advanceCaret: function(direction, e) {
37149      var self = this, fn, $adj;
37150
37151      if (direction === 0) return;
37152
37153      fn = direction > 0 ? 'next' : 'prev';
37154      if (self.isShiftDown) {
37155        $adj = self.$control_input[fn]();
37156        if ($adj.length) {
37157          self.hideInput();
37158          self.setActiveItem($adj);
37159          e && e.preventDefault();
37160        }
37161      } else {
37162        self.setCaret(self.caretPos + direction);
37163      }
37164    },
37165
37166    /**
37167     * Moves the caret to the specified index.
37168     *
37169     * @param {int} i
37170     */
37171    setCaret: function(i) {
37172      var self = this;
37173
37174      if (self.settings.mode === 'single') {
37175        i = self.items.length;
37176      } else {
37177        i = Math.max(0, Math.min(self.items.length, i));
37178      }
37179
37180      if(!self.isPending) {
37181        // the input must be moved by leaving it in place and moving the
37182        // siblings, due to the fact that focus cannot be restored once lost
37183        // on mobile webkit devices
37184        var j, n, fn, $children, $child;
37185        $children = self.$control.children(':not(input)');
37186        for (j = 0, n = $children.length; j < n; j++) {
37187          $child = $($children[j]).detach();
37188          if (j <  i) {
37189            self.$control_input.before($child);
37190          } else {
37191            self.$control.append($child);
37192          }
37193        }
37194      }
37195
37196      self.caretPos = i;
37197    },
37198
37199    /**
37200     * Disables user input on the control. Used while
37201     * items are being asynchronously created.
37202     */
37203    lock: function() {
37204      this.close();
37205      this.isLocked = true;
37206      this.refreshState();
37207    },
37208
37209    /**
37210     * Re-enables user input on the control.
37211     */
37212    unlock: function() {
37213      this.isLocked = false;
37214      this.refreshState();
37215    },
37216
37217    /**
37218     * Disables user input on the control completely.
37219     * While disabled, it cannot receive focus.
37220     */
37221    disable: function() {
37222      var self = this;
37223      self.$input.prop('disabled', true);
37224      self.$control_input.prop('disabled', true).prop('tabindex', -1);
37225      self.isDisabled = true;
37226      self.lock();
37227    },
37228
37229    /**
37230     * Enables the control so that it can respond
37231     * to focus and user input.
37232     */
37233    enable: function() {
37234      var self = this;
37235      self.$input.prop('disabled', false);
37236      self.$control_input.prop('disabled', false).prop('tabindex', self.tabIndex);
37237      self.isDisabled = false;
37238      self.unlock();
37239    },
37240
37241    /**
37242     * Completely destroys the control and
37243     * unbinds all event listeners so that it can
37244     * be garbage collected.
37245     */
37246    destroy: function() {
37247      var self = this;
37248      var eventNS = self.eventNS;
37249      var revertSettings = self.revertSettings;
37250
37251      self.trigger('destroy');
37252      self.off();
37253      self.$wrapper.remove();
37254      self.$dropdown.remove();
37255
37256      self.$input
37257        .html('')
37258        .append(revertSettings.$children)
37259        .removeAttr('tabindex')
37260        .removeClass('selectized')
37261        .attr({tabindex: revertSettings.tabindex})
37262        .show();
37263
37264      self.$control_input.removeData('grow');
37265      self.$input.removeData('selectize');
37266
37267      if (--Selectize.count == 0 && Selectize.$testInput) {
37268        Selectize.$testInput.remove();
37269        Selectize.$testInput = undefined;
37270      }
37271
37272      $(window).off(eventNS);
37273      $(document).off(eventNS);
37274      $(document.body).off(eventNS);
37275
37276      delete self.$input[0].selectize;
37277    },
37278
37279    /**
37280     * A helper method for rendering "item" and
37281     * "option" templates, given the data.
37282     *
37283     * @param {string} templateName
37284     * @param {object} data
37285     * @returns {string}
37286     */
37287    render: function(templateName, data) {
37288      var value, id, label;
37289      var html = '';
37290      var cache = false;
37291      var self = this;
37292      var regex_tag = /^[\t \r\n]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;
37293
37294      if (templateName === 'option' || templateName === 'item') {
37295        value = hash_key(data[self.settings.valueField]);
37296        cache = !!value;
37297      }
37298
37299      // pull markup from cache if it exists
37300      if (cache) {
37301        if (!isset(self.renderCache[templateName])) {
37302          self.renderCache[templateName] = {};
37303        }
37304        if (self.renderCache[templateName].hasOwnProperty(value)) {
37305          return self.renderCache[templateName][value];
37306        }
37307      }
37308
37309      // render markup
37310      html = $(self.settings.render[templateName].apply(this, [data, escape_html]));
37311
37312      // add mandatory attributes
37313      if (templateName === 'option' || templateName === 'option_create') {
37314        if (!data[self.settings.disabledField]) {
37315          html.attr('data-selectable', '');
37316        }
37317      }
37318      else if (templateName === 'optgroup') {
37319        id = data[self.settings.optgroupValueField] || '';
37320        html.attr('data-group', id);
37321        if(data[self.settings.disabledField]) {
37322          html.attr('data-disabled', '');
37323        }
37324      }
37325      if (templateName === 'option' || templateName === 'item') {
37326        html.attr('data-value', value || '');
37327      }
37328
37329      // update cache
37330      if (cache) {
37331        self.renderCache[templateName][value] = html[0];
37332      }
37333
37334      return html[0];
37335    },
37336
37337    /**
37338     * Clears the render cache for a template. If
37339     * no template is given, clears all render
37340     * caches.
37341     *
37342     * @param {string} templateName
37343     */
37344    clearCache: function(templateName) {
37345      var self = this;
37346      if (typeof templateName === 'undefined') {
37347        self.renderCache = {};
37348      } else {
37349        delete self.renderCache[templateName];
37350      }
37351    },
37352
37353    /**
37354     * Determines whether or not to display the
37355     * create item prompt, given a user input.
37356     *
37357     * @param {string} input
37358     * @return {boolean}
37359     */
37360    canCreate: function(input) {
37361      var self = this;
37362      if (!self.settings.create) return false;
37363      var filter = self.settings.createFilter;
37364      return input.length
37365        && (typeof filter !== 'function' || filter.apply(self, [input]))
37366        && (typeof filter !== 'string' || new RegExp(filter).test(input))
37367        && (!(filter instanceof RegExp) || filter.test(input));
37368    }
37369
37370  });
37371
37372
37373  Selectize.count = 0;
37374  Selectize.defaults = {
37375    options: [],
37376    optgroups: [],
37377
37378    plugins: [],
37379    delimiter: ',',
37380    splitOn: null, // regexp or string for splitting up values from a paste command
37381    persist: true,
37382    diacritics: true,
37383    create: false,
37384    createOnBlur: false,
37385    createFilter: null,
37386    highlight: true,
37387    openOnFocus: true,
37388    maxOptions: 1000,
37389    maxItems: null,
37390    hideSelected: null,
37391    addPrecedence: false,
37392    selectOnTab: false,
37393    preload: false,
37394    allowEmptyOption: false,
37395    closeAfterSelect: false,
37396
37397    scrollDuration: 60,
37398    loadThrottle: 300,
37399    loadingClass: 'loading',
37400
37401    dataAttr: 'data-data',
37402    optgroupField: 'optgroup',
37403    valueField: 'value',
37404    labelField: 'text',
37405    disabledField: 'disabled',
37406    optgroupLabelField: 'label',
37407    optgroupValueField: 'value',
37408    lockOptgroupOrder: false,
37409
37410    sortField: '$order',
37411    searchField: ['text'],
37412    searchConjunction: 'and',
37413
37414    mode: null,
37415    wrapperClass: 'selectize-control',
37416    inputClass: 'selectize-input',
37417    dropdownClass: 'selectize-dropdown',
37418    dropdownContentClass: 'selectize-dropdown-content',
37419
37420    dropdownParent: null,
37421
37422    copyClassesToDropdown: true,
37423
37424    /*
37425    load                 : null, // function(query, callback) { ... }
37426    score                : null, // function(search) { ... }
37427    onInitialize         : null, // function() { ... }
37428    onChange             : null, // function(value) { ... }
37429    onItemAdd            : null, // function(value, $item) { ... }
37430    onItemRemove         : null, // function(value) { ... }
37431    onClear              : null, // function() { ... }
37432    onOptionAdd          : null, // function(value, data) { ... }
37433    onOptionRemove       : null, // function(value) { ... }
37434    onOptionClear        : null, // function() { ... }
37435    onOptionGroupAdd     : null, // function(id, data) { ... }
37436    onOptionGroupRemove  : null, // function(id) { ... }
37437    onOptionGroupClear   : null, // function() { ... }
37438    onDropdownOpen       : null, // function($dropdown) { ... }
37439    onDropdownClose      : null, // function($dropdown) { ... }
37440    onType               : null, // function(str) { ... }
37441    onDelete             : null, // function(values) { ... }
37442    */
37443
37444    render: {
37445      /*
37446      item: null,
37447      optgroup: null,
37448      optgroup_header: null,
37449      option: null,
37450      option_create: null
37451      */
37452    }
37453  };
37454
37455
37456  $.fn.selectize = function(settings_user) {
37457    var defaults             = $.fn.selectize.defaults;
37458    var settings             = $.extend({}, defaults, settings_user);
37459    var attr_data            = settings.dataAttr;
37460    var field_label          = settings.labelField;
37461    var field_value          = settings.valueField;
37462    var field_disabled       = settings.disabledField;
37463    var field_optgroup       = settings.optgroupField;
37464    var field_optgroup_label = settings.optgroupLabelField;
37465    var field_optgroup_value = settings.optgroupValueField;
37466
37467    /**
37468     * Initializes selectize from a <input type="text"> element.
37469     *
37470     * @param {object} $input
37471     * @param {object} settings_element
37472     */
37473    var init_textbox = function($input, settings_element) {
37474      var i, n, values, option;
37475
37476      var data_raw = $input.attr(attr_data);
37477
37478      if (!data_raw) {
37479        var value = $.trim($input.val() || '');
37480        if (!settings.allowEmptyOption && !value.length) return;
37481        values = value.split(settings.delimiter);
37482        for (i = 0, n = values.length; i < n; i++) {
37483          option = {};
37484          option[field_label] = values[i];
37485          option[field_value] = values[i];
37486          settings_element.options.push(option);
37487        }
37488        settings_element.items = values;
37489      } else {
37490        settings_element.options = JSON.parse(data_raw);
37491        for (i = 0, n = settings_element.options.length; i < n; i++) {
37492          settings_element.items.push(settings_element.options[i][field_value]);
37493        }
37494      }
37495    };
37496
37497    /**
37498     * Initializes selectize from a <select> element.
37499     *
37500     * @param {object} $input
37501     * @param {object} settings_element
37502     */
37503    var init_select = function($input, settings_element) {
37504      var i, n, tagName, $children, order = 0;
37505      var options = settings_element.options;
37506      var optionsMap = {};
37507
37508      var readData = function($el) {
37509        var data = attr_data && $el.attr(attr_data);
37510        if (typeof data === 'string' && data.length) {
37511          return JSON.parse(data);
37512        }
37513        return null;
37514      };
37515
37516      var addOption = function($option, group) {
37517        $option = $($option);
37518
37519        var value = hash_key($option.val());
37520        if (!value && !settings.allowEmptyOption) return;
37521
37522        // if the option already exists, it's probably been
37523        // duplicated in another optgroup. in this case, push
37524        // the current group to the "optgroup" property on the
37525        // existing option so that it's rendered in both places.
37526        if (optionsMap.hasOwnProperty(value)) {
37527          if (group) {
37528            var arr = optionsMap[value][field_optgroup];
37529            if (!arr) {
37530              optionsMap[value][field_optgroup] = group;
37531            } else if (!$.isArray(arr)) {
37532              optionsMap[value][field_optgroup] = [arr, group];
37533            } else {
37534              arr.push(group);
37535            }
37536          }
37537          return;
37538        }
37539
37540        var option             = readData($option) || {};
37541        option[field_label]    = option[field_label] || $option.text();
37542        option[field_value]    = option[field_value] || value;
37543        option[field_disabled] = option[field_disabled] || $option.prop('disabled');
37544        option[field_optgroup] = option[field_optgroup] || group;
37545
37546        optionsMap[value] = option;
37547        options.push(option);
37548
37549        if ($option.is(':selected')) {
37550          settings_element.items.push(value);
37551        }
37552      };
37553
37554      var addGroup = function($optgroup) {
37555        var i, n, id, optgroup, $options;
37556
37557        $optgroup = $($optgroup);
37558        id = $optgroup.attr('label');
37559
37560        if (id) {
37561          optgroup = readData($optgroup) || {};
37562          optgroup[field_optgroup_label] = id;
37563          optgroup[field_optgroup_value] = id;
37564          optgroup[field_disabled] = $optgroup.prop('disabled');
37565          settings_element.optgroups.push(optgroup);
37566        }
37567
37568        $options = $('option', $optgroup);
37569        for (i = 0, n = $options.length; i < n; i++) {
37570          addOption($options[i], id);
37571        }
37572      };
37573
37574      settings_element.maxItems = $input.attr('multiple') ? null : 1;
37575
37576      $children = $input.children();
37577      for (i = 0, n = $children.length; i < n; i++) {
37578        tagName = $children[i].tagName.toLowerCase();
37579        if (tagName === 'optgroup') {
37580          addGroup($children[i]);
37581        } else if (tagName === 'option') {
37582          addOption($children[i]);
37583        }
37584      }
37585    };
37586
37587    return this.each(function() {
37588      if (this.selectize) return;
37589
37590      var instance;
37591      var $input = $(this);
37592      var tag_name = this.tagName.toLowerCase();
37593      var placeholder = $input.attr('placeholder') || $input.attr('data-placeholder');
37594      if (!placeholder && !settings.allowEmptyOption) {
37595        placeholder = $input.children('option[value=""]').text();
37596      }
37597
37598      var settings_element = {
37599        'placeholder' : placeholder,
37600        'options'     : [],
37601        'optgroups'   : [],
37602        'items'       : []
37603      };
37604
37605      if (tag_name === 'select') {
37606        init_select($input, settings_element);
37607      } else {
37608        init_textbox($input, settings_element);
37609      }
37610
37611      instance = new Selectize($input, $.extend(true, {}, defaults, settings_element, settings_user));
37612    });
37613  };
37614
37615  $.fn.selectize.defaults = Selectize.defaults;
37616  $.fn.selectize.support = {
37617    validity: SUPPORTS_VALIDITY_API
37618  };
37619
37620
37621  Selectize.define('drag_drop', function(options) {
37622    if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');
37623    if (this.settings.mode !== 'multi') return;
37624    var self = this;
37625
37626    self.lock = (function() {
37627      var original = self.lock;
37628      return function() {
37629        var sortable = self.$control.data('sortable');
37630        if (sortable) sortable.disable();
37631        return original.apply(self, arguments);
37632      };
37633    })();
37634
37635    self.unlock = (function() {
37636      var original = self.unlock;
37637      return function() {
37638        var sortable = self.$control.data('sortable');
37639        if (sortable) sortable.enable();
37640        return original.apply(self, arguments);
37641      };
37642    })();
37643
37644    self.setup = (function() {
37645      var original = self.setup;
37646      return function() {
37647        original.apply(this, arguments);
37648
37649        var $control = self.$control.sortable({
37650          items: '[data-value]',
37651          forcePlaceholderSize: true,
37652          disabled: self.isLocked,
37653          start: function(e, ui) {
37654            ui.placeholder.css('width', ui.helper.css('width'));
37655            $control.css({overflow: 'visible'});
37656          },
37657          stop: function() {
37658            $control.css({overflow: 'hidden'});
37659            var active = self.$activeItems ? self.$activeItems.slice() : null;
37660            var values = [];
37661            $control.children('[data-value]').each(function() {
37662              values.push($(this).attr('data-value'));
37663            });
37664            self.setValue(values);
37665            self.setActiveItem(active);
37666          }
37667        });
37668      };
37669    })();
37670
37671  });
37672
37673  Selectize.define('dropdown_header', function(options) {
37674    var self = this;
37675
37676    options = $.extend({
37677      title         : 'Untitled',
37678      headerClass   : 'selectize-dropdown-header',
37679      titleRowClass : 'selectize-dropdown-header-title',
37680      labelClass    : 'selectize-dropdown-header-label',
37681      closeClass    : 'selectize-dropdown-header-close',
37682
37683      html: function(data) {
37684        return (
37685          '<div class="' + data.headerClass + '">' +
37686            '<div class="' + data.titleRowClass + '">' +
37687              '<span class="' + data.labelClass + '">' + data.title + '</span>' +
37688              '<a href="javascript:void(0)" class="' + data.closeClass + '">&times;</a>' +
37689            '</div>' +
37690          '</div>'
37691        );
37692      }
37693    }, options);
37694
37695    self.setup = (function() {
37696      var original = self.setup;
37697      return function() {
37698        original.apply(self, arguments);
37699        self.$dropdown_header = $(options.html(options));
37700        self.$dropdown.prepend(self.$dropdown_header);
37701      };
37702    })();
37703
37704  });
37705
37706  Selectize.define('optgroup_columns', function(options) {
37707    var self = this;
37708
37709    options = $.extend({
37710      equalizeWidth  : true,
37711      equalizeHeight : true
37712    }, options);
37713
37714    this.getAdjacentOption = function($option, direction) {
37715      var $options = $option.closest('[data-group]').find('[data-selectable]');
37716      var index    = $options.index($option) + direction;
37717
37718      return index >= 0 && index < $options.length ? $options.eq(index) : $();
37719    };
37720
37721    this.onKeyDown = (function() {
37722      var original = self.onKeyDown;
37723      return function(e) {
37724        var index, $option, $options, $optgroup;
37725
37726        if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) {
37727          self.ignoreHover = true;
37728          $optgroup = this.$activeOption.closest('[data-group]');
37729          index = $optgroup.find('[data-selectable]').index(this.$activeOption);
37730
37731          if(e.keyCode === KEY_LEFT) {
37732            $optgroup = $optgroup.prev('[data-group]');
37733          } else {
37734            $optgroup = $optgroup.next('[data-group]');
37735          }
37736
37737          $options = $optgroup.find('[data-selectable]');
37738          $option  = $options.eq(Math.min($options.length - 1, index));
37739          if ($option.length) {
37740            this.setActiveOption($option);
37741          }
37742          return;
37743        }
37744
37745        return original.apply(this, arguments);
37746      };
37747    })();
37748
37749    var getScrollbarWidth = function() {
37750      var div;
37751      var width = getScrollbarWidth.width;
37752      var doc = document;
37753
37754      if (typeof width === 'undefined') {
37755        div = doc.createElement('div');
37756        div.innerHTML = '<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>';
37757        div = div.firstChild;
37758        doc.body.appendChild(div);
37759        width = getScrollbarWidth.width = div.offsetWidth - div.clientWidth;
37760        doc.body.removeChild(div);
37761      }
37762      return width;
37763    };
37764
37765    var equalizeSizes = function() {
37766      var i, n, height_max, width, width_last, width_parent, $optgroups;
37767
37768      $optgroups = $('[data-group]', self.$dropdown_content);
37769      n = $optgroups.length;
37770      if (!n || !self.$dropdown_content.width()) return;
37771
37772      if (options.equalizeHeight) {
37773        height_max = 0;
37774        for (i = 0; i < n; i++) {
37775          height_max = Math.max(height_max, $optgroups.eq(i).height());
37776        }
37777        $optgroups.css({height: height_max});
37778      }
37779
37780      if (options.equalizeWidth) {
37781        width_parent = self.$dropdown_content.innerWidth() - getScrollbarWidth();
37782        width = Math.round(width_parent / n);
37783        $optgroups.css({width: width});
37784        if (n > 1) {
37785          width_last = width_parent - width * (n - 1);
37786          $optgroups.eq(n - 1).css({width: width_last});
37787        }
37788      }
37789    };
37790
37791    if (options.equalizeHeight || options.equalizeWidth) {
37792      hook.after(this, 'positionDropdown', equalizeSizes);
37793      hook.after(this, 'refreshOptions', equalizeSizes);
37794    }
37795
37796
37797  });
37798
37799  Selectize.define('remove_button', function(options) {
37800    options = $.extend({
37801        label     : '&times;',
37802        title     : 'Remove',
37803        className : 'remove',
37804        append    : true
37805      }, options);
37806
37807      var singleClose = function(thisRef, options) {
37808
37809        options.className = 'remove-single';
37810
37811        var self = thisRef;
37812        var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
37813
37814        /**
37815         * Appends an element as a child (with raw HTML).
37816         *
37817         * @param {string} html_container
37818         * @param {string} html_element
37819         * @return {string}
37820         */
37821        var append = function(html_container, html_element) {
37822          return $('<span>').append(html_container)
37823            .append(html_element);
37824        };
37825
37826        thisRef.setup = (function() {
37827          var original = self.setup;
37828          return function() {
37829            // override the item rendering method to add the button to each
37830            if (options.append) {
37831              var id = $(self.$input.context).attr('id');
37832              var selectizer = $('#'+id);
37833
37834              var render_item = self.settings.render.item;
37835              self.settings.render.item = function(data) {
37836                return append(render_item.apply(thisRef, arguments), html);
37837              };
37838            }
37839
37840            original.apply(thisRef, arguments);
37841
37842            // add event listener
37843            thisRef.$control.on('click', '.' + options.className, function(e) {
37844              e.preventDefault();
37845              if (self.isLocked) return;
37846
37847              self.clear();
37848            });
37849
37850          };
37851        })();
37852      };
37853
37854      var multiClose = function(thisRef, options) {
37855
37856        var self = thisRef;
37857        var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
37858
37859        /**
37860         * Appends an element as a child (with raw HTML).
37861         *
37862         * @param {string} html_container
37863         * @param {string} html_element
37864         * @return {string}
37865         */
37866        var append = function(html_container, html_element) {
37867          var pos = html_container.search(/(<\/[^>]+>\s*)$/);
37868          return html_container.substring(0, pos) + html_element + html_container.substring(pos);
37869        };
37870
37871        thisRef.setup = (function() {
37872          var original = self.setup;
37873          return function() {
37874            // override the item rendering method to add the button to each
37875            if (options.append) {
37876              var render_item = self.settings.render.item;
37877              self.settings.render.item = function(data) {
37878                return append(render_item.apply(thisRef, arguments), html);
37879              };
37880            }
37881
37882            original.apply(thisRef, arguments);
37883
37884            // add event listener
37885            thisRef.$control.on('click', '.' + options.className, function(e) {
37886              e.preventDefault();
37887              if (self.isLocked) return;
37888
37889              var $item = $(e.currentTarget).parent();
37890              self.setActiveItem($item);
37891              if (self.deleteSelection()) {
37892                self.setCaret(self.items.length);
37893              }
37894            });
37895
37896          };
37897        })();
37898      };
37899
37900      if (this.settings.mode === 'single') {
37901        singleClose(this, options);
37902        return;
37903      } else {
37904        multiClose(this, options);
37905      }
37906  });
37907
37908
37909  Selectize.define('restore_on_backspace', function(options) {
37910    var self = this;
37911
37912    options.text = options.text || function(option) {
37913      return option[this.settings.labelField];
37914    };
37915
37916    this.onKeyDown = (function() {
37917      var original = self.onKeyDown;
37918      return function(e) {
37919        var index, option;
37920        if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) {
37921          index = this.caretPos - 1;
37922          if (index >= 0 && index < this.items.length) {
37923            option = this.options[this.items[index]];
37924            if (this.deleteSelection(e)) {
37925              this.setTextboxValue(options.text.apply(this, [option]));
37926              this.refreshOptions(true);
37927            }
37928            e.preventDefault();
37929            return;
37930          }
37931        }
37932        return original.apply(this, arguments);
37933      };
37934    })();
37935  });
37936
37937
37938  return Selectize;
37939}));
37940/*
37941 * Mailcheck https://github.com/mailcheck/mailcheck
37942 * Author
37943 * Derrick Ko (@derrickko)
37944 *
37945 * Released under the MIT License.
37946 *
37947 * v 1.1.2
37948 */
37949
37950var Mailcheck = {
37951  domainThreshold: 2,
37952  secondLevelThreshold: 2,
37953  topLevelThreshold: 2,
37954
37955  defaultDomains: ['msn.com', 'bellsouth.net',
37956    'telus.net', 'comcast.net', 'optusnet.com.au',
37957    'earthlink.net', 'qq.com', 'sky.com', 'icloud.com',
37958    'mac.com', 'sympatico.ca', 'googlemail.com',
37959    'att.net', 'xtra.co.nz', 'web.de',
37960    'cox.net', 'gmail.com', 'ymail.com',
37961    'aim.com', 'rogers.com', 'verizon.net',
37962    'rocketmail.com', 'google.com', 'optonline.net',
37963    'sbcglobal.net', 'aol.com', 'me.com', 'btinternet.com',
37964    'charter.net', 'shaw.ca'],
37965
37966  defaultSecondLevelDomains: ["yahoo", "hotmail", "mail", "live", "outlook", "gmx"],
37967
37968  defaultTopLevelDomains: ["com", "com.au", "com.tw", "ca", "co.nz", "co.uk", "de",
37969    "fr", "it", "ru", "net", "org", "edu", "gov", "jp", "nl", "kr", "se", "eu",
37970    "ie", "co.il", "us", "at", "be", "dk", "hk", "es", "gr", "ch", "no", "cz",
37971    "in", "net", "net.au", "info", "biz", "mil", "co.jp", "sg", "hu", "uk"],
37972
37973  run: function(opts) {
37974    opts.domains = opts.domains || Mailcheck.defaultDomains;
37975    opts.secondLevelDomains = opts.secondLevelDomains || Mailcheck.defaultSecondLevelDomains;
37976    opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains;
37977    opts.distanceFunction = opts.distanceFunction || Mailcheck.sift3Distance;
37978
37979    var defaultCallback = function(result){ return result };
37980    var suggestedCallback = opts.suggested || defaultCallback;
37981    var emptyCallback = opts.empty || defaultCallback;
37982
37983    var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.secondLevelDomains, opts.topLevelDomains, opts.distanceFunction);
37984
37985    return result ? suggestedCallback(result) : emptyCallback()
37986  },
37987
37988  suggest: function(email, domains, secondLevelDomains, topLevelDomains, distanceFunction) {
37989    email = email.toLowerCase();
37990
37991    var emailParts = this.splitEmail(email);
37992
37993    if (secondLevelDomains && topLevelDomains) {
37994        // If the email is a valid 2nd-level + top-level, do not suggest anything.
37995        if (secondLevelDomains.indexOf(emailParts.secondLevelDomain) !== -1 && topLevelDomains.indexOf(emailParts.topLevelDomain) !== -1) {
37996            return false;
37997        }
37998    }
37999
38000    var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold);
38001
38002    if (closestDomain) {
38003      if (closestDomain == emailParts.domain) {
38004        // The email address exactly matches one of the supplied domains; do not return a suggestion.
38005        return false;
38006      } else {
38007        // The email address closely matches one of the supplied domains; return a suggestion
38008        return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
38009      }
38010    }
38011
38012    // The email address does not closely match one of the supplied domains
38013    var closestSecondLevelDomain = this.findClosestDomain(emailParts.secondLevelDomain, secondLevelDomains, distanceFunction, this.secondLevelThreshold);
38014    var closestTopLevelDomain    = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold);
38015
38016    if (emailParts.domain) {
38017      var closestDomain = emailParts.domain;
38018      var rtrn = false;
38019
38020      if(closestSecondLevelDomain && closestSecondLevelDomain != emailParts.secondLevelDomain) {
38021        // The email address may have a mispelled second-level domain; return a suggestion
38022        closestDomain = closestDomain.replace(emailParts.secondLevelDomain, closestSecondLevelDomain);
38023        rtrn = true;
38024      }
38025
38026      if(closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
38027        // The email address may have a mispelled top-level domain; return a suggestion
38028        closestDomain = closestDomain.replace(new RegExp(emailParts.topLevelDomain + "$"), closestTopLevelDomain);
38029        rtrn = true;
38030      }
38031
38032      if (rtrn == true) {
38033        return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
38034      }
38035    }
38036
38037    /* The email address exactly matches one of the supplied domains, does not closely
38038     * match any domain and does not appear to simply have a mispelled top-level domain,
38039     * or is an invalid email address; do not return a suggestion.
38040     */
38041    return false;
38042  },
38043
38044  findClosestDomain: function(domain, domains, distanceFunction, threshold) {
38045    threshold = threshold || this.topLevelThreshold;
38046    var dist;
38047    var minDist = Infinity;
38048    var closestDomain = null;
38049
38050    if (!domain || !domains) {
38051      return false;
38052    }
38053    if(!distanceFunction) {
38054      distanceFunction = this.sift3Distance;
38055    }
38056
38057    for (var i = 0; i < domains.length; i++) {
38058      if (domain === domains[i]) {
38059        return domain;
38060      }
38061      dist = distanceFunction(domain, domains[i]);
38062      if (dist < minDist) {
38063        minDist = dist;
38064        closestDomain = domains[i];
38065      }
38066    }
38067
38068    if (minDist <= threshold && closestDomain !== null) {
38069      return closestDomain;
38070    } else {
38071      return false;
38072    }
38073  },
38074
38075  sift3Distance: function(s1, s2) {
38076    // sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
38077    if (s1 == null || s1.length === 0) {
38078      if (s2 == null || s2.length === 0) {
38079        return 0;
38080      } else {
38081        return s2.length;
38082      }
38083    }
38084
38085    if (s2 == null || s2.length === 0) {
38086      return s1.length;
38087    }
38088
38089    var c = 0;
38090    var offset1 = 0;
38091    var offset2 = 0;
38092    var lcs = 0;
38093    var maxOffset = 5;
38094
38095    while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
38096      if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
38097        lcs++;
38098      } else {
38099        offset1 = 0;
38100        offset2 = 0;
38101        for (var i = 0; i < maxOffset; i++) {
38102          if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
38103            offset1 = i;
38104            break;
38105          }
38106          if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
38107            offset2 = i;
38108            break;
38109          }
38110        }
38111      }
38112      c++;
38113    }
38114    return (s1.length + s2.length) /2 - lcs;
38115  },
38116
38117  splitEmail: function(email) {
38118    var parts = email.trim().split('@');
38119
38120    if (parts.length < 2) {
38121      return false;
38122    }
38123
38124    for (var i = 0; i < parts.length; i++) {
38125      if (parts[i] === '') {
38126        return false;
38127      }
38128    }
38129
38130    var domain = parts.pop();
38131    var domainParts = domain.split('.');
38132    var sld = '';
38133    var tld = '';
38134
38135    if (domainParts.length == 0) {
38136      // The address does not have a top-level domain
38137      return false;
38138    } else if (domainParts.length == 1) {
38139      // The address has only a top-level domain (valid under RFC)
38140      tld = domainParts[0];
38141    } else {
38142      // The address has a domain and a top-level domain
38143      sld = domainParts[0];
38144      for (var i = 1; i < domainParts.length; i++) {
38145        tld += domainParts[i] + '.';
38146      }
38147      tld = tld.substring(0, tld.length - 1);
38148    }
38149
38150    return {
38151      topLevelDomain: tld,
38152      secondLevelDomain: sld,
38153      domain: domain,
38154      address: parts.join('@')
38155    }
38156  },
38157
38158  // Encode the email address to prevent XSS but leave in valid
38159  // characters, following this official spec:
38160  // http://en.wikipedia.org/wiki/Email_address#Syntax
38161  encodeEmail: function(email) {
38162    var result = encodeURI(email);
38163    result = result.replace('%20', ' ').replace('%25', '%').replace('%5E', '^')
38164                   .replace('%60', '`').replace('%7B', '{').replace('%7C', '|')
38165                   .replace('%7D', '}');
38166    return result;
38167  }
38168};
38169
38170// Export the mailcheck object if we're in a CommonJS env (e.g. Node).
38171// Modeled off of Underscore.js.
38172if (typeof module !== 'undefined' && module.exports) {
38173    module.exports = Mailcheck;
38174}
38175
38176// Support AMD style definitions
38177// Based on jQuery (see http://stackoverflow.com/a/17954882/1322410)
38178if (typeof define === "function" && define.amd) {
38179  define("mailcheck", [], function() {
38180    return Mailcheck;
38181  });
38182}
38183
38184if (typeof window !== 'undefined' && window.jQuery) {
38185  (function($){
38186    $.fn.mailcheck = function(opts) {
38187      var self = this;
38188      if (opts.suggested) {
38189        var oldSuggested = opts.suggested;
38190        opts.suggested = function(result) {
38191          oldSuggested(self, result);
38192        };
38193      }
38194
38195      if (opts.empty) {
38196        var oldEmpty = opts.empty;
38197        opts.empty = function() {
38198          oldEmpty.call(null, self);
38199        };
38200      }
38201
38202      opts.email = this.val();
38203      Mailcheck.run(opts);
38204    }
38205  })(jQuery);
38206};
38207//! moment.js
38208//! version : 2.18.1
38209//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
38210//! license : MIT
38211//! momentjs.com
38212
38213;(function (global, factory) {
38214    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
38215    typeof define === 'function' && define.amd ? define(factory) :
38216    global.moment = factory()
38217}(this, (function () { 'use strict';
38218
38219var hookCallback;
38220
38221function hooks () {
38222    return hookCallback.apply(null, arguments);
38223}
38224
38225// This is done to register the method called with moment()
38226// without creating circular dependencies.
38227function setHookCallback (callback) {
38228    hookCallback = callback;
38229}
38230
38231function isArray(input) {
38232    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
38233}
38234
38235function isObject(input) {
38236    // IE8 will treat undefined and null as object if it wasn't for
38237    // input != null
38238    return input != null && Object.prototype.toString.call(input) === '[object Object]';
38239}
38240
38241function isObjectEmpty(obj) {
38242    var k;
38243    for (k in obj) {
38244        // even if its not own property I'd still call it non-empty
38245        return false;
38246    }
38247    return true;
38248}
38249
38250function isUndefined(input) {
38251    return input === void 0;
38252}
38253
38254function isNumber(input) {
38255    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
38256}
38257
38258function isDate(input) {
38259    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
38260}
38261
38262function map(arr, fn) {
38263    var res = [], i;
38264    for (i = 0; i < arr.length; ++i) {
38265        res.push(fn(arr[i], i));
38266    }
38267    return res;
38268}
38269
38270function hasOwnProp(a, b) {
38271    return Object.prototype.hasOwnProperty.call(a, b);
38272}
38273
38274function extend(a, b) {
38275    for (var i in b) {
38276        if (hasOwnProp(b, i)) {
38277            a[i] = b[i];
38278        }
38279    }
38280
38281    if (hasOwnProp(b, 'toString')) {
38282        a.toString = b.toString;
38283    }
38284
38285    if (hasOwnProp(b, 'valueOf')) {
38286        a.valueOf = b.valueOf;
38287    }
38288
38289    return a;
38290}
38291
38292function createUTC (input, format, locale, strict) {
vendor: 9,650 bytes, lines 38293-38660
38293    return createLocalOrUTC(input, format, locale, strict, true).utc();
38294}
38295
38296function defaultParsingFlags() {
38297    // We need to deep clone this object.
38298    return {
38299        empty           : false,
38300        unusedTokens    : [],
38301        unusedInput     : [],
38302        overflow        : -2,
38303        charsLeftOver   : 0,
38304        nullInput       : false,
38305        invalidMonth    : null,
38306        invalidFormat   : false,
38307        userInvalidated : false,
38308        iso             : false,
38309        parsedDateParts : [],
38310        meridiem        : null,
38311        rfc2822         : false,
38312        weekdayMismatch : false
38313    };
38314}
38315
38316function getParsingFlags(m) {
38317    if (m._pf == null) {
38318        m._pf = defaultParsingFlags();
38319    }
38320    return m._pf;
38321}
38322
38323var some;
38324if (Array.prototype.some) {
38325    some = Array.prototype.some;
38326} else {
38327    some = function (fun) {
38328        var t = Object(this);
38329        var len = t.length >>> 0;
38330
38331        for (var i = 0; i < len; i++) {
38332            if (i in t && fun.call(this, t[i], i, t)) {
38333                return true;
38334            }
38335        }
38336
38337        return false;
38338    };
38339}
38340
38341var some$1 = some;
38342
38343function isValid(m) {
38344    if (m._isValid == null) {
38345        var flags = getParsingFlags(m);
38346        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {
38347            return i != null;
38348        });
38349        var isNowValid = !isNaN(m._d.getTime()) &&
38350            flags.overflow < 0 &&
38351            !flags.empty &&
38352            !flags.invalidMonth &&
38353            !flags.invalidWeekday &&
38354            !flags.nullInput &&
38355            !flags.invalidFormat &&
38356            !flags.userInvalidated &&
38357            (!flags.meridiem || (flags.meridiem && parsedParts));
38358
38359        if (m._strict) {
38360            isNowValid = isNowValid &&
38361                flags.charsLeftOver === 0 &&
38362                flags.unusedTokens.length === 0 &&
38363                flags.bigHour === undefined;
38364        }
38365
38366        if (Object.isFrozen == null || !Object.isFrozen(m)) {
38367            m._isValid = isNowValid;
38368        }
38369        else {
38370            return isNowValid;
38371        }
38372    }
38373    return m._isValid;
38374}
38375
38376function createInvalid (flags) {
38377    var m = createUTC(NaN);
38378    if (flags != null) {
38379        extend(getParsingFlags(m), flags);
38380    }
38381    else {
38382        getParsingFlags(m).userInvalidated = true;
38383    }
38384
38385    return m;
38386}
38387
38388// Plugins that add properties should also add the key here (null value),
38389// so we can properly clone ourselves.
38390var momentProperties = hooks.momentProperties = [];
38391
38392function copyConfig(to, from) {
38393    var i, prop, val;
38394
38395    if (!isUndefined(from._isAMomentObject)) {
38396        to._isAMomentObject = from._isAMomentObject;
38397    }
38398    if (!isUndefined(from._i)) {
38399        to._i = from._i;
38400    }
38401    if (!isUndefined(from._f)) {
38402        to._f = from._f;
38403    }
38404    if (!isUndefined(from._l)) {
38405        to._l = from._l;
38406    }
38407    if (!isUndefined(from._strict)) {
38408        to._strict = from._strict;
38409    }
38410    if (!isUndefined(from._tzm)) {
38411        to._tzm = from._tzm;
38412    }
38413    if (!isUndefined(from._isUTC)) {
38414        to._isUTC = from._isUTC;
38415    }
38416    if (!isUndefined(from._offset)) {
38417        to._offset = from._offset;
38418    }
38419    if (!isUndefined(from._pf)) {
38420        to._pf = getParsingFlags(from);
38421    }
38422    if (!isUndefined(from._locale)) {
38423        to._locale = from._locale;
38424    }
38425
38426    if (momentProperties.length > 0) {
38427        for (i = 0; i < momentProperties.length; i++) {
38428            prop = momentProperties[i];
38429            val = from[prop];
38430            if (!isUndefined(val)) {
38431                to[prop] = val;
38432            }
38433        }
38434    }
38435
38436    return to;
38437}
38438
38439var updateInProgress = false;
38440
38441// Moment prototype object
38442function Moment(config) {
38443    copyConfig(this, config);
38444    this._d = new Date(config._d != null ? config._d.getTime() : NaN);
38445    if (!this.isValid()) {
38446        this._d = new Date(NaN);
38447    }
38448    // Prevent infinite loop in case updateOffset creates new moment
38449    // objects.
38450    if (updateInProgress === false) {
38451        updateInProgress = true;
38452        hooks.updateOffset(this);
38453        updateInProgress = false;
38454    }
38455}
38456
38457function isMoment (obj) {
38458    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
38459}
38460
38461function absFloor (number) {
38462    if (number < 0) {
38463        // -0 -> 0
38464        return Math.ceil(number) || 0;
38465    } else {
38466        return Math.floor(number);
38467    }
38468}
38469
38470function toInt(argumentForCoercion) {
38471    var coercedNumber = +argumentForCoercion,
38472        value = 0;
38473
38474    if (coercedNumber !== 0 && isFinite(coercedNumber)) {
38475        value = absFloor(coercedNumber);
38476    }
38477
38478    return value;
38479}
38480
38481// compare two arrays, return the number of differences
38482function compareArrays(array1, array2, dontConvert) {
38483    var len = Math.min(array1.length, array2.length),
38484        lengthDiff = Math.abs(array1.length - array2.length),
38485        diffs = 0,
38486        i;
38487    for (i = 0; i < len; i++) {
38488        if ((dontConvert && array1[i] !== array2[i]) ||
38489            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
38490            diffs++;
38491        }
38492    }
38493    return diffs + lengthDiff;
38494}
38495
38496function warn(msg) {
38497    if (hooks.suppressDeprecationWarnings === false &&
38498            (typeof console !==  'undefined') && console.warn) {
38499        console.warn('Deprecation warning: ' + msg);
38500    }
38501}
38502
38503function deprecate(msg, fn) {
38504    var firstTime = true;
38505
38506    return extend(function () {
38507        if (hooks.deprecationHandler != null) {
38508            hooks.deprecationHandler(null, msg);
38509        }
38510        if (firstTime) {
38511            var args = [];
38512            var arg;
38513            for (var i = 0; i < arguments.length; i++) {
38514                arg = '';
38515                if (typeof arguments[i] === 'object') {
38516                    arg += '\n[' + i + '] ';
38517                    for (var key in arguments[0]) {
38518                        arg += key + ': ' + arguments[0][key] + ', ';
38519                    }
38520                    arg = arg.slice(0, -2); // Remove trailing comma and space
38521                } else {
38522                    arg = arguments[i];
38523                }
38524                args.push(arg);
38525            }
38526            warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
38527            firstTime = false;
38528        }
38529        return fn.apply(this, arguments);
38530    }, fn);
38531}
38532
38533var deprecations = {};
38534
38535function deprecateSimple(name, msg) {
38536    if (hooks.deprecationHandler != null) {
38537        hooks.deprecationHandler(name, msg);
38538    }
38539    if (!deprecations[name]) {
38540        warn(msg);
38541        deprecations[name] = true;
38542    }
38543}
38544
38545hooks.suppressDeprecationWarnings = false;
38546hooks.deprecationHandler = null;
38547
38548function isFunction(input) {
38549    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
38550}
38551
38552function set (config) {
38553    var prop, i;
38554    for (i in config) {
38555        prop = config[i];
38556        if (isFunction(prop)) {
38557            this[i] = prop;
38558        } else {
38559            this['_' + i] = prop;
38560        }
38561    }
38562    this._config = config;
38563    // Lenient ordinal parsing accepts just a number in addition to
38564    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
38565    // TODO: Remove "ordinalParse" fallback in next major release.
38566    this._dayOfMonthOrdinalParseLenient = new RegExp(
38567        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
38568            '|' + (/\d{1,2}/).source);
38569}
38570
38571function mergeConfigs(parentConfig, childConfig) {
38572    var res = extend({}, parentConfig), prop;
38573    for (prop in childConfig) {
38574        if (hasOwnProp(childConfig, prop)) {
38575            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
38576                res[prop] = {};
38577                extend(res[prop], parentConfig[prop]);
38578                extend(res[prop], childConfig[prop]);
38579            } else if (childConfig[prop] != null) {
38580                res[prop] = childConfig[prop];
38581            } else {
38582                delete res[prop];
38583            }
38584        }
38585    }
38586    for (prop in parentConfig) {
38587        if (hasOwnProp(parentConfig, prop) &&
38588                !hasOwnProp(childConfig, prop) &&
38589                isObject(parentConfig[prop])) {
38590            // make sure changes to properties don't modify parent config
38591            res[prop] = extend({}, res[prop]);
38592        }
38593    }
38594    return res;
38595}
38596
38597function Locale(config) {
38598    if (config != null) {
38599        this.set(config);
38600    }
38601}
38602
38603var keys;
38604
38605if (Object.keys) {
38606    keys = Object.keys;
38607} else {
38608    keys = function (obj) {
38609        var i, res = [];
38610        for (i in obj) {
38611            if (hasOwnProp(obj, i)) {
38612                res.push(i);
38613            }
38614        }
38615        return res;
38616    };
38617}
38618
38619var keys$1 = keys;
38620
38621var defaultCalendar = {
38622    sameDay : '[Today at] LT',
38623    nextDay : '[Tomorrow at] LT',
38624    nextWeek : 'dddd [at] LT',
38625    lastDay : '[Yesterday at] LT',
38626    lastWeek : '[Last] dddd [at] LT',
38627    sameElse : 'L'
38628};
38629
38630function calendar (key, mom, now) {
38631    var output = this._calendar[key] || this._calendar['sameElse'];
38632    return isFunction(output) ? output.call(mom, now) : output;
38633}
38634
38635var defaultLongDateFormat = {
38636    LTS  : 'h:mm:ss A',
38637    LT   : 'h:mm A',
38638    L    : 'MM/DD/YYYY',
38639    LL   : 'MMMM D, YYYY',
38640    LLL  : 'MMMM D, YYYY h:mm A',
38641    LLLL : 'dddd, MMMM D, YYYY h:mm A'
38642};
38643
38644function longDateFormat (key) {
38645    var format = this._longDateFormat[key],
38646        formatUpper = this._longDateFormat[key.toUpperCase()];
38647
38648    if (format || !formatUpper) {
38649        return format;
38650    }
38651
38652    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
38653        return val.slice(1);
38654    });
38655
38656    return this._longDateFormat[key];
38657}
38658
38659var defaultInvalidDate = 'Invalid date';
38660
vendor: 10,397 bytes, lines 38661-39046
38661function invalidDate () {
38662    return this._invalidDate;
38663}
38664
38665var defaultOrdinal = '%d';
38666var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
38667
38668function ordinal (number) {
38669    return this._ordinal.replace('%d', number);
38670}
38671
38672var defaultRelativeTime = {
38673    future : 'in %s',
38674    past   : '%s ago',
38675    s  : 'a few seconds',
38676    ss : '%d seconds',
38677    m  : 'a minute',
38678    mm : '%d minutes',
38679    h  : 'an hour',
38680    hh : '%d hours',
38681    d  : 'a day',
38682    dd : '%d days',
38683    M  : 'a month',
38684    MM : '%d months',
38685    y  : 'a year',
38686    yy : '%d years'
38687};
38688
38689function relativeTime (number, withoutSuffix, string, isFuture) {
38690    var output = this._relativeTime[string];
38691    return (isFunction(output)) ?
38692        output(number, withoutSuffix, string, isFuture) :
38693        output.replace(/%d/i, number);
38694}
38695
38696function pastFuture (diff, output) {
38697    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
38698    return isFunction(format) ? format(output) : format.replace(/%s/i, output);
38699}
38700
38701var aliases = {};
38702
38703function addUnitAlias (unit, shorthand) {
38704    var lowerCase = unit.toLowerCase();
38705    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
38706}
38707
38708function normalizeUnits(units) {
38709    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
38710}
38711
38712function normalizeObjectUnits(inputObject) {
38713    var normalizedInput = {},
38714        normalizedProp,
38715        prop;
38716
38717    for (prop in inputObject) {
38718        if (hasOwnProp(inputObject, prop)) {
38719            normalizedProp = normalizeUnits(prop);
38720            if (normalizedProp) {
38721                normalizedInput[normalizedProp] = inputObject[prop];
38722            }
38723        }
38724    }
38725
38726    return normalizedInput;
38727}
38728
38729var priorities = {};
38730
38731function addUnitPriority(unit, priority) {
38732    priorities[unit] = priority;
38733}
38734
38735function getPrioritizedUnits(unitsObj) {
38736    var units = [];
38737    for (var u in unitsObj) {
38738        units.push({unit: u, priority: priorities[u]});
38739    }
38740    units.sort(function (a, b) {
38741        return a.priority - b.priority;
38742    });
38743    return units;
38744}
38745
38746function makeGetSet (unit, keepTime) {
38747    return function (value) {
38748        if (value != null) {
38749            set$1(this, unit, value);
38750            hooks.updateOffset(this, keepTime);
38751            return this;
38752        } else {
38753            return get(this, unit);
38754        }
38755    };
38756}
38757
38758function get (mom, unit) {
38759    return mom.isValid() ?
38760        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
38761}
38762
38763function set$1 (mom, unit, value) {
38764    if (mom.isValid()) {
38765        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
38766    }
38767}
38768
38769// MOMENTS
38770
38771function stringGet (units) {
38772    units = normalizeUnits(units);
38773    if (isFunction(this[units])) {
38774        return this[units]();
38775    }
38776    return this;
38777}
38778
38779
38780function stringSet (units, value) {
38781    if (typeof units === 'object') {
38782        units = normalizeObjectUnits(units);
38783        var prioritized = getPrioritizedUnits(units);
38784        for (var i = 0; i < prioritized.length; i++) {
38785            this[prioritized[i].unit](units[prioritized[i].unit]);
38786        }
38787    } else {
38788        units = normalizeUnits(units);
38789        if (isFunction(this[units])) {
38790            return this[units](value);
38791        }
38792    }
38793    return this;
38794}
38795
38796function zeroFill(number, targetLength, forceSign) {
38797    var absNumber = '' + Math.abs(number),
38798        zerosToFill = targetLength - absNumber.length,
38799        sign = number >= 0;
38800    return (sign ? (forceSign ? '+' : '') : '-') +
38801        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
38802}
38803
38804var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
38805
38806var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
38807
38808var formatFunctions = {};
38809
38810var formatTokenFunctions = {};
38811
38812// token:    'M'
38813// padded:   ['MM', 2]
38814// ordinal:  'Mo'
38815// callback: function () { this.month() + 1 }
38816function addFormatToken (token, padded, ordinal, callback) {
38817    var func = callback;
38818    if (typeof callback === 'string') {
38819        func = function () {
38820            return this[callback]();
38821        };
38822    }
38823    if (token) {
38824        formatTokenFunctions[token] = func;
38825    }
38826    if (padded) {
38827        formatTokenFunctions[padded[0]] = function () {
38828            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
38829        };
38830    }
38831    if (ordinal) {
38832        formatTokenFunctions[ordinal] = function () {
38833            return this.localeData().ordinal(func.apply(this, arguments), token);
38834        };
38835    }
38836}
38837
38838function removeFormattingTokens(input) {
38839    if (input.match(/\[[\s\S]/)) {
38840        return input.replace(/^\[|\]$/g, '');
38841    }
38842    return input.replace(/\\/g, '');
38843}
38844
38845function makeFormatFunction(format) {
38846    var array = format.match(formattingTokens), i, length;
38847
38848    for (i = 0, length = array.length; i < length; i++) {
38849        if (formatTokenFunctions[array[i]]) {
38850            array[i] = formatTokenFunctions[array[i]];
38851        } else {
38852            array[i] = removeFormattingTokens(array[i]);
38853        }
38854    }
38855
38856    return function (mom) {
38857        var output = '', i;
38858        for (i = 0; i < length; i++) {
38859            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
38860        }
38861        return output;
38862    };
38863}
38864
38865// format date using native date object
38866function formatMoment(m, format) {
38867    if (!m.isValid()) {
38868        return m.localeData().invalidDate();
38869    }
38870
38871    format = expandFormat(format, m.localeData());
38872    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
38873
38874    return formatFunctions[format](m);
38875}
38876
38877function expandFormat(format, locale) {
38878    var i = 5;
38879
38880    function replaceLongDateFormatTokens(input) {
38881        return locale.longDateFormat(input) || input;
38882    }
38883
38884    localFormattingTokens.lastIndex = 0;
38885    while (i >= 0 && localFormattingTokens.test(format)) {
38886        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
38887        localFormattingTokens.lastIndex = 0;
38888        i -= 1;
38889    }
38890
38891    return format;
38892}
38893
38894var match1         = /\d/;            //       0 - 9
38895var match2         = /\d\d/;          //      00 - 99
38896var match3         = /\d{3}/;         //     000 - 999
38897var match4         = /\d{4}/;         //    0000 - 9999
38898var match6         = /[+-]?\d{6}/;    // -999999 - 999999
38899var match1to2      = /\d\d?/;         //       0 - 99
38900var match3to4      = /\d\d\d\d?/;     //     999 - 9999
38901var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
38902var match1to3      = /\d{1,3}/;       //       0 - 999
38903var match1to4      = /\d{1,4}/;       //       0 - 9999
38904var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
38905
38906var matchUnsigned  = /\d+/;           //       0 - inf
38907var matchSigned    = /[+-]?\d+/;      //    -inf - inf
38908
38909var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
38910var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
38911
38912var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
38913
38914// any word (or two) characters or numbers including two/three word month in arabic.
38915// includes scottish gaelic two word and hyphenated months
38916var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
38917
38918
38919var regexes = {};
38920
38921function addRegexToken (token, regex, strictRegex) {
38922    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
38923        return (isStrict && strictRegex) ? strictRegex : regex;
38924    };
38925}
38926
38927function getParseRegexForToken (token, config) {
38928    if (!hasOwnProp(regexes, token)) {
38929        return new RegExp(unescapeFormat(token));
38930    }
38931
38932    return regexes[token](config._strict, config._locale);
38933}
38934
38935// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
38936function unescapeFormat(s) {
38937    return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
38938        return p1 || p2 || p3 || p4;
38939    }));
38940}
38941
38942function regexEscape(s) {
38943    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
38944}
38945
38946var tokens = {};
38947
38948function addParseToken (token, callback) {
38949    var i, func = callback;
38950    if (typeof token === 'string') {
38951        token = [token];
38952    }
38953    if (isNumber(callback)) {
38954        func = function (input, array) {
38955            array[callback] = toInt(input);
38956        };
38957    }
38958    for (i = 0; i < token.length; i++) {
38959        tokens[token[i]] = func;
38960    }
38961}
38962
38963function addWeekParseToken (token, callback) {
38964    addParseToken(token, function (input, array, config, token) {
38965        config._w = config._w || {};
38966        callback(input, config._w, config, token);
38967    });
38968}
38969
38970function addTimeToArrayFromToken(token, input, config) {
38971    if (input != null && hasOwnProp(tokens, token)) {
38972        tokens[token](input, config._a, config, token);
38973    }
38974}
38975
38976var YEAR = 0;
38977var MONTH = 1;
38978var DATE = 2;
38979var HOUR = 3;
38980var MINUTE = 4;
38981var SECOND = 5;
38982var MILLISECOND = 6;
38983var WEEK = 7;
38984var WEEKDAY = 8;
38985
38986var indexOf;
38987
38988if (Array.prototype.indexOf) {
38989    indexOf = Array.prototype.indexOf;
38990} else {
38991    indexOf = function (o) {
38992        // I know
38993        var i;
38994        for (i = 0; i < this.length; ++i) {
38995            if (this[i] === o) {
38996                return i;
38997            }
38998        }
38999        return -1;
39000    };
39001}
39002
39003var indexOf$1 = indexOf;
39004
39005function daysInMonth(year, month) {
39006    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
39007}
39008
39009// FORMATTING
39010
39011addFormatToken('M', ['MM', 2], 'Mo', function () {
39012    return this.month() + 1;
39013});
39014
39015addFormatToken('MMM', 0, 0, function (format) {
39016    return this.localeData().monthsShort(this, format);
39017});
39018
39019addFormatToken('MMMM', 0, 0, function (format) {
39020    return this.localeData().months(this, format);
39021});
39022
39023// ALIASES
39024
39025addUnitAlias('month', 'M');
39026
39027// PRIORITY
39028
39029addUnitPriority('month', 8);
39030
39031// PARSING
39032
39033addRegexToken('M',    match1to2);
39034addRegexToken('MM',   match1to2, match2);
39035addRegexToken('MMM',  function (isStrict, locale) {
39036    return locale.monthsShortRegex(isStrict);
39037});
39038addRegexToken('MMMM', function (isStrict, locale) {
39039    return locale.monthsRegex(isStrict);
39040});
39041
39042addParseToken(['M', 'MM'], function (input, array) {
39043    array[MONTH] = toInt(input) - 1;
39044});
39045
39046addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
vendor: 25,600 bytes, lines 39047-39897
39047    var month = config._locale.monthsParse(input, token, config._strict);
39048    // if we didn't find a month name, mark the date as invalid.
39049    if (month != null) {
39050        array[MONTH] = month;
39051    } else {
39052        getParsingFlags(config).invalidMonth = input;
39053    }
39054});
39055
39056// LOCALES
39057
39058var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
39059var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
39060function localeMonths (m, format) {
39061    if (!m) {
39062        return isArray(this._months) ? this._months :
39063            this._months['standalone'];
39064    }
39065    return isArray(this._months) ? this._months[m.month()] :
39066        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
39067}
39068
39069var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
39070function localeMonthsShort (m, format) {
39071    if (!m) {
39072        return isArray(this._monthsShort) ? this._monthsShort :
39073            this._monthsShort['standalone'];
39074    }
39075    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
39076        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
39077}
39078
39079function handleStrictParse(monthName, format, strict) {
39080    var i, ii, mom, llc = monthName.toLocaleLowerCase();
39081    if (!this._monthsParse) {
39082        // this is not used
39083        this._monthsParse = [];
39084        this._longMonthsParse = [];
39085        this._shortMonthsParse = [];
39086        for (i = 0; i < 12; ++i) {
39087            mom = createUTC([2000, i]);
39088            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
39089            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
39090        }
39091    }
39092
39093    if (strict) {
39094        if (format === 'MMM') {
39095            ii = indexOf$1.call(this._shortMonthsParse, llc);
39096            return ii !== -1 ? ii : null;
39097        } else {
39098            ii = indexOf$1.call(this._longMonthsParse, llc);
39099            return ii !== -1 ? ii : null;
39100        }
39101    } else {
39102        if (format === 'MMM') {
39103            ii = indexOf$1.call(this._shortMonthsParse, llc);
39104            if (ii !== -1) {
39105                return ii;
39106            }
39107            ii = indexOf$1.call(this._longMonthsParse, llc);
39108            return ii !== -1 ? ii : null;
39109        } else {
39110            ii = indexOf$1.call(this._longMonthsParse, llc);
39111            if (ii !== -1) {
39112                return ii;
39113            }
39114            ii = indexOf$1.call(this._shortMonthsParse, llc);
39115            return ii !== -1 ? ii : null;
39116        }
39117    }
39118}
39119
39120function localeMonthsParse (monthName, format, strict) {
39121    var i, mom, regex;
39122
39123    if (this._monthsParseExact) {
39124        return handleStrictParse.call(this, monthName, format, strict);
39125    }
39126
39127    if (!this._monthsParse) {
39128        this._monthsParse = [];
39129        this._longMonthsParse = [];
39130        this._shortMonthsParse = [];
39131    }
39132
39133    // TODO: add sorting
39134    // Sorting makes sure if one month (or abbr) is a prefix of another
39135    // see sorting in computeMonthsParse
39136    for (i = 0; i < 12; i++) {
39137        // make the regex if we don't have it already
39138        mom = createUTC([2000, i]);
39139        if (strict && !this._longMonthsParse[i]) {
39140            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
39141            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
39142        }
39143        if (!strict && !this._monthsParse[i]) {
39144            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
39145            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
39146        }
39147        // test the regex
39148        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
39149            return i;
39150        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
39151            return i;
39152        } else if (!strict && this._monthsParse[i].test(monthName)) {
39153            return i;
39154        }
39155    }
39156}
39157
39158// MOMENTS
39159
39160function setMonth (mom, value) {
39161    var dayOfMonth;
39162
39163    if (!mom.isValid()) {
39164        // No op
39165        return mom;
39166    }
39167
39168    if (typeof value === 'string') {
39169        if (/^\d+$/.test(value)) {
39170            value = toInt(value);
39171        } else {
39172            value = mom.localeData().monthsParse(value);
39173            // TODO: Another silent failure?
39174            if (!isNumber(value)) {
39175                return mom;
39176            }
39177        }
39178    }
39179
39180    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
39181    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
39182    return mom;
39183}
39184
39185function getSetMonth (value) {
39186    if (value != null) {
39187        setMonth(this, value);
39188        hooks.updateOffset(this, true);
39189        return this;
39190    } else {
39191        return get(this, 'Month');
39192    }
39193}
39194
39195function getDaysInMonth () {
39196    return daysInMonth(this.year(), this.month());
39197}
39198
39199var defaultMonthsShortRegex = matchWord;
39200function monthsShortRegex (isStrict) {
39201    if (this._monthsParseExact) {
39202        if (!hasOwnProp(this, '_monthsRegex')) {
39203            computeMonthsParse.call(this);
39204        }
39205        if (isStrict) {
39206            return this._monthsShortStrictRegex;
39207        } else {
39208            return this._monthsShortRegex;
39209        }
39210    } else {
39211        if (!hasOwnProp(this, '_monthsShortRegex')) {
39212            this._monthsShortRegex = defaultMonthsShortRegex;
39213        }
39214        return this._monthsShortStrictRegex && isStrict ?
39215            this._monthsShortStrictRegex : this._monthsShortRegex;
39216    }
39217}
39218
39219var defaultMonthsRegex = matchWord;
39220function monthsRegex (isStrict) {
39221    if (this._monthsParseExact) {
39222        if (!hasOwnProp(this, '_monthsRegex')) {
39223            computeMonthsParse.call(this);
39224        }
39225        if (isStrict) {
39226            return this._monthsStrictRegex;
39227        } else {
39228            return this._monthsRegex;
39229        }
39230    } else {
39231        if (!hasOwnProp(this, '_monthsRegex')) {
39232            this._monthsRegex = defaultMonthsRegex;
39233        }
39234        return this._monthsStrictRegex && isStrict ?
39235            this._monthsStrictRegex : this._monthsRegex;
39236    }
39237}
39238
39239function computeMonthsParse () {
39240    function cmpLenRev(a, b) {
39241        return b.length - a.length;
39242    }
39243
39244    var shortPieces = [], longPieces = [], mixedPieces = [],
39245        i, mom;
39246    for (i = 0; i < 12; i++) {
39247        // make the regex if we don't have it already
39248        mom = createUTC([2000, i]);
39249        shortPieces.push(this.monthsShort(mom, ''));
39250        longPieces.push(this.months(mom, ''));
39251        mixedPieces.push(this.months(mom, ''));
39252        mixedPieces.push(this.monthsShort(mom, ''));
39253    }
39254    // Sorting makes sure if one month (or abbr) is a prefix of another it
39255    // will match the longer piece.
39256    shortPieces.sort(cmpLenRev);
39257    longPieces.sort(cmpLenRev);
39258    mixedPieces.sort(cmpLenRev);
39259    for (i = 0; i < 12; i++) {
39260        shortPieces[i] = regexEscape(shortPieces[i]);
39261        longPieces[i] = regexEscape(longPieces[i]);
39262    }
39263    for (i = 0; i < 24; i++) {
39264        mixedPieces[i] = regexEscape(mixedPieces[i]);
39265    }
39266
39267    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
39268    this._monthsShortRegex = this._monthsRegex;
39269    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
39270    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
39271}
39272
39273// FORMATTING
39274
39275addFormatToken('Y', 0, 0, function () {
39276    var y = this.year();
39277    return y <= 9999 ? '' + y : '+' + y;
39278});
39279
39280addFormatToken(0, ['YY', 2], 0, function () {
39281    return this.year() % 100;
39282});
39283
39284addFormatToken(0, ['YYYY',   4],       0, 'year');
39285addFormatToken(0, ['YYYYY',  5],       0, 'year');
39286addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
39287
39288// ALIASES
39289
39290addUnitAlias('year', 'y');
39291
39292// PRIORITIES
39293
39294addUnitPriority('year', 1);
39295
39296// PARSING
39297
39298addRegexToken('Y',      matchSigned);
39299addRegexToken('YY',     match1to2, match2);
39300addRegexToken('YYYY',   match1to4, match4);
39301addRegexToken('YYYYY',  match1to6, match6);
39302addRegexToken('YYYYYY', match1to6, match6);
39303
39304addParseToken(['YYYYY', 'YYYYYY'], YEAR);
39305addParseToken('YYYY', function (input, array) {
39306    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
39307});
39308addParseToken('YY', function (input, array) {
39309    array[YEAR] = hooks.parseTwoDigitYear(input);
39310});
39311addParseToken('Y', function (input, array) {
39312    array[YEAR] = parseInt(input, 10);
39313});
39314
39315// HELPERS
39316
39317function daysInYear(year) {
39318    return isLeapYear(year) ? 366 : 365;
39319}
39320
39321function isLeapYear(year) {
39322    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
39323}
39324
39325// HOOKS
39326
39327hooks.parseTwoDigitYear = function (input) {
39328    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
39329};
39330
39331// MOMENTS
39332
39333var getSetYear = makeGetSet('FullYear', true);
39334
39335function getIsLeapYear () {
39336    return isLeapYear(this.year());
39337}
39338
39339function createDate (y, m, d, h, M, s, ms) {
39340    // can't just apply() to create a date:
39341    // https://stackoverflow.com/q/181348
39342    var date = new Date(y, m, d, h, M, s, ms);
39343
39344    // the date constructor remaps years 0-99 to 1900-1999
39345    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
39346        date.setFullYear(y);
39347    }
39348    return date;
39349}
39350
39351function createUTCDate (y) {
39352    var date = new Date(Date.UTC.apply(null, arguments));
39353
39354    // the Date.UTC function remaps years 0-99 to 1900-1999
39355    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
39356        date.setUTCFullYear(y);
39357    }
39358    return date;
39359}
39360
39361// start-of-first-week - start-of-year
39362function firstWeekOffset(year, dow, doy) {
39363    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
39364        fwd = 7 + dow - doy,
39365        // first-week day local weekday -- which local weekday is fwd
39366        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
39367
39368    return -fwdlw + fwd - 1;
39369}
39370
39371// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
39372function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
39373    var localWeekday = (7 + weekday - dow) % 7,
39374        weekOffset = firstWeekOffset(year, dow, doy),
39375        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
39376        resYear, resDayOfYear;
39377
39378    if (dayOfYear <= 0) {
39379        resYear = year - 1;
39380        resDayOfYear = daysInYear(resYear) + dayOfYear;
39381    } else if (dayOfYear > daysInYear(year)) {
39382        resYear = year + 1;
39383        resDayOfYear = dayOfYear - daysInYear(year);
39384    } else {
39385        resYear = year;
39386        resDayOfYear = dayOfYear;
39387    }
39388
39389    return {
39390        year: resYear,
39391        dayOfYear: resDayOfYear
39392    };
39393}
39394
39395function weekOfYear(mom, dow, doy) {
39396    var weekOffset = firstWeekOffset(mom.year(), dow, doy),
39397        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
39398        resWeek, resYear;
39399
39400    if (week < 1) {
39401        resYear = mom.year() - 1;
39402        resWeek = week + weeksInYear(resYear, dow, doy);
39403    } else if (week > weeksInYear(mom.year(), dow, doy)) {
39404        resWeek = week - weeksInYear(mom.year(), dow, doy);
39405        resYear = mom.year() + 1;
39406    } else {
39407        resYear = mom.year();
39408        resWeek = week;
39409    }
39410
39411    return {
39412        week: resWeek,
39413        year: resYear
39414    };
39415}
39416
39417function weeksInYear(year, dow, doy) {
39418    var weekOffset = firstWeekOffset(year, dow, doy),
39419        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
39420    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
39421}
39422
39423// FORMATTING
39424
39425addFormatToken('w', ['ww', 2], 'wo', 'week');
39426addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
39427
39428// ALIASES
39429
39430addUnitAlias('week', 'w');
39431addUnitAlias('isoWeek', 'W');
39432
39433// PRIORITIES
39434
39435addUnitPriority('week', 5);
39436addUnitPriority('isoWeek', 5);
39437
39438// PARSING
39439
39440addRegexToken('w',  match1to2);
39441addRegexToken('ww', match1to2, match2);
39442addRegexToken('W',  match1to2);
39443addRegexToken('WW', match1to2, match2);
39444
39445addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
39446    week[token.substr(0, 1)] = toInt(input);
39447});
39448
39449// HELPERS
39450
39451// LOCALES
39452
39453function localeWeek (mom) {
39454    return weekOfYear(mom, this._week.dow, this._week.doy).week;
39455}
39456
39457var defaultLocaleWeek = {
39458    dow : 0, // Sunday is the first day of the week.
39459    doy : 6  // The week that contains Jan 1st is the first week of the year.
39460};
39461
39462function localeFirstDayOfWeek () {
39463    return this._week.dow;
39464}
39465
39466function localeFirstDayOfYear () {
39467    return this._week.doy;
39468}
39469
39470// MOMENTS
39471
39472function getSetWeek (input) {
39473    var week = this.localeData().week(this);
39474    return input == null ? week : this.add((input - week) * 7, 'd');
39475}
39476
39477function getSetISOWeek (input) {
39478    var week = weekOfYear(this, 1, 4).week;
39479    return input == null ? week : this.add((input - week) * 7, 'd');
39480}
39481
39482// FORMATTING
39483
39484addFormatToken('d', 0, 'do', 'day');
39485
39486addFormatToken('dd', 0, 0, function (format) {
39487    return this.localeData().weekdaysMin(this, format);
39488});
39489
39490addFormatToken('ddd', 0, 0, function (format) {
39491    return this.localeData().weekdaysShort(this, format);
39492});
39493
39494addFormatToken('dddd', 0, 0, function (format) {
39495    return this.localeData().weekdays(this, format);
39496});
39497
39498addFormatToken('e', 0, 0, 'weekday');
39499addFormatToken('E', 0, 0, 'isoWeekday');
39500
39501// ALIASES
39502
39503addUnitAlias('day', 'd');
39504addUnitAlias('weekday', 'e');
39505addUnitAlias('isoWeekday', 'E');
39506
39507// PRIORITY
39508addUnitPriority('day', 11);
39509addUnitPriority('weekday', 11);
39510addUnitPriority('isoWeekday', 11);
39511
39512// PARSING
39513
39514addRegexToken('d',    match1to2);
39515addRegexToken('e',    match1to2);
39516addRegexToken('E',    match1to2);
39517addRegexToken('dd',   function (isStrict, locale) {
39518    return locale.weekdaysMinRegex(isStrict);
39519});
39520addRegexToken('ddd',   function (isStrict, locale) {
39521    return locale.weekdaysShortRegex(isStrict);
39522});
39523addRegexToken('dddd',   function (isStrict, locale) {
39524    return locale.weekdaysRegex(isStrict);
39525});
39526
39527addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
39528    var weekday = config._locale.weekdaysParse(input, token, config._strict);
39529    // if we didn't get a weekday name, mark the date as invalid
39530    if (weekday != null) {
39531        week.d = weekday;
39532    } else {
39533        getParsingFlags(config).invalidWeekday = input;
39534    }
39535});
39536
39537addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
39538    week[token] = toInt(input);
39539});
39540
39541// HELPERS
39542
39543function parseWeekday(input, locale) {
39544    if (typeof input !== 'string') {
39545        return input;
39546    }
39547
39548    if (!isNaN(input)) {
39549        return parseInt(input, 10);
39550    }
39551
39552    input = locale.weekdaysParse(input);
39553    if (typeof input === 'number') {
39554        return input;
39555    }
39556
39557    return null;
39558}
39559
39560function parseIsoWeekday(input, locale) {
39561    if (typeof input === 'string') {
39562        return locale.weekdaysParse(input) % 7 || 7;
39563    }
39564    return isNaN(input) ? null : input;
39565}
39566
39567// LOCALES
39568
39569var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
39570function localeWeekdays (m, format) {
39571    if (!m) {
39572        return isArray(this._weekdays) ? this._weekdays :
39573            this._weekdays['standalone'];
39574    }
39575    return isArray(this._weekdays) ? this._weekdays[m.day()] :
39576        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
39577}
39578
39579var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
39580function localeWeekdaysShort (m) {
39581    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
39582}
39583
39584var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
39585function localeWeekdaysMin (m) {
39586    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
39587}
39588
39589function handleStrictParse$1(weekdayName, format, strict) {
39590    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
39591    if (!this._weekdaysParse) {
39592        this._weekdaysParse = [];
39593        this._shortWeekdaysParse = [];
39594        this._minWeekdaysParse = [];
39595
39596        for (i = 0; i < 7; ++i) {
39597            mom = createUTC([2000, 1]).day(i);
39598            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
39599            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
39600            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
39601        }
39602    }
39603
39604    if (strict) {
39605        if (format === 'dddd') {
39606            ii = indexOf$1.call(this._weekdaysParse, llc);
39607            return ii !== -1 ? ii : null;
39608        } else if (format === 'ddd') {
39609            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
39610            return ii !== -1 ? ii : null;
39611        } else {
39612            ii = indexOf$1.call(this._minWeekdaysParse, llc);
39613            return ii !== -1 ? ii : null;
39614        }
39615    } else {
39616        if (format === 'dddd') {
39617            ii = indexOf$1.call(this._weekdaysParse, llc);
39618            if (ii !== -1) {
39619                return ii;
39620            }
39621            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
39622            if (ii !== -1) {
39623                return ii;
39624            }
39625            ii = indexOf$1.call(this._minWeekdaysParse, llc);
39626            return ii !== -1 ? ii : null;
39627        } else if (format === 'ddd') {
39628            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
39629            if (ii !== -1) {
39630                return ii;
39631            }
39632            ii = indexOf$1.call(this._weekdaysParse, llc);
39633            if (ii !== -1) {
39634                return ii;
39635            }
39636            ii = indexOf$1.call(this._minWeekdaysParse, llc);
39637            return ii !== -1 ? ii : null;
39638        } else {
39639            ii = indexOf$1.call(this._minWeekdaysParse, llc);
39640            if (ii !== -1) {
39641                return ii;
39642            }
39643            ii = indexOf$1.call(this._weekdaysParse, llc);
39644            if (ii !== -1) {
39645                return ii;
39646            }
39647            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
39648            return ii !== -1 ? ii : null;
39649        }
39650    }
39651}
39652
39653function localeWeekdaysParse (weekdayName, format, strict) {
39654    var i, mom, regex;
39655
39656    if (this._weekdaysParseExact) {
39657        return handleStrictParse$1.call(this, weekdayName, format, strict);
39658    }
39659
39660    if (!this._weekdaysParse) {
39661        this._weekdaysParse = [];
39662        this._minWeekdaysParse = [];
39663        this._shortWeekdaysParse = [];
39664        this._fullWeekdaysParse = [];
39665    }
39666
39667    for (i = 0; i < 7; i++) {
39668        // make the regex if we don't have it already
39669
39670        mom = createUTC([2000, 1]).day(i);
39671        if (strict && !this._fullWeekdaysParse[i]) {
39672            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
39673            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
39674            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
39675        }
39676        if (!this._weekdaysParse[i]) {
39677            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
39678            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
39679        }
39680        // test the regex
39681        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
39682            return i;
39683        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
39684            return i;
39685        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
39686            return i;
39687        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
39688            return i;
39689        }
39690    }
39691}
39692
39693// MOMENTS
39694
39695function getSetDayOfWeek (input) {
39696    if (!this.isValid()) {
39697        return input != null ? this : NaN;
39698    }
39699    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
39700    if (input != null) {
39701        input = parseWeekday(input, this.localeData());
39702        return this.add(input - day, 'd');
39703    } else {
39704        return day;
39705    }
39706}
39707
39708function getSetLocaleDayOfWeek (input) {
39709    if (!this.isValid()) {
39710        return input != null ? this : NaN;
39711    }
39712    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
39713    return input == null ? weekday : this.add(input - weekday, 'd');
39714}
39715
39716function getSetISODayOfWeek (input) {
39717    if (!this.isValid()) {
39718        return input != null ? this : NaN;
39719    }
39720
39721    // behaves the same as moment#day except
39722    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
39723    // as a setter, sunday should belong to the previous week.
39724
39725    if (input != null) {
39726        var weekday = parseIsoWeekday(input, this.localeData());
39727        return this.day(this.day() % 7 ? weekday : weekday - 7);
39728    } else {
39729        return this.day() || 7;
39730    }
39731}
39732
39733var defaultWeekdaysRegex = matchWord;
39734function weekdaysRegex (isStrict) {
39735    if (this._weekdaysParseExact) {
39736        if (!hasOwnProp(this, '_weekdaysRegex')) {
39737            computeWeekdaysParse.call(this);
39738        }
39739        if (isStrict) {
39740            return this._weekdaysStrictRegex;
39741        } else {
39742            return this._weekdaysRegex;
39743        }
39744    } else {
39745        if (!hasOwnProp(this, '_weekdaysRegex')) {
39746            this._weekdaysRegex = defaultWeekdaysRegex;
39747        }
39748        return this._weekdaysStrictRegex && isStrict ?
39749            this._weekdaysStrictRegex : this._weekdaysRegex;
39750    }
39751}
39752
39753var defaultWeekdaysShortRegex = matchWord;
39754function weekdaysShortRegex (isStrict) {
39755    if (this._weekdaysParseExact) {
39756        if (!hasOwnProp(this, '_weekdaysRegex')) {
39757            computeWeekdaysParse.call(this);
39758        }
39759        if (isStrict) {
39760            return this._weekdaysShortStrictRegex;
39761        } else {
39762            return this._weekdaysShortRegex;
39763        }
39764    } else {
39765        if (!hasOwnProp(this, '_weekdaysShortRegex')) {
39766            this._weekdaysShortRegex = defaultWeekdaysShortRegex;
39767        }
39768        return this._weekdaysShortStrictRegex && isStrict ?
39769            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
39770    }
39771}
39772
39773var defaultWeekdaysMinRegex = matchWord;
39774function weekdaysMinRegex (isStrict) {
39775    if (this._weekdaysParseExact) {
39776        if (!hasOwnProp(this, '_weekdaysRegex')) {
39777            computeWeekdaysParse.call(this);
39778        }
39779        if (isStrict) {
39780            return this._weekdaysMinStrictRegex;
39781        } else {
39782            return this._weekdaysMinRegex;
39783        }
39784    } else {
39785        if (!hasOwnProp(this, '_weekdaysMinRegex')) {
39786            this._weekdaysMinRegex = defaultWeekdaysMinRegex;
39787        }
39788        return this._weekdaysMinStrictRegex && isStrict ?
39789            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
39790    }
39791}
39792
39793
39794function computeWeekdaysParse () {
39795    function cmpLenRev(a, b) {
39796        return b.length - a.length;
39797    }
39798
39799    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
39800        i, mom, minp, shortp, longp;
39801    for (i = 0; i < 7; i++) {
39802        // make the regex if we don't have it already
39803        mom = createUTC([2000, 1]).day(i);
39804        minp = this.weekdaysMin(mom, '');
39805        shortp = this.weekdaysShort(mom, '');
39806        longp = this.weekdays(mom, '');
39807        minPieces.push(minp);
39808        shortPieces.push(shortp);
39809        longPieces.push(longp);
39810        mixedPieces.push(minp);
39811        mixedPieces.push(shortp);
39812        mixedPieces.push(longp);
39813    }
39814    // Sorting makes sure if one weekday (or abbr) is a prefix of another it
39815    // will match the longer piece.
39816    minPieces.sort(cmpLenRev);
39817    shortPieces.sort(cmpLenRev);
39818    longPieces.sort(cmpLenRev);
39819    mixedPieces.sort(cmpLenRev);
39820    for (i = 0; i < 7; i++) {
39821        shortPieces[i] = regexEscape(shortPieces[i]);
39822        longPieces[i] = regexEscape(longPieces[i]);
39823        mixedPieces[i] = regexEscape(mixedPieces[i]);
39824    }
39825
39826    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
39827    this._weekdaysShortRegex = this._weekdaysRegex;
39828    this._weekdaysMinRegex = this._weekdaysRegex;
39829
39830    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
39831    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
39832    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
39833}
39834
39835// FORMATTING
39836
39837function hFormat() {
39838    return this.hours() % 12 || 12;
39839}
39840
39841function kFormat() {
39842    return this.hours() || 24;
39843}
39844
39845addFormatToken('H', ['HH', 2], 0, 'hour');
39846addFormatToken('h', ['hh', 2], 0, hFormat);
39847addFormatToken('k', ['kk', 2], 0, kFormat);
39848
39849addFormatToken('hmm', 0, 0, function () {
39850    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
39851});
39852
39853addFormatToken('hmmss', 0, 0, function () {
39854    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
39855        zeroFill(this.seconds(), 2);
39856});
39857
39858addFormatToken('Hmm', 0, 0, function () {
39859    return '' + this.hours() + zeroFill(this.minutes(), 2);
39860});
39861
39862addFormatToken('Hmmss', 0, 0, function () {
39863    return '' + this.hours() + zeroFill(this.minutes(), 2) +
39864        zeroFill(this.seconds(), 2);
39865});
39866
39867function meridiem (token, lowercase) {
39868    addFormatToken(token, 0, 0, function () {
39869        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
39870    });
39871}
39872
39873meridiem('a', true);
39874meridiem('A', false);
39875
39876// ALIASES
39877
39878addUnitAlias('hour', 'h');
39879
39880// PRIORITY
39881addUnitPriority('hour', 13);
39882
39883// PARSING
39884
39885function matchMeridiem (isStrict, locale) {
39886    return locale._meridiemParse;
39887}
39888
39889addRegexToken('a',  matchMeridiem);
39890addRegexToken('A',  matchMeridiem);
39891addRegexToken('H',  match1to2);
39892addRegexToken('h',  match1to2);
39893addRegexToken('k',  match1to2);
39894addRegexToken('HH', match1to2, match2);
39895addRegexToken('hh', match1to2, match2);
39896addRegexToken('kk', match1to2, match2);
39897
vendor: 10,831 bytes, lines 39898-40238
39898addRegexToken('hmm', match3to4);
39899addRegexToken('hmmss', match5to6);
39900addRegexToken('Hmm', match3to4);
39901addRegexToken('Hmmss', match5to6);
39902
39903addParseToken(['H', 'HH'], HOUR);
39904addParseToken(['k', 'kk'], function (input, array, config) {
39905    var kInput = toInt(input);
39906    array[HOUR] = kInput === 24 ? 0 : kInput;
39907});
39908addParseToken(['a', 'A'], function (input, array, config) {
39909    config._isPm = config._locale.isPM(input);
39910    config._meridiem = input;
39911});
39912addParseToken(['h', 'hh'], function (input, array, config) {
39913    array[HOUR] = toInt(input);
39914    getParsingFlags(config).bigHour = true;
39915});
39916addParseToken('hmm', function (input, array, config) {
39917    var pos = input.length - 2;
39918    array[HOUR] = toInt(input.substr(0, pos));
39919    array[MINUTE] = toInt(input.substr(pos));
39920    getParsingFlags(config).bigHour = true;
39921});
39922addParseToken('hmmss', function (input, array, config) {
39923    var pos1 = input.length - 4;
39924    var pos2 = input.length - 2;
39925    array[HOUR] = toInt(input.substr(0, pos1));
39926    array[MINUTE] = toInt(input.substr(pos1, 2));
39927    array[SECOND] = toInt(input.substr(pos2));
39928    getParsingFlags(config).bigHour = true;
39929});
39930addParseToken('Hmm', function (input, array, config) {
39931    var pos = input.length - 2;
39932    array[HOUR] = toInt(input.substr(0, pos));
39933    array[MINUTE] = toInt(input.substr(pos));
39934});
39935addParseToken('Hmmss', function (input, array, config) {
39936    var pos1 = input.length - 4;
39937    var pos2 = input.length - 2;
39938    array[HOUR] = toInt(input.substr(0, pos1));
39939    array[MINUTE] = toInt(input.substr(pos1, 2));
39940    array[SECOND] = toInt(input.substr(pos2));
39941});
39942
39943// LOCALES
39944
39945function localeIsPM (input) {
39946    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
39947    // Using charAt should be more compatible.
39948    return ((input + '').toLowerCase().charAt(0) === 'p');
39949}
39950
39951var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
39952function localeMeridiem (hours, minutes, isLower) {
39953    if (hours > 11) {
39954        return isLower ? 'pm' : 'PM';
39955    } else {
39956        return isLower ? 'am' : 'AM';
39957    }
39958}
39959
39960
39961// MOMENTS
39962
39963// Setting the hour should keep the time, because the user explicitly
39964// specified which hour he wants. So trying to maintain the same hour (in
39965// a new timezone) makes sense. Adding/subtracting hours does not follow
39966// this rule.
39967var getSetHour = makeGetSet('Hours', true);
39968
39969// months
39970// week
39971// weekdays
39972// meridiem
39973var baseConfig = {
39974    calendar: defaultCalendar,
39975    longDateFormat: defaultLongDateFormat,
39976    invalidDate: defaultInvalidDate,
39977    ordinal: defaultOrdinal,
39978    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
39979    relativeTime: defaultRelativeTime,
39980
39981    months: defaultLocaleMonths,
39982    monthsShort: defaultLocaleMonthsShort,
39983
39984    week: defaultLocaleWeek,
39985
39986    weekdays: defaultLocaleWeekdays,
39987    weekdaysMin: defaultLocaleWeekdaysMin,
39988    weekdaysShort: defaultLocaleWeekdaysShort,
39989
39990    meridiemParse: defaultLocaleMeridiemParse
39991};
39992
39993// internal storage for locale config files
39994var locales = {};
39995var localeFamilies = {};
39996var globalLocale;
39997
39998function normalizeLocale(key) {
39999    return key ? key.toLowerCase().replace('_', '-') : key;
40000}
40001
40002// pick the locale from the array
40003// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
40004// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
40005function chooseLocale(names) {
40006    var i = 0, j, next, locale, split;
40007
40008    while (i < names.length) {
40009        split = normalizeLocale(names[i]).split('-');
40010        j = split.length;
40011        next = normalizeLocale(names[i + 1]);
40012        next = next ? next.split('-') : null;
40013        while (j > 0) {
40014            locale = loadLocale(split.slice(0, j).join('-'));
40015            if (locale) {
40016                return locale;
40017            }
40018            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
40019                //the next array item is better than a shallower substring of this one
40020                break;
40021            }
40022            j--;
40023        }
40024        i++;
40025    }
40026    return null;
40027}
40028
40029function loadLocale(name) {
40030    var oldLocale = null;
40031    // TODO: Find a better way to register and load all the locales in Node
40032    if (!locales[name] && (typeof module !== 'undefined') &&
40033            module && module.exports) {
40034        try {
40035            oldLocale = globalLocale._abbr;
40036            require('./locale/' + name);
40037            // because defineLocale currently also sets the global locale, we
40038            // want to undo that for lazy loaded locales
40039            getSetGlobalLocale(oldLocale);
40040        } catch (e) { }
40041    }
40042    return locales[name];
40043}
40044
40045// This function will load locale and then set the global locale.  If
40046// no arguments are passed in, it will simply return the current global
40047// locale key.
40048function getSetGlobalLocale (key, values) {
40049    var data;
40050    if (key) {
40051        if (isUndefined(values)) {
40052            data = getLocale(key);
40053        }
40054        else {
40055            data = defineLocale(key, values);
40056        }
40057
40058        if (data) {
40059            // moment.duration._locale = moment._locale = data;
40060            globalLocale = data;
40061        }
40062    }
40063
40064    return globalLocale._abbr;
40065}
40066
40067function defineLocale (name, config) {
40068    if (config !== null) {
40069        var parentConfig = baseConfig;
40070        config.abbr = name;
40071        if (locales[name] != null) {
40072            deprecateSimple('defineLocaleOverride',
40073                    'use moment.updateLocale(localeName, config) to change ' +
40074                    'an existing locale. moment.defineLocale(localeName, ' +
40075                    'config) should only be used for creating a new locale ' +
40076                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
40077            parentConfig = locales[name]._config;
40078        } else if (config.parentLocale != null) {
40079            if (locales[config.parentLocale] != null) {
40080                parentConfig = locales[config.parentLocale]._config;
40081            } else {
40082                if (!localeFamilies[config.parentLocale]) {
40083                    localeFamilies[config.parentLocale] = [];
40084                }
40085                localeFamilies[config.parentLocale].push({
40086                    name: name,
40087                    config: config
40088                });
40089                return null;
40090            }
40091        }
40092        locales[name] = new Locale(mergeConfigs(parentConfig, config));
40093
40094        if (localeFamilies[name]) {
40095            localeFamilies[name].forEach(function (x) {
40096                defineLocale(x.name, x.config);
40097            });
40098        }
40099
40100        // backwards compat for now: also set the locale
40101        // make sure we set the locale AFTER all child locales have been
40102        // created, so we won't end up with the child locale set.
40103        getSetGlobalLocale(name);
40104
40105
40106        return locales[name];
40107    } else {
40108        // useful for testing
40109        delete locales[name];
40110        return null;
40111    }
40112}
40113
40114function updateLocale(name, config) {
40115    if (config != null) {
40116        var locale, parentConfig = baseConfig;
40117        // MERGE
40118        if (locales[name] != null) {
40119            parentConfig = locales[name]._config;
40120        }
40121        config = mergeConfigs(parentConfig, config);
40122        locale = new Locale(config);
40123        locale.parentLocale = locales[name];
40124        locales[name] = locale;
40125
40126        // backwards compat for now: also set the locale
40127        getSetGlobalLocale(name);
40128    } else {
40129        // pass null for config to unupdate, useful for tests
40130        if (locales[name] != null) {
40131            if (locales[name].parentLocale != null) {
40132                locales[name] = locales[name].parentLocale;
40133            } else if (locales[name] != null) {
40134                delete locales[name];
40135            }
40136        }
40137    }
40138    return locales[name];
40139}
40140
40141// returns locale data
40142function getLocale (key) {
40143    var locale;
40144
40145    if (key && key._locale && key._locale._abbr) {
40146        key = key._locale._abbr;
40147    }
40148
40149    if (!key) {
40150        return globalLocale;
40151    }
40152
40153    if (!isArray(key)) {
40154        //short-circuit everything else
40155        locale = loadLocale(key);
40156        if (locale) {
40157            return locale;
40158        }
40159        key = [key];
40160    }
40161
40162    return chooseLocale(key);
40163}
40164
40165function listLocales() {
40166    return keys$1(locales);
40167}
40168
40169function checkOverflow (m) {
40170    var overflow;
40171    var a = m._a;
40172
40173    if (a && getParsingFlags(m).overflow === -2) {
40174        overflow =
40175            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
40176            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
40177            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
40178            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
40179            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
40180            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
40181            -1;
40182
40183        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
40184            overflow = DATE;
40185        }
40186        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
40187            overflow = WEEK;
40188        }
40189        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
40190            overflow = WEEKDAY;
40191        }
40192
40193        getParsingFlags(m).overflow = overflow;
40194    }
40195
40196    return m;
40197}
40198
40199// iso 8601 regex
40200// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
40201var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
40202var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
40203
40204var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
40205
40206var isoDates = [
40207    ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
40208    ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
40209    ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
40210    ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
40211    ['YYYY-DDD', /\d{4}-\d{3}/],
40212    ['YYYY-MM', /\d{4}-\d\d/, false],
40213    ['YYYYYYMMDD', /[+-]\d{10}/],
40214    ['YYYYMMDD', /\d{8}/],
40215    // YYYYMM is NOT allowed by the standard
40216    ['GGGG[W]WWE', /\d{4}W\d{3}/],
40217    ['GGGG[W]WW', /\d{4}W\d{2}/, false],
40218    ['YYYYDDD', /\d{7}/]
40219];
40220
40221// iso time formats and regexes
40222var isoTimes = [
40223    ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
40224    ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
40225    ['HH:mm:ss', /\d\d:\d\d:\d\d/],
40226    ['HH:mm', /\d\d:\d\d/],
40227    ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
40228    ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
40229    ['HHmmss', /\d\d\d\d\d\d/],
40230    ['HHmm', /\d\d\d\d/],
40231    ['HH', /\d\d/]
40232];
40233
40234var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
40235
40236// date from iso format
40237function configFromISO(config) {
40238    var i, l,
vendor: 2,325 bytes, lines 40239-40310
40239        string = config._i,
40240        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
40241        allowTime, dateFormat, timeFormat, tzFormat;
40242
40243    if (match) {
40244        getParsingFlags(config).iso = true;
40245
40246        for (i = 0, l = isoDates.length; i < l; i++) {
40247            if (isoDates[i][1].exec(match[1])) {
40248                dateFormat = isoDates[i][0];
40249                allowTime = isoDates[i][2] !== false;
40250                break;
40251            }
40252        }
40253        if (dateFormat == null) {
40254            config._isValid = false;
40255            return;
40256        }
40257        if (match[3]) {
40258            for (i = 0, l = isoTimes.length; i < l; i++) {
40259                if (isoTimes[i][1].exec(match[3])) {
40260                    // match[2] should be 'T' or space
40261                    timeFormat = (match[2] || ' ') + isoTimes[i][0];
40262                    break;
40263                }
40264            }
40265            if (timeFormat == null) {
40266                config._isValid = false;
40267                return;
40268            }
40269        }
40270        if (!allowTime && timeFormat != null) {
40271            config._isValid = false;
40272            return;
40273        }
40274        if (match[4]) {
40275            if (tzRegex.exec(match[4])) {
40276                tzFormat = 'Z';
40277            } else {
40278                config._isValid = false;
40279                return;
40280            }
40281        }
40282        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
40283        configFromStringAndFormat(config);
40284    } else {
40285        config._isValid = false;
40286    }
40287}
40288
40289// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
40290var basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;
40291
40292// date and time from ref 2822 format
40293function configFromRFC2822(config) {
40294    var string, match, dayFormat,
40295        dateFormat, timeFormat, tzFormat;
40296    var timezones = {
40297        ' GMT': ' +0000',
40298        ' EDT': ' -0400',
40299        ' EST': ' -0500',
40300        ' CDT': ' -0500',
40301        ' CST': ' -0600',
40302        ' MDT': ' -0600',
40303        ' MST': ' -0700',
40304        ' PDT': ' -0700',
40305        ' PST': ' -0800'
40306    };
40307    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';
40308    var timezone, timezoneIndex;
40309
40310    string = config._i
40311        .replace(/\([^\)]*\)|[\n\t]/g, ' ') // Remove comments and folding whitespace
40312        .replace(/(\s\s+)/g, ' ') // Replace multiple-spaces with a single space
40313        .replace(/^\s|\s$/g, ''); // Remove leading and trailing spaces
40314    match = basicRfcRegex.exec(string);
40315
40316    if (match) {
40317        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';
40318        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');
40319        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');
40320
40321        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
40322        if (match[1]) { // day of week given
40323            var momentDate = new Date(match[2]);
40324            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];
40325
40326            if (match[1].substr(0,3) !== momentDay) {
40327                getParsingFlags(config).weekdayMismatch = true;
40328                config._isValid = false;
40329                return;
40330            }
40331        }
40332
40333        switch (match[5].length) {
40334            case 2: // military
40335                if (timezoneIndex === 0) {
40336                    timezone = ' +0000';
40337                } else {
40338                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;
40339                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +
40340                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';
40341                }
40342                break;
40343            case 4: // Zone
40344                timezone = timezones[match[5]];
40345                break;
40346            default: // UT or +/-9999
40347                timezone = timezones[' GMT'];
40348        }
40349        match[5] = timezone;
40350        config._i = match.splice(1).join('');
40351        tzFormat = ' ZZ';
40352        config._f = dayFormat + dateFormat + timeFormat + tzFormat;
40353        configFromStringAndFormat(config);
40354        getParsingFlags(config).rfc2822 = true;
40355    } else {
40356        config._isValid = false;
40357    }
40358}
40359
40360// date from iso format or fallback
40361function configFromString(config) {
40362    var matched = aspNetJsonRegex.exec(config._i);
40363
40364    if (matched !== null) {
40365        config._d = new Date(+matched[1]);
40366        return;
40367    }
40368
40369    configFromISO(config);
40370    if (config._isValid === false) {
40371        delete config._isValid;
40372    } else {
40373        return;
40374    }
40375
40376    configFromRFC2822(config);
40377    if (config._isValid === false) {
40378        delete config._isValid;
40379    } else {
40380        return;
40381    }
40382
40383    // Final attempt, use Input Fallback
40384    hooks.createFromInputFallback(config);
40385}
40386
40387hooks.createFromInputFallback = deprecate(
40388    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
40389    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
40390    'discouraged and will be removed in an upcoming major release. Please refer to ' +
40391    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
40392    function (config) {
40393        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
40394    }
40395);
40396
40397// Pick the first defined of two or three arguments.
40398function defaults(a, b, c) {
40399    if (a != null) {
40400        return a;
40401    }
40402    if (b != null) {
40403        return b;
40404    }
40405    return c;
40406}
40407
40408function currentDateArray(config) {
40409    // hooks is actually the exported moment object
40410    var nowValue = new Date(hooks.now());
40411    if (config._useUTC) {
40412        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
40413    }
40414    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
40415}
40416
40417// convert an array to a date.
40418// the array should mirror the parameters below
40419// note: all values past the year are optional and will default to the lowest possible value.
40420// [year, month, day , hour, minute, second, millisecond]
40421function configFromArray (config) {
40422    var i, date, input = [], currentDate, yearToUse;
40423
40424    if (config._d) {
40425        return;
40426    }
40427
40428    currentDate = currentDateArray(config);
40429
40430    //compute day of the year from weeks and weekdays
40431    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
40432        dayOfYearFromWeekInfo(config);
40433    }
40434
40435    //if the day of the year is set, figure out what it is
40436    if (config._dayOfYear != null) {
40437        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
40438
40439        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
40440            getParsingFlags(config)._overflowDayOfYear = true;
40441        }
40442
40443        date = createUTCDate(yearToUse, 0, config._dayOfYear);
40444        config._a[MONTH] = date.getUTCMonth();
40445        config._a[DATE] = date.getUTCDate();
40446    }
40447
40448    // Default to current date.
40449    // * if no year, month, day of month are given, default to today
40450    // * if day of month is given, default month and year
40451    // * if month is given, default only year
40452    // * if year is given, don't default anything
40453    for (i = 0; i < 3 && config._a[i] == null; ++i) {
vendor: 4,215 bytes, lines 40454-40577
40454        config._a[i] = input[i] = currentDate[i];
40455    }
40456
40457    // Zero out whatever was not defaulted, including time
40458    for (; i < 7; i++) {
40459        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
40460    }
40461
40462    // Check for 24:00:00.000
40463    if (config._a[HOUR] === 24 &&
40464            config._a[MINUTE] === 0 &&
40465            config._a[SECOND] === 0 &&
40466            config._a[MILLISECOND] === 0) {
40467        config._nextDay = true;
40468        config._a[HOUR] = 0;
40469    }
40470
40471    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
40472    // Apply timezone offset from input. The actual utcOffset can be changed
40473    // with parseZone.
40474    if (config._tzm != null) {
40475        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
40476    }
40477
40478    if (config._nextDay) {
40479        config._a[HOUR] = 24;
40480    }
40481}
40482
40483function dayOfYearFromWeekInfo(config) {
40484    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
40485
40486    w = config._w;
40487    if (w.GG != null || w.W != null || w.E != null) {
40488        dow = 1;
40489        doy = 4;
40490
40491        // TODO: We need to take the current isoWeekYear, but that depends on
40492        // how we interpret now (local, utc, fixed offset). So create
40493        // a now version of current config (take local/utc/offset flags, and
40494        // create now).
40495        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
40496        week = defaults(w.W, 1);
40497        weekday = defaults(w.E, 1);
40498        if (weekday < 1 || weekday > 7) {
40499            weekdayOverflow = true;
40500        }
40501    } else {
40502        dow = config._locale._week.dow;
40503        doy = config._locale._week.doy;
40504
40505        var curWeek = weekOfYear(createLocal(), dow, doy);
40506
40507        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
40508
40509        // Default to current week.
40510        week = defaults(w.w, curWeek.week);
40511
40512        if (w.d != null) {
40513            // weekday -- low day numbers are considered next week
40514            weekday = w.d;
40515            if (weekday < 0 || weekday > 6) {
40516                weekdayOverflow = true;
40517            }
40518        } else if (w.e != null) {
40519            // local weekday -- counting starts from begining of week
40520            weekday = w.e + dow;
40521            if (w.e < 0 || w.e > 6) {
40522                weekdayOverflow = true;
40523            }
40524        } else {
40525            // default to begining of week
40526            weekday = dow;
40527        }
40528    }
40529    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
40530        getParsingFlags(config)._overflowWeeks = true;
40531    } else if (weekdayOverflow != null) {
40532        getParsingFlags(config)._overflowWeekday = true;
40533    } else {
40534        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
40535        config._a[YEAR] = temp.year;
40536        config._dayOfYear = temp.dayOfYear;
40537    }
40538}
40539
40540// constant that refers to the ISO standard
40541hooks.ISO_8601 = function () {};
40542
40543// constant that refers to the RFC 2822 form
40544hooks.RFC_2822 = function () {};
40545
40546// date from string and format string
40547function configFromStringAndFormat(config) {
40548    // TODO: Move this to another part of the creation flow to prevent circular deps
40549    if (config._f === hooks.ISO_8601) {
40550        configFromISO(config);
40551        return;
40552    }
40553    if (config._f === hooks.RFC_2822) {
40554        configFromRFC2822(config);
40555        return;
40556    }
40557    config._a = [];
40558    getParsingFlags(config).empty = true;
40559
40560    // This array is used to make a Date, either with `new Date` or `Date.UTC`
40561    var string = '' + config._i,
40562        i, parsedInput, tokens, token, skipped,
40563        stringLength = string.length,
40564        totalParsedInputLength = 0;
40565
40566    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
40567
40568    for (i = 0; i < tokens.length; i++) {
40569        token = tokens[i];
40570        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
40571        // console.log('token', token, 'parsedInput', parsedInput,
40572        //         'regex', getParseRegexForToken(token, config));
40573        if (parsedInput) {
40574            skipped = string.substr(0, string.indexOf(parsedInput));
40575            if (skipped.length > 0) {
40576                getParsingFlags(config).unusedInput.push(skipped);
40577            }
vendor: 18,727 bytes, lines 40578-41230
40578            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
40579            totalParsedInputLength += parsedInput.length;
40580        }
40581        // don't parse if it's not a known token
40582        if (formatTokenFunctions[token]) {
40583            if (parsedInput) {
40584                getParsingFlags(config).empty = false;
40585            }
40586            else {
40587                getParsingFlags(config).unusedTokens.push(token);
40588            }
40589            addTimeToArrayFromToken(token, parsedInput, config);
40590        }
40591        else if (config._strict && !parsedInput) {
40592            getParsingFlags(config).unusedTokens.push(token);
40593        }
40594    }
40595
40596    // add remaining unparsed input length to the string
40597    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
40598    if (string.length > 0) {
40599        getParsingFlags(config).unusedInput.push(string);
40600    }
40601
40602    // clear _12h flag if hour is <= 12
40603    if (config._a[HOUR] <= 12 &&
40604        getParsingFlags(config).bigHour === true &&
40605        config._a[HOUR] > 0) {
40606        getParsingFlags(config).bigHour = undefined;
40607    }
40608
40609    getParsingFlags(config).parsedDateParts = config._a.slice(0);
40610    getParsingFlags(config).meridiem = config._meridiem;
40611    // handle meridiem
40612    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
40613
40614    configFromArray(config);
40615    checkOverflow(config);
40616}
40617
40618
40619function meridiemFixWrap (locale, hour, meridiem) {
40620    var isPm;
40621
40622    if (meridiem == null) {
40623        // nothing to do
40624        return hour;
40625    }
40626    if (locale.meridiemHour != null) {
40627        return locale.meridiemHour(hour, meridiem);
40628    } else if (locale.isPM != null) {
40629        // Fallback
40630        isPm = locale.isPM(meridiem);
40631        if (isPm && hour < 12) {
40632            hour += 12;
40633        }
40634        if (!isPm && hour === 12) {
40635            hour = 0;
40636        }
40637        return hour;
40638    } else {
40639        // this is not supposed to happen
40640        return hour;
40641    }
40642}
40643
40644// date from string and array of format strings
40645function configFromStringAndArray(config) {
40646    var tempConfig,
40647        bestMoment,
40648
40649        scoreToBeat,
40650        i,
40651        currentScore;
40652
40653    if (config._f.length === 0) {
40654        getParsingFlags(config).invalidFormat = true;
40655        config._d = new Date(NaN);
40656        return;
40657    }
40658
40659    for (i = 0; i < config._f.length; i++) {
40660        currentScore = 0;
40661        tempConfig = copyConfig({}, config);
40662        if (config._useUTC != null) {
40663            tempConfig._useUTC = config._useUTC;
40664        }
40665        tempConfig._f = config._f[i];
40666        configFromStringAndFormat(tempConfig);
40667
40668        if (!isValid(tempConfig)) {
40669            continue;
40670        }
40671
40672        // if there is any input that was not parsed add a penalty for that format
40673        currentScore += getParsingFlags(tempConfig).charsLeftOver;
40674
40675        //or tokens
40676        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
40677
40678        getParsingFlags(tempConfig).score = currentScore;
40679
40680        if (scoreToBeat == null || currentScore < scoreToBeat) {
40681            scoreToBeat = currentScore;
40682            bestMoment = tempConfig;
40683        }
40684    }
40685
40686    extend(config, bestMoment || tempConfig);
40687}
40688
40689function configFromObject(config) {
40690    if (config._d) {
40691        return;
40692    }
40693
40694    var i = normalizeObjectUnits(config._i);
40695    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
40696        return obj && parseInt(obj, 10);
40697    });
40698
40699    configFromArray(config);
40700}
40701
40702function createFromConfig (config) {
40703    var res = new Moment(checkOverflow(prepareConfig(config)));
40704    if (res._nextDay) {
40705        // Adding is smart enough around DST
40706        res.add(1, 'd');
40707        res._nextDay = undefined;
40708    }
40709
40710    return res;
40711}
40712
40713function prepareConfig (config) {
40714    var input = config._i,
40715        format = config._f;
40716
40717    config._locale = config._locale || getLocale(config._l);
40718
40719    if (input === null || (format === undefined && input === '')) {
40720        return createInvalid({nullInput: true});
40721    }
40722
40723    if (typeof input === 'string') {
40724        config._i = input = config._locale.preparse(input);
40725    }
40726
40727    if (isMoment(input)) {
40728        return new Moment(checkOverflow(input));
40729    } else if (isDate(input)) {
40730        config._d = input;
40731    } else if (isArray(format)) {
40732        configFromStringAndArray(config);
40733    } else if (format) {
40734        configFromStringAndFormat(config);
40735    }  else {
40736        configFromInput(config);
40737    }
40738
40739    if (!isValid(config)) {
40740        config._d = null;
40741    }
40742
40743    return config;
40744}
40745
40746function configFromInput(config) {
40747    var input = config._i;
40748    if (isUndefined(input)) {
40749        config._d = new Date(hooks.now());
40750    } else if (isDate(input)) {
40751        config._d = new Date(input.valueOf());
40752    } else if (typeof input === 'string') {
40753        configFromString(config);
40754    } else if (isArray(input)) {
40755        config._a = map(input.slice(0), function (obj) {
40756            return parseInt(obj, 10);
40757        });
40758        configFromArray(config);
40759    } else if (isObject(input)) {
40760        configFromObject(config);
40761    } else if (isNumber(input)) {
40762        // from milliseconds
40763        config._d = new Date(input);
40764    } else {
40765        hooks.createFromInputFallback(config);
40766    }
40767}
40768
40769function createLocalOrUTC (input, format, locale, strict, isUTC) {
40770    var c = {};
40771
40772    if (locale === true || locale === false) {
40773        strict = locale;
40774        locale = undefined;
40775    }
40776
40777    if ((isObject(input) && isObjectEmpty(input)) ||
40778            (isArray(input) && input.length === 0)) {
40779        input = undefined;
40780    }
40781    // object construction must be done this way.
40782    // https://github.com/moment/moment/issues/1423
40783    c._isAMomentObject = true;
40784    c._useUTC = c._isUTC = isUTC;
40785    c._l = locale;
40786    c._i = input;
40787    c._f = format;
40788    c._strict = strict;
40789
40790    return createFromConfig(c);
40791}
40792
40793function createLocal (input, format, locale, strict) {
40794    return createLocalOrUTC(input, format, locale, strict, false);
40795}
40796
40797var prototypeMin = deprecate(
40798    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
40799    function () {
40800        var other = createLocal.apply(null, arguments);
40801        if (this.isValid() && other.isValid()) {
40802            return other < this ? this : other;
40803        } else {
40804            return createInvalid();
40805        }
40806    }
40807);
40808
40809var prototypeMax = deprecate(
40810    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
40811    function () {
40812        var other = createLocal.apply(null, arguments);
40813        if (this.isValid() && other.isValid()) {
40814            return other > this ? this : other;
40815        } else {
40816            return createInvalid();
40817        }
40818    }
40819);
40820
40821// Pick a moment m from moments so that m[fn](other) is true for all
40822// other. This relies on the function fn to be transitive.
40823//
40824// moments should either be an array of moment objects or an array, whose
40825// first element is an array of moment objects.
40826function pickBy(fn, moments) {
40827    var res, i;
40828    if (moments.length === 1 && isArray(moments[0])) {
40829        moments = moments[0];
40830    }
40831    if (!moments.length) {
40832        return createLocal();
40833    }
40834    res = moments[0];
40835    for (i = 1; i < moments.length; ++i) {
40836        if (!moments[i].isValid() || moments[i][fn](res)) {
40837            res = moments[i];
40838        }
40839    }
40840    return res;
40841}
40842
40843// TODO: Use [].sort instead?
40844function min () {
40845    var args = [].slice.call(arguments, 0);
40846
40847    return pickBy('isBefore', args);
40848}
40849
40850function max () {
40851    var args = [].slice.call(arguments, 0);
40852
40853    return pickBy('isAfter', args);
40854}
40855
40856var now = function () {
40857    return Date.now ? Date.now() : +(new Date());
40858};
40859
40860var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
40861
40862function isDurationValid(m) {
40863    for (var key in m) {
40864        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
40865            return false;
40866        }
40867    }
40868
40869    var unitHasDecimal = false;
40870    for (var i = 0; i < ordering.length; ++i) {
40871        if (m[ordering[i]]) {
40872            if (unitHasDecimal) {
40873                return false; // only allow non-integers for smallest unit
40874            }
40875            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
40876                unitHasDecimal = true;
40877            }
40878        }
40879    }
40880
40881    return true;
40882}
40883
40884function isValid$1() {
40885    return this._isValid;
40886}
40887
40888function createInvalid$1() {
40889    return createDuration(NaN);
40890}
40891
40892function Duration (duration) {
40893    var normalizedInput = normalizeObjectUnits(duration),
40894        years = normalizedInput.year || 0,
40895        quarters = normalizedInput.quarter || 0,
40896        months = normalizedInput.month || 0,
40897        weeks = normalizedInput.week || 0,
40898        days = normalizedInput.day || 0,
40899        hours = normalizedInput.hour || 0,
40900        minutes = normalizedInput.minute || 0,
40901        seconds = normalizedInput.second || 0,
40902        milliseconds = normalizedInput.millisecond || 0;
40903
40904    this._isValid = isDurationValid(normalizedInput);
40905
40906    // representation for dateAddRemove
40907    this._milliseconds = +milliseconds +
40908        seconds * 1e3 + // 1000
40909        minutes * 6e4 + // 1000 * 60
40910        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
40911    // Because of dateAddRemove treats 24 hours as different from a
40912    // day when working around DST, we need to store them separately
40913    this._days = +days +
40914        weeks * 7;
40915    // It is impossible translate months into days without knowing
40916    // which months you are are talking about, so we have to store
40917    // it separately.
40918    this._months = +months +
40919        quarters * 3 +
40920        years * 12;
40921
40922    this._data = {};
40923
40924    this._locale = getLocale();
40925
40926    this._bubble();
40927}
40928
40929function isDuration (obj) {
40930    return obj instanceof Duration;
40931}
40932
40933function absRound (number) {
40934    if (number < 0) {
40935        return Math.round(-1 * number) * -1;
40936    } else {
40937        return Math.round(number);
40938    }
40939}
40940
40941// FORMATTING
40942
40943function offset (token, separator) {
40944    addFormatToken(token, 0, 0, function () {
40945        var offset = this.utcOffset();
40946        var sign = '+';
40947        if (offset < 0) {
40948            offset = -offset;
40949            sign = '-';
40950        }
40951        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
40952    });
40953}
40954
40955offset('Z', ':');
40956offset('ZZ', '');
40957
40958// PARSING
40959
40960addRegexToken('Z',  matchShortOffset);
40961addRegexToken('ZZ', matchShortOffset);
40962addParseToken(['Z', 'ZZ'], function (input, array, config) {
40963    config._useUTC = true;
40964    config._tzm = offsetFromString(matchShortOffset, input);
40965});
40966
40967// HELPERS
40968
40969// timezone chunker
40970// '+10:00' > ['10',  '00']
40971// '-1530'  > ['-15', '30']
40972var chunkOffset = /([\+\-]|\d\d)/gi;
40973
40974function offsetFromString(matcher, string) {
40975    var matches = (string || '').match(matcher);
40976
40977    if (matches === null) {
40978        return null;
40979    }
40980
40981    var chunk   = matches[matches.length - 1] || [];
40982    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
40983    var minutes = +(parts[1] * 60) + toInt(parts[2]);
40984
40985    return minutes === 0 ?
40986      0 :
40987      parts[0] === '+' ? minutes : -minutes;
40988}
40989
40990// Return a moment from input, that is local/utc/zone equivalent to model.
40991function cloneWithOffset(input, model) {
40992    var res, diff;
40993    if (model._isUTC) {
40994        res = model.clone();
40995        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
40996        // Use low-level api, because this fn is low-level api.
40997        res._d.setTime(res._d.valueOf() + diff);
40998        hooks.updateOffset(res, false);
40999        return res;
41000    } else {
41001        return createLocal(input).local();
41002    }
41003}
41004
41005function getDateOffset (m) {
41006    // On Firefox.24 Date#getTimezoneOffset returns a floating point.
41007    // https://github.com/moment/moment/pull/1871
41008    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
41009}
41010
41011// HOOKS
41012
41013// This function will be called whenever a moment is mutated.
41014// It is intended to keep the offset in sync with the timezone.
41015hooks.updateOffset = function () {};
41016
41017// MOMENTS
41018
41019// keepLocalTime = true means only change the timezone, without
41020// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
41021// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
41022// +0200, so we adjust the time as needed, to be valid.
41023//
41024// Keeping the time actually adds/subtracts (one hour)
41025// from the actual represented time. That is why we call updateOffset
41026// a second time. In case it wants us to change the offset again
41027// _changeInProgress == true case, then we have to adjust, because
41028// there is no such time in the given timezone.
41029function getSetOffset (input, keepLocalTime, keepMinutes) {
41030    var offset = this._offset || 0,
41031        localAdjust;
41032    if (!this.isValid()) {
41033        return input != null ? this : NaN;
41034    }
41035    if (input != null) {
41036        if (typeof input === 'string') {
41037            input = offsetFromString(matchShortOffset, input);
41038            if (input === null) {
41039                return this;
41040            }
41041        } else if (Math.abs(input) < 16 && !keepMinutes) {
41042            input = input * 60;
41043        }
41044        if (!this._isUTC && keepLocalTime) {
41045            localAdjust = getDateOffset(this);
41046        }
41047        this._offset = input;
41048        this._isUTC = true;
41049        if (localAdjust != null) {
41050            this.add(localAdjust, 'm');
41051        }
41052        if (offset !== input) {
41053            if (!keepLocalTime || this._changeInProgress) {
41054                addSubtract(this, createDuration(input - offset, 'm'), 1, false);
41055            } else if (!this._changeInProgress) {
41056                this._changeInProgress = true;
41057                hooks.updateOffset(this, true);
41058                this._changeInProgress = null;
41059            }
41060        }
41061        return this;
41062    } else {
41063        return this._isUTC ? offset : getDateOffset(this);
41064    }
41065}
41066
41067function getSetZone (input, keepLocalTime) {
41068    if (input != null) {
41069        if (typeof input !== 'string') {
41070            input = -input;
41071        }
41072
41073        this.utcOffset(input, keepLocalTime);
41074
41075        return this;
41076    } else {
41077        return -this.utcOffset();
41078    }
41079}
41080
41081function setOffsetToUTC (keepLocalTime) {
41082    return this.utcOffset(0, keepLocalTime);
41083}
41084
41085function setOffsetToLocal (keepLocalTime) {
41086    if (this._isUTC) {
41087        this.utcOffset(0, keepLocalTime);
41088        this._isUTC = false;
41089
41090        if (keepLocalTime) {
41091            this.subtract(getDateOffset(this), 'm');
41092        }
41093    }
41094    return this;
41095}
41096
41097function setOffsetToParsedOffset () {
41098    if (this._tzm != null) {
41099        this.utcOffset(this._tzm, false, true);
41100    } else if (typeof this._i === 'string') {
41101        var tZone = offsetFromString(matchOffset, this._i);
41102        if (tZone != null) {
41103            this.utcOffset(tZone);
41104        }
41105        else {
41106            this.utcOffset(0, true);
41107        }
41108    }
41109    return this;
41110}
41111
41112function hasAlignedHourOffset (input) {
41113    if (!this.isValid()) {
41114        return false;
41115    }
41116    input = input ? createLocal(input).utcOffset() : 0;
41117
41118    return (this.utcOffset() - input) % 60 === 0;
41119}
41120
41121function isDaylightSavingTime () {
41122    return (
41123        this.utcOffset() > this.clone().month(0).utcOffset() ||
41124        this.utcOffset() > this.clone().month(5).utcOffset()
41125    );
41126}
41127
41128function isDaylightSavingTimeShifted () {
41129    if (!isUndefined(this._isDSTShifted)) {
41130        return this._isDSTShifted;
41131    }
41132
41133    var c = {};
41134
41135    copyConfig(c, this);
41136    c = prepareConfig(c);
41137
41138    if (c._a) {
41139        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
41140        this._isDSTShifted = this.isValid() &&
41141            compareArrays(c._a, other.toArray()) > 0;
41142    } else {
41143        this._isDSTShifted = false;
41144    }
41145
41146    return this._isDSTShifted;
41147}
41148
41149function isLocal () {
41150    return this.isValid() ? !this._isUTC : false;
41151}
41152
41153function isUtcOffset () {
41154    return this.isValid() ? this._isUTC : false;
41155}
41156
41157function isUtc () {
41158    return this.isValid() ? this._isUTC && this._offset === 0 : false;
41159}
41160
41161// ASP.NET json date format regex
41162var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
41163
41164// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
41165// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
41166// and further modified to allow for strings containing both week and day
41167var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
41168
41169function createDuration (input, key) {
41170    var duration = input,
41171        // matching against regexp is expensive, do it on demand
41172        match = null,
41173        sign,
41174        ret,
41175        diffRes;
41176
41177    if (isDuration(input)) {
41178        duration = {
41179            ms : input._milliseconds,
41180            d  : input._days,
41181            M  : input._months
41182        };
41183    } else if (isNumber(input)) {
41184        duration = {};
41185        if (key) {
41186            duration[key] = input;
41187        } else {
41188            duration.milliseconds = input;
41189        }
41190    } else if (!!(match = aspNetRegex.exec(input))) {
41191        sign = (match[1] === '-') ? -1 : 1;
41192        duration = {
41193            y  : 0,
41194            d  : toInt(match[DATE])                         * sign,
41195            h  : toInt(match[HOUR])                         * sign,
41196            m  : toInt(match[MINUTE])                       * sign,
41197            s  : toInt(match[SECOND])                       * sign,
41198            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
41199        };
41200    } else if (!!(match = isoRegex.exec(input))) {
41201        sign = (match[1] === '-') ? -1 : 1;
41202        duration = {
41203            y : parseIso(match[2], sign),
41204            M : parseIso(match[3], sign),
41205            w : parseIso(match[4], sign),
41206            d : parseIso(match[5], sign),
41207            h : parseIso(match[6], sign),
41208            m : parseIso(match[7], sign),
41209            s : parseIso(match[8], sign)
41210        };
41211    } else if (duration == null) {// checks for null or undefined
41212        duration = {};
41213    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
41214        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
41215
41216        duration = {};
41217        duration.ms = diffRes.milliseconds;
41218        duration.M = diffRes.months;
41219    }
41220
41221    ret = new Duration(duration);
41222
41223    if (isDuration(input) && hasOwnProp(input, '_locale')) {
41224        ret._locale = input._locale;
41225    }
41226
41227    return ret;
41228}
41229
41230createDuration.fn = Duration.prototype;
vendor: 8,280 bytes, lines 41231-41490
41231createDuration.invalid = createInvalid$1;
41232
41233function parseIso (inp, sign) {
41234    // We'd normally use ~~inp for this, but unfortunately it also
41235    // converts floats to ints.
41236    // inp may be undefined, so careful calling replace on it.
41237    var res = inp && parseFloat(inp.replace(',', '.'));
41238    // apply sign while we're at it
41239    return (isNaN(res) ? 0 : res) * sign;
41240}
41241
41242function positiveMomentsDifference(base, other) {
41243    var res = {milliseconds: 0, months: 0};
41244
41245    res.months = other.month() - base.month() +
41246        (other.year() - base.year()) * 12;
41247    if (base.clone().add(res.months, 'M').isAfter(other)) {
41248        --res.months;
41249    }
41250
41251    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
41252
41253    return res;
41254}
41255
41256function momentsDifference(base, other) {
41257    var res;
41258    if (!(base.isValid() && other.isValid())) {
41259        return {milliseconds: 0, months: 0};
41260    }
41261
41262    other = cloneWithOffset(other, base);
41263    if (base.isBefore(other)) {
41264        res = positiveMomentsDifference(base, other);
41265    } else {
41266        res = positiveMomentsDifference(other, base);
41267        res.milliseconds = -res.milliseconds;
41268        res.months = -res.months;
41269    }
41270
41271    return res;
41272}
41273
41274// TODO: remove 'name' arg after deprecation is removed
41275function createAdder(direction, name) {
41276    return function (val, period) {
41277        var dur, tmp;
41278        //invert the arguments, but complain about it
41279        if (period !== null && !isNaN(+period)) {
41280            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
41281            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
41282            tmp = val; val = period; period = tmp;
41283        }
41284
41285        val = typeof val === 'string' ? +val : val;
41286        dur = createDuration(val, period);
41287        addSubtract(this, dur, direction);
41288        return this;
41289    };
41290}
41291
41292function addSubtract (mom, duration, isAdding, updateOffset) {
41293    var milliseconds = duration._milliseconds,
41294        days = absRound(duration._days),
41295        months = absRound(duration._months);
41296
41297    if (!mom.isValid()) {
41298        // No op
41299        return;
41300    }
41301
41302    updateOffset = updateOffset == null ? true : updateOffset;
41303
41304    if (milliseconds) {
41305        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
41306    }
41307    if (days) {
41308        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
41309    }
41310    if (months) {
41311        setMonth(mom, get(mom, 'Month') + months * isAdding);
41312    }
41313    if (updateOffset) {
41314        hooks.updateOffset(mom, days || months);
41315    }
41316}
41317
41318var add      = createAdder(1, 'add');
41319var subtract = createAdder(-1, 'subtract');
41320
41321function getCalendarFormat(myMoment, now) {
41322    var diff = myMoment.diff(now, 'days', true);
41323    return diff < -6 ? 'sameElse' :
41324            diff < -1 ? 'lastWeek' :
41325            diff < 0 ? 'lastDay' :
41326            diff < 1 ? 'sameDay' :
41327            diff < 2 ? 'nextDay' :
41328            diff < 7 ? 'nextWeek' : 'sameElse';
41329}
41330
41331function calendar$1 (time, formats) {
41332    // We want to compare the start of today, vs this.
41333    // Getting start-of-today depends on whether we're local/utc/offset or not.
41334    var now = time || createLocal(),
41335        sod = cloneWithOffset(now, this).startOf('day'),
41336        format = hooks.calendarFormat(this, sod) || 'sameElse';
41337
41338    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
41339
41340    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
41341}
41342
41343function clone () {
41344    return new Moment(this);
41345}
41346
41347function isAfter (input, units) {
41348    var localInput = isMoment(input) ? input : createLocal(input);
41349    if (!(this.isValid() && localInput.isValid())) {
41350        return false;
41351    }
41352    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
41353    if (units === 'millisecond') {
41354        return this.valueOf() > localInput.valueOf();
41355    } else {
41356        return localInput.valueOf() < this.clone().startOf(units).valueOf();
41357    }
41358}
41359
41360function isBefore (input, units) {
41361    var localInput = isMoment(input) ? input : createLocal(input);
41362    if (!(this.isValid() && localInput.isValid())) {
41363        return false;
41364    }
41365    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
41366    if (units === 'millisecond') {
41367        return this.valueOf() < localInput.valueOf();
41368    } else {
41369        return this.clone().endOf(units).valueOf() < localInput.valueOf();
41370    }
41371}
41372
41373function isBetween (from, to, units, inclusivity) {
41374    inclusivity = inclusivity || '()';
41375    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
41376        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
41377}
41378
41379function isSame (input, units) {
41380    var localInput = isMoment(input) ? input : createLocal(input),
41381        inputMs;
41382    if (!(this.isValid() && localInput.isValid())) {
41383        return false;
41384    }
41385    units = normalizeUnits(units || 'millisecond');
41386    if (units === 'millisecond') {
41387        return this.valueOf() === localInput.valueOf();
41388    } else {
41389        inputMs = localInput.valueOf();
41390        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
41391    }
41392}
41393
41394function isSameOrAfter (input, units) {
41395    return this.isSame(input, units) || this.isAfter(input,units);
41396}
41397
41398function isSameOrBefore (input, units) {
41399    return this.isSame(input, units) || this.isBefore(input,units);
41400}
41401
41402function diff (input, units, asFloat) {
41403    var that,
41404        zoneDelta,
41405        delta, output;
41406
41407    if (!this.isValid()) {
41408        return NaN;
41409    }
41410
41411    that = cloneWithOffset(input, this);
41412
41413    if (!that.isValid()) {
41414        return NaN;
41415    }
41416
41417    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
41418
41419    units = normalizeUnits(units);
41420
41421    if (units === 'year' || units === 'month' || units === 'quarter') {
41422        output = monthDiff(this, that);
41423        if (units === 'quarter') {
41424            output = output / 3;
41425        } else if (units === 'year') {
41426            output = output / 12;
41427        }
41428    } else {
41429        delta = this - that;
41430        output = units === 'second' ? delta / 1e3 : // 1000
41431            units === 'minute' ? delta / 6e4 : // 1000 * 60
41432            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
41433            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
41434            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
41435            delta;
41436    }
41437    return asFloat ? output : absFloor(output);
41438}
41439
41440function monthDiff (a, b) {
41441    // difference in months
41442    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
41443        // b is in (anchor - 1 month, anchor + 1 month)
41444        anchor = a.clone().add(wholeMonthDiff, 'months'),
41445        anchor2, adjust;
41446
41447    if (b - anchor < 0) {
41448        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
41449        // linear across the month
41450        adjust = (b - anchor) / (anchor - anchor2);
41451    } else {
41452        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
41453        // linear across the month
41454        adjust = (b - anchor) / (anchor2 - anchor);
41455    }
41456
41457    //check for negative zero, return zero if negative zero
41458    return -(wholeMonthDiff + adjust) || 0;
41459}
41460
41461hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
41462hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
41463
41464function toString () {
41465    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
41466}
41467
41468function toISOString() {
41469    if (!this.isValid()) {
41470        return null;
41471    }
41472    var m = this.clone().utc();
41473    if (m.year() < 0 || m.year() > 9999) {
41474        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
41475    }
41476    if (isFunction(Date.prototype.toISOString)) {
41477        // native implementation is ~50x faster, use it when we can
41478        return this.toDate().toISOString();
41479    }
41480    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
41481}
41482
41483/**
41484 * Return a human readable representation of a moment that can
41485 * also be evaluated to get a new moment which is the same
41486 *
41487 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
41488 */
41489function inspect () {
41490    if (!this.isValid()) {
vendor: 4,700 bytes, lines 41491-41675
41491        return 'moment.invalid(/* ' + this._i + ' */)';
41492    }
41493    var func = 'moment';
41494    var zone = '';
41495    if (!this.isLocal()) {
41496        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
41497        zone = 'Z';
41498    }
41499    var prefix = '[' + func + '("]';
41500    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
41501    var datetime = '-MM-DD[T]HH:mm:ss.SSS';
41502    var suffix = zone + '[")]';
41503
41504    return this.format(prefix + year + datetime + suffix);
41505}
41506
41507function format (inputString) {
41508    if (!inputString) {
41509        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
41510    }
41511    var output = formatMoment(this, inputString);
41512    return this.localeData().postformat(output);
41513}
41514
41515function from (time, withoutSuffix) {
41516    if (this.isValid() &&
41517            ((isMoment(time) && time.isValid()) ||
41518             createLocal(time).isValid())) {
41519        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
41520    } else {
41521        return this.localeData().invalidDate();
41522    }
41523}
41524
41525function fromNow (withoutSuffix) {
41526    return this.from(createLocal(), withoutSuffix);
41527}
41528
41529function to (time, withoutSuffix) {
41530    if (this.isValid() &&
41531            ((isMoment(time) && time.isValid()) ||
41532             createLocal(time).isValid())) {
41533        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
41534    } else {
41535        return this.localeData().invalidDate();
41536    }
41537}
41538
41539function toNow (withoutSuffix) {
41540    return this.to(createLocal(), withoutSuffix);
41541}
41542
41543// If passed a locale key, it will set the locale for this
41544// instance.  Otherwise, it will return the locale configuration
41545// variables for this instance.
41546function locale (key) {
41547    var newLocaleData;
41548
41549    if (key === undefined) {
41550        return this._locale._abbr;
41551    } else {
41552        newLocaleData = getLocale(key);
41553        if (newLocaleData != null) {
41554            this._locale = newLocaleData;
41555        }
41556        return this;
41557    }
41558}
41559
41560var lang = deprecate(
41561    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
41562    function (key) {
41563        if (key === undefined) {
41564            return this.localeData();
41565        } else {
41566            return this.locale(key);
41567        }
41568    }
41569);
41570
41571function localeData () {
41572    return this._locale;
41573}
41574
41575function startOf (units) {
41576    units = normalizeUnits(units);
41577    // the following switch intentionally omits break keywords
41578    // to utilize falling through the cases.
41579    switch (units) {
41580        case 'year':
41581            this.month(0);
41582            /* falls through */
41583        case 'quarter':
41584        case 'month':
41585            this.date(1);
41586            /* falls through */
41587        case 'week':
41588        case 'isoWeek':
41589        case 'day':
41590        case 'date':
41591            this.hours(0);
41592            /* falls through */
41593        case 'hour':
41594            this.minutes(0);
41595            /* falls through */
41596        case 'minute':
41597            this.seconds(0);
41598            /* falls through */
41599        case 'second':
41600            this.milliseconds(0);
41601    }
41602
41603    // weeks are a special case
41604    if (units === 'week') {
41605        this.weekday(0);
41606    }
41607    if (units === 'isoWeek') {
41608        this.isoWeekday(1);
41609    }
41610
41611    // quarters are also special
41612    if (units === 'quarter') {
41613        this.month(Math.floor(this.month() / 3) * 3);
41614    }
41615
41616    return this;
41617}
41618
41619function endOf (units) {
41620    units = normalizeUnits(units);
41621    if (units === undefined || units === 'millisecond') {
41622        return this;
41623    }
41624
41625    // 'date' is an alias for 'day', so it should be considered as such.
41626    if (units === 'date') {
41627        units = 'day';
41628    }
41629
41630    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
41631}
41632
41633function valueOf () {
41634    return this._d.valueOf() - ((this._offset || 0) * 60000);
41635}
41636
41637function unix () {
41638    return Math.floor(this.valueOf() / 1000);
41639}
41640
41641function toDate () {
41642    return new Date(this.valueOf());
41643}
41644
41645function toArray () {
41646    var m = this;
41647    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
41648}
41649
41650function toObject () {
41651    var m = this;
41652    return {
41653        years: m.year(),
41654        months: m.month(),
41655        date: m.date(),
41656        hours: m.hours(),
41657        minutes: m.minutes(),
41658        seconds: m.seconds(),
41659        milliseconds: m.milliseconds()
41660    };
41661}
41662
41663function toJSON () {
41664    // new Date(NaN).toJSON() === null
41665    return this.isValid() ? this.toISOString() : null;
41666}
41667
41668function isValid$2 () {
41669    return isValid(this);
41670}
41671
41672function parsingFlags () {
41673    return extend({}, getParsingFlags(this));
41674}
41675
vendor: 11,965 bytes, lines 41676-42147
41676function invalidAt () {
41677    return getParsingFlags(this).overflow;
41678}
41679
41680function creationData() {
41681    return {
41682        input: this._i,
41683        format: this._f,
41684        locale: this._locale,
41685        isUTC: this._isUTC,
41686        strict: this._strict
41687    };
41688}
41689
41690// FORMATTING
41691
41692addFormatToken(0, ['gg', 2], 0, function () {
41693    return this.weekYear() % 100;
41694});
41695
41696addFormatToken(0, ['GG', 2], 0, function () {
41697    return this.isoWeekYear() % 100;
41698});
41699
41700function addWeekYearFormatToken (token, getter) {
41701    addFormatToken(0, [token, token.length], 0, getter);
41702}
41703
41704addWeekYearFormatToken('gggg',     'weekYear');
41705addWeekYearFormatToken('ggggg',    'weekYear');
41706addWeekYearFormatToken('GGGG',  'isoWeekYear');
41707addWeekYearFormatToken('GGGGG', 'isoWeekYear');
41708
41709// ALIASES
41710
41711addUnitAlias('weekYear', 'gg');
41712addUnitAlias('isoWeekYear', 'GG');
41713
41714// PRIORITY
41715
41716addUnitPriority('weekYear', 1);
41717addUnitPriority('isoWeekYear', 1);
41718
41719
41720// PARSING
41721
41722addRegexToken('G',      matchSigned);
41723addRegexToken('g',      matchSigned);
41724addRegexToken('GG',     match1to2, match2);
41725addRegexToken('gg',     match1to2, match2);
41726addRegexToken('GGGG',   match1to4, match4);
41727addRegexToken('gggg',   match1to4, match4);
41728addRegexToken('GGGGG',  match1to6, match6);
41729addRegexToken('ggggg',  match1to6, match6);
41730
41731addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
41732    week[token.substr(0, 2)] = toInt(input);
41733});
41734
41735addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
41736    week[token] = hooks.parseTwoDigitYear(input);
41737});
41738
41739// MOMENTS
41740
41741function getSetWeekYear (input) {
41742    return getSetWeekYearHelper.call(this,
41743            input,
41744            this.week(),
41745            this.weekday(),
41746            this.localeData()._week.dow,
41747            this.localeData()._week.doy);
41748}
41749
41750function getSetISOWeekYear (input) {
41751    return getSetWeekYearHelper.call(this,
41752            input, this.isoWeek(), this.isoWeekday(), 1, 4);
41753}
41754
41755function getISOWeeksInYear () {
41756    return weeksInYear(this.year(), 1, 4);
41757}
41758
41759function getWeeksInYear () {
41760    var weekInfo = this.localeData()._week;
41761    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
41762}
41763
41764function getSetWeekYearHelper(input, week, weekday, dow, doy) {
41765    var weeksTarget;
41766    if (input == null) {
41767        return weekOfYear(this, dow, doy).year;
41768    } else {
41769        weeksTarget = weeksInYear(input, dow, doy);
41770        if (week > weeksTarget) {
41771            week = weeksTarget;
41772        }
41773        return setWeekAll.call(this, input, week, weekday, dow, doy);
41774    }
41775}
41776
41777function setWeekAll(weekYear, week, weekday, dow, doy) {
41778    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
41779        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
41780
41781    this.year(date.getUTCFullYear());
41782    this.month(date.getUTCMonth());
41783    this.date(date.getUTCDate());
41784    return this;
41785}
41786
41787// FORMATTING
41788
41789addFormatToken('Q', 0, 'Qo', 'quarter');
41790
41791// ALIASES
41792
41793addUnitAlias('quarter', 'Q');
41794
41795// PRIORITY
41796
41797addUnitPriority('quarter', 7);
41798
41799// PARSING
41800
41801addRegexToken('Q', match1);
41802addParseToken('Q', function (input, array) {
41803    array[MONTH] = (toInt(input) - 1) * 3;
41804});
41805
41806// MOMENTS
41807
41808function getSetQuarter (input) {
41809    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
41810}
41811
41812// FORMATTING
41813
41814addFormatToken('D', ['DD', 2], 'Do', 'date');
41815
41816// ALIASES
41817
41818addUnitAlias('date', 'D');
41819
41820// PRIOROITY
41821addUnitPriority('date', 9);
41822
41823// PARSING
41824
41825addRegexToken('D',  match1to2);
41826addRegexToken('DD', match1to2, match2);
41827addRegexToken('Do', function (isStrict, locale) {
41828    // TODO: Remove "ordinalParse" fallback in next major release.
41829    return isStrict ?
41830      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
41831      locale._dayOfMonthOrdinalParseLenient;
41832});
41833
41834addParseToken(['D', 'DD'], DATE);
41835addParseToken('Do', function (input, array) {
41836    array[DATE] = toInt(input.match(match1to2)[0], 10);
41837});
41838
41839// MOMENTS
41840
41841var getSetDayOfMonth = makeGetSet('Date', true);
41842
41843// FORMATTING
41844
41845addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
41846
41847// ALIASES
41848
41849addUnitAlias('dayOfYear', 'DDD');
41850
41851// PRIORITY
41852addUnitPriority('dayOfYear', 4);
41853
41854// PARSING
41855
41856addRegexToken('DDD',  match1to3);
41857addRegexToken('DDDD', match3);
41858addParseToken(['DDD', 'DDDD'], function (input, array, config) {
41859    config._dayOfYear = toInt(input);
41860});
41861
41862// HELPERS
41863
41864// MOMENTS
41865
41866function getSetDayOfYear (input) {
41867    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
41868    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
41869}
41870
41871// FORMATTING
41872
41873addFormatToken('m', ['mm', 2], 0, 'minute');
41874
41875// ALIASES
41876
41877addUnitAlias('minute', 'm');
41878
41879// PRIORITY
41880
41881addUnitPriority('minute', 14);
41882
41883// PARSING
41884
41885addRegexToken('m',  match1to2);
41886addRegexToken('mm', match1to2, match2);
41887addParseToken(['m', 'mm'], MINUTE);
41888
41889// MOMENTS
41890
41891var getSetMinute = makeGetSet('Minutes', false);
41892
41893// FORMATTING
41894
41895addFormatToken('s', ['ss', 2], 0, 'second');
41896
41897// ALIASES
41898
41899addUnitAlias('second', 's');
41900
41901// PRIORITY
41902
41903addUnitPriority('second', 15);
41904
41905// PARSING
41906
41907addRegexToken('s',  match1to2);
41908addRegexToken('ss', match1to2, match2);
41909addParseToken(['s', 'ss'], SECOND);
41910
41911// MOMENTS
41912
41913var getSetSecond = makeGetSet('Seconds', false);
41914
41915// FORMATTING
41916
41917addFormatToken('S', 0, 0, function () {
41918    return ~~(this.millisecond() / 100);
41919});
41920
41921addFormatToken(0, ['SS', 2], 0, function () {
41922    return ~~(this.millisecond() / 10);
41923});
41924
41925addFormatToken(0, ['SSS', 3], 0, 'millisecond');
41926addFormatToken(0, ['SSSS', 4], 0, function () {
41927    return this.millisecond() * 10;
41928});
41929addFormatToken(0, ['SSSSS', 5], 0, function () {
41930    return this.millisecond() * 100;
41931});
41932addFormatToken(0, ['SSSSSS', 6], 0, function () {
41933    return this.millisecond() * 1000;
41934});
41935addFormatToken(0, ['SSSSSSS', 7], 0, function () {
41936    return this.millisecond() * 10000;
41937});
41938addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
41939    return this.millisecond() * 100000;
41940});
41941addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
41942    return this.millisecond() * 1000000;
41943});
41944
41945
41946// ALIASES
41947
41948addUnitAlias('millisecond', 'ms');
41949
41950// PRIORITY
41951
41952addUnitPriority('millisecond', 16);
41953
41954// PARSING
41955
41956addRegexToken('S',    match1to3, match1);
41957addRegexToken('SS',   match1to3, match2);
41958addRegexToken('SSS',  match1to3, match3);
41959
41960var token;
41961for (token = 'SSSS'; token.length <= 9; token += 'S') {
41962    addRegexToken(token, matchUnsigned);
41963}
41964
41965function parseMs(input, array) {
41966    array[MILLISECOND] = toInt(('0.' + input) * 1000);
41967}
41968
41969for (token = 'S'; token.length <= 9; token += 'S') {
41970    addParseToken(token, parseMs);
41971}
41972// MOMENTS
41973
41974var getSetMillisecond = makeGetSet('Milliseconds', false);
41975
41976// FORMATTING
41977
41978addFormatToken('z',  0, 0, 'zoneAbbr');
41979addFormatToken('zz', 0, 0, 'zoneName');
41980
41981// MOMENTS
41982
41983function getZoneAbbr () {
41984    return this._isUTC ? 'UTC' : '';
41985}
41986
41987function getZoneName () {
41988    return this._isUTC ? 'Coordinated Universal Time' : '';
41989}
41990
41991var proto = Moment.prototype;
41992
41993proto.add               = add;
41994proto.calendar          = calendar$1;
41995proto.clone             = clone;
41996proto.diff              = diff;
41997proto.endOf             = endOf;
41998proto.format            = format;
41999proto.from              = from;
42000proto.fromNow           = fromNow;
42001proto.to                = to;
42002proto.toNow             = toNow;
42003proto.get               = stringGet;
42004proto.invalidAt         = invalidAt;
42005proto.isAfter           = isAfter;
42006proto.isBefore          = isBefore;
42007proto.isBetween         = isBetween;
42008proto.isSame            = isSame;
42009proto.isSameOrAfter     = isSameOrAfter;
42010proto.isSameOrBefore    = isSameOrBefore;
42011proto.isValid           = isValid$2;
42012proto.lang              = lang;
42013proto.locale            = locale;
42014proto.localeData        = localeData;
42015proto.max               = prototypeMax;
42016proto.min               = prototypeMin;
42017proto.parsingFlags      = parsingFlags;
42018proto.set               = stringSet;
42019proto.startOf           = startOf;
42020proto.subtract          = subtract;
42021proto.toArray           = toArray;
42022proto.toObject          = toObject;
42023proto.toDate            = toDate;
42024proto.toISOString       = toISOString;
42025proto.inspect           = inspect;
42026proto.toJSON            = toJSON;
42027proto.toString          = toString;
42028proto.unix              = unix;
42029proto.valueOf           = valueOf;
42030proto.creationData      = creationData;
42031
42032// Year
42033proto.year       = getSetYear;
42034proto.isLeapYear = getIsLeapYear;
42035
42036// Week Year
42037proto.weekYear    = getSetWeekYear;
42038proto.isoWeekYear = getSetISOWeekYear;
42039
42040// Quarter
42041proto.quarter = proto.quarters = getSetQuarter;
42042
42043// Month
42044proto.month       = getSetMonth;
42045proto.daysInMonth = getDaysInMonth;
42046
42047// Week
42048proto.week           = proto.weeks        = getSetWeek;
42049proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
42050proto.weeksInYear    = getWeeksInYear;
42051proto.isoWeeksInYear = getISOWeeksInYear;
42052
42053// Day
42054proto.date       = getSetDayOfMonth;
42055proto.day        = proto.days             = getSetDayOfWeek;
42056proto.weekday    = getSetLocaleDayOfWeek;
42057proto.isoWeekday = getSetISODayOfWeek;
42058proto.dayOfYear  = getSetDayOfYear;
42059
42060// Hour
42061proto.hour = proto.hours = getSetHour;
42062
42063// Minute
42064proto.minute = proto.minutes = getSetMinute;
42065
42066// Second
42067proto.second = proto.seconds = getSetSecond;
42068
42069// Millisecond
42070proto.millisecond = proto.milliseconds = getSetMillisecond;
42071
42072// Offset
42073proto.utcOffset            = getSetOffset;
42074proto.utc                  = setOffsetToUTC;
42075proto.local                = setOffsetToLocal;
42076proto.parseZone            = setOffsetToParsedOffset;
42077proto.hasAlignedHourOffset = hasAlignedHourOffset;
42078proto.isDST                = isDaylightSavingTime;
42079proto.isLocal              = isLocal;
42080proto.isUtcOffset          = isUtcOffset;
42081proto.isUtc                = isUtc;
42082proto.isUTC                = isUtc;
42083
42084// Timezone
42085proto.zoneAbbr = getZoneAbbr;
42086proto.zoneName = getZoneName;
42087
42088// Deprecations
42089proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
42090proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
42091proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
42092proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
42093proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
42094
42095function createUnix (input) {
42096    return createLocal(input * 1000);
42097}
42098
42099function createInZone () {
42100    return createLocal.apply(null, arguments).parseZone();
42101}
42102
42103function preParsePostFormat (string) {
42104    return string;
42105}
42106
42107var proto$1 = Locale.prototype;
42108
42109proto$1.calendar        = calendar;
42110proto$1.longDateFormat  = longDateFormat;
42111proto$1.invalidDate     = invalidDate;
42112proto$1.ordinal         = ordinal;
42113proto$1.preparse        = preParsePostFormat;
42114proto$1.postformat      = preParsePostFormat;
42115proto$1.relativeTime    = relativeTime;
42116proto$1.pastFuture      = pastFuture;
42117proto$1.set             = set;
42118
42119// Month
42120proto$1.months            =        localeMonths;
42121proto$1.monthsShort       =        localeMonthsShort;
42122proto$1.monthsParse       =        localeMonthsParse;
42123proto$1.monthsRegex       = monthsRegex;
42124proto$1.monthsShortRegex  = monthsShortRegex;
42125
42126// Week
42127proto$1.week = localeWeek;
42128proto$1.firstDayOfYear = localeFirstDayOfYear;
42129proto$1.firstDayOfWeek = localeFirstDayOfWeek;
42130
42131// Day of Week
42132proto$1.weekdays       =        localeWeekdays;
42133proto$1.weekdaysMin    =        localeWeekdaysMin;
42134proto$1.weekdaysShort  =        localeWeekdaysShort;
42135proto$1.weekdaysParse  =        localeWeekdaysParse;
42136
42137proto$1.weekdaysRegex       =        weekdaysRegex;
42138proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
42139proto$1.weekdaysMinRegex    =        weekdaysMinRegex;
42140
42141// Hours
42142proto$1.isPM = localeIsPM;
42143proto$1.meridiem = localeMeridiem;
42144
42145function get$1 (format, index, field, setter) {
42146    var locale = getLocale();
42147    var utc = createUTC().set(setter, index);
vendor: 7,873 bytes, lines 42148-42436
42148    return locale[field](utc, format);
42149}
42150
42151function listMonthsImpl (format, index, field) {
42152    if (isNumber(format)) {
42153        index = format;
42154        format = undefined;
42155    }
42156
42157    format = format || '';
42158
42159    if (index != null) {
42160        return get$1(format, index, field, 'month');
42161    }
42162
42163    var i;
42164    var out = [];
42165    for (i = 0; i < 12; i++) {
42166        out[i] = get$1(format, i, field, 'month');
42167    }
42168    return out;
42169}
42170
42171// ()
42172// (5)
42173// (fmt, 5)
42174// (fmt)
42175// (true)
42176// (true, 5)
42177// (true, fmt, 5)
42178// (true, fmt)
42179function listWeekdaysImpl (localeSorted, format, index, field) {
42180    if (typeof localeSorted === 'boolean') {
42181        if (isNumber(format)) {
42182            index = format;
42183            format = undefined;
42184        }
42185
42186        format = format || '';
42187    } else {
42188        format = localeSorted;
42189        index = format;
42190        localeSorted = false;
42191
42192        if (isNumber(format)) {
42193            index = format;
42194            format = undefined;
42195        }
42196
42197        format = format || '';
42198    }
42199
42200    var locale = getLocale(),
42201        shift = localeSorted ? locale._week.dow : 0;
42202
42203    if (index != null) {
42204        return get$1(format, (index + shift) % 7, field, 'day');
42205    }
42206
42207    var i;
42208    var out = [];
42209    for (i = 0; i < 7; i++) {
42210        out[i] = get$1(format, (i + shift) % 7, field, 'day');
42211    }
42212    return out;
42213}
42214
42215function listMonths (format, index) {
42216    return listMonthsImpl(format, index, 'months');
42217}
42218
42219function listMonthsShort (format, index) {
42220    return listMonthsImpl(format, index, 'monthsShort');
42221}
42222
42223function listWeekdays (localeSorted, format, index) {
42224    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
42225}
42226
42227function listWeekdaysShort (localeSorted, format, index) {
42228    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
42229}
42230
42231function listWeekdaysMin (localeSorted, format, index) {
42232    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
42233}
42234
42235getSetGlobalLocale('en', {
42236    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
42237    ordinal : function (number) {
42238        var b = number % 10,
42239            output = (toInt(number % 100 / 10) === 1) ? 'th' :
42240            (b === 1) ? 'st' :
42241            (b === 2) ? 'nd' :
42242            (b === 3) ? 'rd' : 'th';
42243        return number + output;
42244    }
42245});
42246
42247// Side effect imports
42248hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
42249hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
42250
42251var mathAbs = Math.abs;
42252
42253function abs () {
42254    var data           = this._data;
42255
42256    this._milliseconds = mathAbs(this._milliseconds);
42257    this._days         = mathAbs(this._days);
42258    this._months       = mathAbs(this._months);
42259
42260    data.milliseconds  = mathAbs(data.milliseconds);
42261    data.seconds       = mathAbs(data.seconds);
42262    data.minutes       = mathAbs(data.minutes);
42263    data.hours         = mathAbs(data.hours);
42264    data.months        = mathAbs(data.months);
42265    data.years         = mathAbs(data.years);
42266
42267    return this;
42268}
42269
42270function addSubtract$1 (duration, input, value, direction) {
42271    var other = createDuration(input, value);
42272
42273    duration._milliseconds += direction * other._milliseconds;
42274    duration._days         += direction * other._days;
42275    duration._months       += direction * other._months;
42276
42277    return duration._bubble();
42278}
42279
42280// supports only 2.0-style add(1, 's') or add(duration)
42281function add$1 (input, value) {
42282    return addSubtract$1(this, input, value, 1);
42283}
42284
42285// supports only 2.0-style subtract(1, 's') or subtract(duration)
42286function subtract$1 (input, value) {
42287    return addSubtract$1(this, input, value, -1);
42288}
42289
42290function absCeil (number) {
42291    if (number < 0) {
42292        return Math.floor(number);
42293    } else {
42294        return Math.ceil(number);
42295    }
42296}
42297
42298function bubble () {
42299    var milliseconds = this._milliseconds;
42300    var days         = this._days;
42301    var months       = this._months;
42302    var data         = this._data;
42303    var seconds, minutes, hours, years, monthsFromDays;
42304
42305    // if we have a mix of positive and negative values, bubble down first
42306    // check: https://github.com/moment/moment/issues/2166
42307    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
42308            (milliseconds <= 0 && days <= 0 && months <= 0))) {
42309        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
42310        days = 0;
42311        months = 0;
42312    }
42313
42314    // The following code bubbles up values, see the tests for
42315    // examples of what that means.
42316    data.milliseconds = milliseconds % 1000;
42317
42318    seconds           = absFloor(milliseconds / 1000);
42319    data.seconds      = seconds % 60;
42320
42321    minutes           = absFloor(seconds / 60);
42322    data.minutes      = minutes % 60;
42323
42324    hours             = absFloor(minutes / 60);
42325    data.hours        = hours % 24;
42326
42327    days += absFloor(hours / 24);
42328
42329    // convert days to months
42330    monthsFromDays = absFloor(daysToMonths(days));
42331    months += monthsFromDays;
42332    days -= absCeil(monthsToDays(monthsFromDays));
42333
42334    // 12 months -> 1 year
42335    years = absFloor(months / 12);
42336    months %= 12;
42337
42338    data.days   = days;
42339    data.months = months;
42340    data.years  = years;
42341
42342    return this;
42343}
42344
42345function daysToMonths (days) {
42346    // 400 years have 146097 days (taking into account leap year rules)
42347    // 400 years have 12 months === 4800
42348    return days * 4800 / 146097;
42349}
42350
42351function monthsToDays (months) {
42352    // the reverse of daysToMonths
42353    return months * 146097 / 4800;
42354}
42355
42356function as (units) {
42357    if (!this.isValid()) {
42358        return NaN;
42359    }
42360    var days;
42361    var months;
42362    var milliseconds = this._milliseconds;
42363
42364    units = normalizeUnits(units);
42365
42366    if (units === 'month' || units === 'year') {
42367        days   = this._days   + milliseconds / 864e5;
42368        months = this._months + daysToMonths(days);
42369        return units === 'month' ? months : months / 12;
42370    } else {
42371        // handle milliseconds separately because of floating point math errors (issue #1867)
42372        days = this._days + Math.round(monthsToDays(this._months));
42373        switch (units) {
42374            case 'week'   : return days / 7     + milliseconds / 6048e5;
42375            case 'day'    : return days         + milliseconds / 864e5;
42376            case 'hour'   : return days * 24    + milliseconds / 36e5;
42377            case 'minute' : return days * 1440  + milliseconds / 6e4;
42378            case 'second' : return days * 86400 + milliseconds / 1000;
42379            // Math.floor prevents floating point math errors here
42380            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
42381            default: throw new Error('Unknown unit ' + units);
42382        }
42383    }
42384}
42385
42386// TODO: Use this.as('ms')?
42387function valueOf$1 () {
42388    if (!this.isValid()) {
42389        return NaN;
42390    }
42391    return (
42392        this._milliseconds +
42393        this._days * 864e5 +
42394        (this._months % 12) * 2592e6 +
42395        toInt(this._months / 12) * 31536e6
42396    );
42397}
42398
42399function makeAs (alias) {
42400    return function () {
42401        return this.as(alias);
42402    };
42403}
42404
42405var asMilliseconds = makeAs('ms');
42406var asSeconds      = makeAs('s');
42407var asMinutes      = makeAs('m');
42408var asHours        = makeAs('h');
42409var asDays         = makeAs('d');
42410var asWeeks        = makeAs('w');
42411var asMonths       = makeAs('M');
42412var asYears        = makeAs('y');
42413
42414function get$2 (units) {
42415    units = normalizeUnits(units);
42416    return this.isValid() ? this[units + 's']() : NaN;
42417}
42418
42419function makeGetter(name) {
42420    return function () {
42421        return this.isValid() ? this._data[name] : NaN;
42422    };
42423}
42424
42425var milliseconds = makeGetter('milliseconds');
42426var seconds      = makeGetter('seconds');
42427var minutes      = makeGetter('minutes');
42428var hours        = makeGetter('hours');
42429var days         = makeGetter('days');
42430var months       = makeGetter('months');
42431var years        = makeGetter('years');
42432
42433function weeks () {
42434    return absFloor(this.days() / 7);
42435}
42436
vendor: 5,863 bytes, lines 42437-42624
42437var round = Math.round;
42438var thresholds = {
42439    ss: 44,         // a few seconds to seconds
42440    s : 45,         // seconds to minute
42441    m : 45,         // minutes to hour
42442    h : 22,         // hours to day
42443    d : 26,         // days to month
42444    M : 11          // months to year
42445};
42446
42447// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
42448function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
42449    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
42450}
42451
42452function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
42453    var duration = createDuration(posNegDuration).abs();
42454    var seconds  = round(duration.as('s'));
42455    var minutes  = round(duration.as('m'));
42456    var hours    = round(duration.as('h'));
42457    var days     = round(duration.as('d'));
42458    var months   = round(duration.as('M'));
42459    var years    = round(duration.as('y'));
42460
42461    var a = seconds <= thresholds.ss && ['s', seconds]  ||
42462            seconds < thresholds.s   && ['ss', seconds] ||
42463            minutes <= 1             && ['m']           ||
42464            minutes < thresholds.m   && ['mm', minutes] ||
42465            hours   <= 1             && ['h']           ||
42466            hours   < thresholds.h   && ['hh', hours]   ||
42467            days    <= 1             && ['d']           ||
42468            days    < thresholds.d   && ['dd', days]    ||
42469            months  <= 1             && ['M']           ||
42470            months  < thresholds.M   && ['MM', months]  ||
42471            years   <= 1             && ['y']           || ['yy', years];
42472
42473    a[2] = withoutSuffix;
42474    a[3] = +posNegDuration > 0;
42475    a[4] = locale;
42476    return substituteTimeAgo.apply(null, a);
42477}
42478
42479// This function allows you to set the rounding function for relative time strings
42480function getSetRelativeTimeRounding (roundingFunction) {
42481    if (roundingFunction === undefined) {
42482        return round;
42483    }
42484    if (typeof(roundingFunction) === 'function') {
42485        round = roundingFunction;
42486        return true;
42487    }
42488    return false;
42489}
42490
42491// This function allows you to set a threshold for relative time strings
42492function getSetRelativeTimeThreshold (threshold, limit) {
42493    if (thresholds[threshold] === undefined) {
42494        return false;
42495    }
42496    if (limit === undefined) {
42497        return thresholds[threshold];
42498    }
42499    thresholds[threshold] = limit;
42500    if (threshold === 's') {
42501        thresholds.ss = limit - 1;
42502    }
42503    return true;
42504}
42505
42506function humanize (withSuffix) {
42507    if (!this.isValid()) {
42508        return this.localeData().invalidDate();
42509    }
42510
42511    var locale = this.localeData();
42512    var output = relativeTime$1(this, !withSuffix, locale);
42513
42514    if (withSuffix) {
42515        output = locale.pastFuture(+this, output);
42516    }
42517
42518    return locale.postformat(output);
42519}
42520
42521var abs$1 = Math.abs;
42522
42523function toISOString$1() {
42524    // for ISO strings we do not use the normal bubbling rules:
42525    //  * milliseconds bubble up until they become hours
42526    //  * days do not bubble at all
42527    //  * months bubble up until they become years
42528    // This is because there is no context-free conversion between hours and days
42529    // (think of clock changes)
42530    // and also not between days and months (28-31 days per month)
42531    if (!this.isValid()) {
42532        return this.localeData().invalidDate();
42533    }
42534
42535    var seconds = abs$1(this._milliseconds) / 1000;
42536    var days         = abs$1(this._days);
42537    var months       = abs$1(this._months);
42538    var minutes, hours, years;
42539
42540    // 3600 seconds -> 60 minutes -> 1 hour
42541    minutes           = absFloor(seconds / 60);
42542    hours             = absFloor(minutes / 60);
42543    seconds %= 60;
42544    minutes %= 60;
42545
42546    // 12 months -> 1 year
42547    years  = absFloor(months / 12);
42548    months %= 12;
42549
42550
42551    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
42552    var Y = years;
42553    var M = months;
42554    var D = days;
42555    var h = hours;
42556    var m = minutes;
42557    var s = seconds;
42558    var total = this.asSeconds();
42559
42560    if (!total) {
42561        // this is the same as C#'s (Noda) and python (isodate)...
42562        // but not other JS (goog.date)
42563        return 'P0D';
42564    }
42565
42566    return (total < 0 ? '-' : '') +
42567        'P' +
42568        (Y ? Y + 'Y' : '') +
42569        (M ? M + 'M' : '') +
42570        (D ? D + 'D' : '') +
42571        ((h || m || s) ? 'T' : '') +
42572        (h ? h + 'H' : '') +
42573        (m ? m + 'M' : '') +
42574        (s ? s + 'S' : '');
42575}
42576
42577var proto$2 = Duration.prototype;
42578
42579proto$2.isValid        = isValid$1;
42580proto$2.abs            = abs;
42581proto$2.add            = add$1;
42582proto$2.subtract       = subtract$1;
42583proto$2.as             = as;
42584proto$2.asMilliseconds = asMilliseconds;
42585proto$2.asSeconds      = asSeconds;
42586proto$2.asMinutes      = asMinutes;
42587proto$2.asHours        = asHours;
42588proto$2.asDays         = asDays;
42589proto$2.asWeeks        = asWeeks;
42590proto$2.asMonths       = asMonths;
42591proto$2.asYears        = asYears;
42592proto$2.valueOf        = valueOf$1;
42593proto$2._bubble        = bubble;
42594proto$2.get            = get$2;
42595proto$2.milliseconds   = milliseconds;
42596proto$2.seconds        = seconds;
42597proto$2.minutes        = minutes;
42598proto$2.hours          = hours;
42599proto$2.days           = days;
42600proto$2.weeks          = weeks;
42601proto$2.months         = months;
42602proto$2.years          = years;
42603proto$2.humanize       = humanize;
42604proto$2.toISOString    = toISOString$1;
42605proto$2.toString       = toISOString$1;
42606proto$2.toJSON         = toISOString$1;
42607proto$2.locale         = locale;
42608proto$2.localeData     = localeData;
42609
42610// Deprecations
42611proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
42612proto$2.lang = lang;
42613
42614// Side effect imports
42615
42616// FORMATTING
42617
42618addFormatToken('X', 0, 0, 'unix');
42619addFormatToken('x', 0, 0, 'valueOf');
42620
42621// PARSING
42622
42623addRegexToken('x', matchSigned);
42624addRegexToken('X', matchTimestamp);
42625addParseToken('X', function (input, array, config) {
42626    config._d = new Date(parseFloat(input, 10) * 1000);
42627});
42628addParseToken('x', function (input, array, config) {
42629    config._d = new Date(toInt(input));
42630});
42631
42632// Side effect imports
42633
42634
42635hooks.version = '2.18.1';
42636
42637setHookCallback(createLocal);
42638
42639hooks.fn                    = proto;
42640hooks.min                   = min;
42641hooks.max                   = max;
42642hooks.now                   = now;
42643hooks.utc                   = createUTC;
42644hooks.unix                  = createUnix;
42645hooks.months                = listMonths;
42646hooks.isDate                = isDate;
42647hooks.locale                = getSetGlobalLocale;
42648hooks.invalid               = createInvalid;
42649hooks.duration              = createDuration;
42650hooks.isMoment              = isMoment;
42651hooks.weekdays              = listWeekdays;
42652hooks.parseZone             = createInZone;
42653hooks.localeData            = getLocale;
42654hooks.isDuration            = isDuration;
42655hooks.monthsShort           = listMonthsShort;
42656hooks.weekdaysMin           = listWeekdaysMin;
42657hooks.defineLocale          = defineLocale;
42658hooks.updateLocale          = updateLocale;
42659hooks.locales               = listLocales;
42660hooks.weekdaysShort         = listWeekdaysShort;
42661hooks.normalizeUnits        = normalizeUnits;
42662hooks.relativeTimeRounding = getSetRelativeTimeRounding;
42663hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
42664hooks.calendarFormat        = getCalendarFormat;
42665hooks.prototype             = proto;
42666
42667return hooks;
42668
42669})));
42670!function(a,i){"use strict";"object"==typeof module&&module.exports?module.exports=i(require("moment")):"function"==typeof define&&define.amd?define(["moment"],i):i(a.moment)}(this,function(c){"use strict";var i,A={},n={},s={},u={};c&&"string"==typeof c.version||L("Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/");var a=c.version.split("."),e=+a[0],r=+a[1];function t(a){return 96<a?a-87:64<a?a-29:a-48}function o(a){var i=0,e=a.split("."),r=e[0],o=e[1]||"",c=1,A=0,n=1;for(45===a.charCodeAt(0)&&(n=-(i=1));i<r.length;i++)A=60*A+t(r.charCodeAt(i));for(i=0;i<o.length;i++)c/=60,A+=t(o.charCodeAt(i))*c;return A*n}function m(a){for(var i=0;i<a.length;i++)a[i]=o(a[i])}function f(a,i){var e,r=[];for(e=0;e<i.length;e++)r[e]=a[i[e]];return r}function l(a){var i=a.split("|"),e=i[2].split(" "),r=i[3].split(""),o=i[4].split(" ");return m(e),m(r),m(o),function(a,i){for(var e=0;e<i;e++)a[e]=Math.round((a[e-1]||0)+6e4*a[e]);a[i-1]=1/0}(o,r.length),{name:i[0],abbrs:f(i[1].split(" "),r),offsets:f(e,r),untils:o,population:0|i[5]}}function p(a){a&&this._set(l(a))}function M(a){var i=a.toTimeString(),e=i.match(/\([a-z ]+\)/i);"GMT"===(e=e&&e[0]?(e=e[0].match(/[A-Z]/g))?e.join(""):void 0:(e=i.match(/[A-Z]{3,5}/g))?e[0]:void 0)&&(e=void 0),this.at=+a,this.abbr=e,this.offset=a.getTimezoneOffset()}function b(a){this.zone=a,this.offsetScore=0,this.abbrScore=0}function d(a,i){for(var e,r;r=6e4*((i.at-a.at)/12e4|0);)(e=new M(new Date(a.at+r))).offset===a.offset?a=e:i=e;return a}function h(a,i){return a.offsetScore!==i.offsetScore?a.offsetScore-i.offsetScore:a.abbrScore!==i.abbrScore?a.abbrScore-i.abbrScore:i.zone.population-a.zone.population}function z(a,i){var e,r;for(m(i),e=0;e<i.length;e++)r=i[e],u[r]=u[r]||{},u[r][a]=!0}function E(){try{var a=Intl.DateTimeFormat().resolvedOptions().timeZone;if(a&&3<a.length){var i=s[g(a)];if(i)return i;L("Moment Timezone found "+a+" from the Intl api, but did not have that data loaded.")}}catch(a){}var e,r,o,c=function(){var a,i,e,r=(new Date).getFullYear()-2,o=new M(new Date(r,0,1)),c=[o];for(e=1;e<48;e++)(i=new M(new Date(r,e,1))).offset!==o.offset&&(a=d(o,i),c.push(a),c.push(new M(new Date(a.at+6e4)))),o=i;for(e=0;e<4;e++)c.push(new M(new Date(r+e,0,1))),c.push(new M(new Date(r+e,6,1)));return c}(),A=c.length,n=function(a){var i,e,r,o=a.length,c={},A=[];for(i=0;i<o;i++)for(e in r=u[a[i].offset]||{})r.hasOwnProperty(e)&&(c[e]=!0);for(i in c)c.hasOwnProperty(i)&&A.push(s[i]);return A}(c),t=[];for(r=0;r<n.length;r++){for(e=new b(P(n[r]),A),o=0;o<A;o++)e.scoreOffsetAt(c[o]);t.push(e)}return t.sort(h),0<t.length?t[0].zone.name:void 0}
vendor: 4,150 bytes, line 42670
42670function g(a){return(a||"").toLowerCase().replace(/\//g,"_")}function T(a){var i,e,r,o;for("string"==typeof a&&(a=[a]),i=0;i<a.length;i++)o=g(e=(r=a[i].split("|"))[0]),A[o]=a[i],s[o]=e,z(o,r[2].split(" "))}function P(a,i){a=g(a);var e,r=A[a];return r instanceof p?r:"string"==typeof r?(r=new p(r),A[a]=r):n[a]&&i!==P&&(e=P(n[a],P))?((r=A[a]=new p)._set(e),r.name=s[a],r):null}function S(a){var i,e,r,o;for("string"==typeof a&&(a=[a]),i=0;i<a.length;i++)r=g((e=a[i].split("|"))[0]),o=g(e[1]),n[r]=o,s[r]=e[0],n[o]=r,s[o]=e[1]}function _(a){T(a.zones),S(a.links),B.dataVersion=a.version}function k(a){var i="X"===a._f||"x"===a._f;return!(!a._a||void 0!==a._tzm||i)}function L(a){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(a)}function B(a){var i=Array.prototype.slice.call(arguments,0,-1),e=arguments[arguments.length-1],r=P(e),o=c.utc.apply(null,i);return r&&!c.isMoment(a)&&k(o)&&o.add(r.parse(o),"minutes"),o.tz(e),o}(e<2||2==e&&r<6)&&L("Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js "+c.version+". See momentjs.com"),p.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var i,e=+a,r=this.untils;for(i=0;i<r.length;i++)if(e<r[i])return i},parse:function(a){var i,e,r,o,c=+a,A=this.offsets,n=this.untils,t=n.length-1;for(o=0;o<t;o++)if(i=A[o],e=A[o+1],r=A[o?o-1:o],i<e&&B.moveAmbiguousForward?i=e:r<i&&B.moveInvalidForward&&(i=r),c<n[o]-6e4*i)return A[o];return A[t]},abbr:function(a){return this.abbrs[this._index(a)]},offset:function(a){return L("zone.offset has been deprecated in favor of zone.utcOffset"),this.offsets[this._index(a)]},utcOffset:function(a){return this.offsets[this._index(a)]}},b.prototype.scoreOffsetAt=function(a){this.offsetScore+=Math.abs(this.zone.utcOffset(a.at)-a.offset),this.zone.abbr(a.at).replace(/[^A-Z]/g,"")!==a.abbr&&this.abbrScore++},B.version="0.5.25",B.dataVersion="",B._zones=A,B._links=n,B._names=s,B.add=T,B.link=S,B.load=_,B.zone=P,B.zoneExists=function a(i){return a.didShowError||(a.didShowError=!0,L("moment.tz.zoneExists('"+i+"') has been deprecated in favor of !moment.tz.zone('"+i+"')")),!!P(i)},B.guess=function(a){return i&&!a||(i=E()),i},B.names=function(){var a,i=[];for(a in s)s.hasOwnProperty(a)&&(A[a]||A[n[a]])&&s[a]&&i.push(s[a]);return i.sort()},B.Zone=p,B.unpack=l,B.unpackBase60=o,B.needsOffset=k,B.moveInvalidForward=!0,B.moveAmbiguousForward=!1;var C,O=c.fn;function N(a){return function(){return this._z?this._z.abbr(this):a.call(this)}}function D(a){return function(){return this._z=null,a.apply(this,arguments)}}c.tz=B,c.defaultZone=null,c.updateOffset=function(a,i){var e,r=c.defaultZone;if(void 0===a._z&&(r&&k(a)&&!a._isUTC&&(a._d=c.utc(a._a)._d,a.utc().add(r.parse(a),"minutes")),a._z=r),a._z)if(e=a._z.utcOffset(a),Math.abs(e)<16&&(e/=60),void 0!==a.utcOffset){var o=a._z;a.utcOffset(-e,i),a._z=o}else a.zone(e,i)},O.tz=function(a,i){if(a){if("string"!=typeof a)throw new Error("Time zone name must be a string, got "+a+" ["+typeof a+"]");return this._z=P(a),this._z?c.updateOffset(this,i):L("Moment Timezone has no data for "+a+". See http://momentjs.com/timezone/docs/#/data-loading/."),this}if(this._z)return this._z.name},O.zoneName=N(O.zoneName),O.zoneAbbr=N(O.zoneAbbr),O.utc=D(O.utc),O.local=D(O.local),O.utcOffset=(C=O.utcOffset,function(){return 0<arguments.length&&(this._z=null),C.apply(this,arguments)}),c.tz.setDefault=function(a){return(e<2||2==e&&r<9)&&L("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js "+c.version+"."),c.defaultZone=a?P(a):null,c};var y=c.momentProperties;return"[object Array]"===Object.prototype.toString.call(y)?(y.push("_z"),y.push("_a")):y&&(y._z=null),_({version:"2019a",zones:["Africa/Abidjan|GMT|0|0||48e5","Africa/Nairobi|EAT|-30|0||47e5","Africa/Algiers|CET|-10|0||26e5","Africa/Lagos|WAT|-10|0||17e6","Africa/Maputo|CAT|-20|0||26e5","Africa/Cairo|EET EEST|-20 -30|01010|1M2m0 gL0 e10 mn0|15e6","Africa/Casablanca|+00 +01|0 -10|01010101010101010101010101010101|1LHC0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e
4267000 28M0 e00 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00|32e5","Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|11e6","Africa/Johannesburg|SAST|-20|0||84e5","Africa/Khartoum|EAT CAT|-30 -20|01|1Usl0|51e5","Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00","Africa/Tripoli|EET|-20|0||11e5","Africa/Windhoek|CAT WAT|-20 -10|010101010|1LKo0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|32e4","America/Adak|HST HDT|a0 90|01010101010101010101010|1Lzo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326","America/Anchorage|AKST AKDT|90 80|01010101010101010101010|1Lzn0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4","America/Santo_Domingo|AST|40|0||29e5","America/Fortaleza|-03|30|0||34e5","America/Asuncion|-03 -04|30 40|01010101010101010101010|1LEP0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0|28e5","America/Panama|EST|50|0||15e5","America/Mexico_City|CST CDT|60 50|01010101010101010101010|1LKw0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|20e6","America/Managua|CST|60|0||22e5","America/La_Paz|-04|40|0||19e5","America/Lima|-05|50|0||11e6","America/Denver|MST MDT|70 60|01010101010101010101010|1Lzl0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5","America/Campo_Grande|-03 -04|30 40|01010101010101010101010|1LqP0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0 1HB0 FX0 1HB0 IL0 1HB0 FX0 1HB0 IL0 1EN0 FX0 1HB0|77e4","America/Cancun|CST CDT EST|60 50 50|0102|1LKw0 1lb0 Dd0|63e4","America/Caracas|-0430 -04|4u 40|01|1QMT0|29e5","America/Chicago|CST CDT|60 50|01010101010101010101010|1Lzk0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5","America/Chihuahua|MST MDT|70 60|01010101010101010101010|1LKx0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0|81e4","America/Phoenix|MST|70|0||42e5","America/Los_Angeles|PST PDT|80 70|01010101010101010101010|1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6","America/New_York|EST EDT|50 40|01010101010101010101010|1Lzj0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6","America/Fort_Nelson|PST PDT MST|80 70 70|0102|1Lzm0 1zb0 Op0|39e2","America/Halifax|AST ADT|40 30|01010101010101010101010|1Lzi0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4","America/Godthab|-03 -02|30 20|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e3","America/Grand_Turk|EST EDT AST|50 40 40|0101210101010101010|1Lzj0 1zb0 Op0 1zb0 5Ip0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2","America/Havana|CST CDT|50 40|01010101010101010101010|1Lzh0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5","America/Metlakatla|PST AKST AKDT|80 90 80|012121201212
42670121212121|1PAa0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2","America/Miquelon|-03 -02|30 20|01010101010101010101010|1Lzh0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2","America/Montevideo|-02 -03|20 30|0101|1Lzg0 1o10 11z0|17e5","America/Noronha|-02|20|0||30e2","America/Port-au-Prince|EST EDT|50 40|010101010101010101010|1Lzj0 1zb0 Op0 1zb0 3iN0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","Antarctica/Palmer|-03 -04|30 40|01010|1LSP0 Rd0 46n0 Ap0|40","America/Santiago|-03 -04|30 40|010101010101010101010|1LSP0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0|62e5","America/Sao_Paulo|-02 -03|20 30|01010101010101010101010|1LqO0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0 1HB0 FX0 1HB0 IL0 1HB0 FX0 1HB0 IL0 1EN0 FX0 1HB0|20e6","Atlantic/Azores|-01 +00|10 0|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|25e4","America/St_Johns|NST NDT|3u 2u|01010101010101010101010|1Lzhu 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4","Antarctica/Casey|+08 +11|-80 -b0|010|1RWg0 3m10|10","Asia/Bangkok|+07|-70|0||15e6","Pacific/Port_Moresby|+10|-a0|0||25e4","Pacific/Guadalcanal|+11|-b0|0||11e4","Asia/Tashkent|+05|-50|0||23e5","Pacific/Auckland|NZDT NZST|-d0 -c0|01010101010101010101010|1LKe0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00|14e5","Asia/Baghdad|+03|-30|0||66e5","Antarctica/Troll|+00 +02|0 -20|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|40","Asia/Dhaka|+06|-60|0||16e6","Asia/Amman|EET EEST|-20 -30|01010101010101010101010|1LGK0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|25e5","Asia/Kamchatka|+12|-c0|0||18e4","Asia/Baku|+04 +05|-40 -50|01010|1LHA0 1o00 11A0 1o00|27e5","Asia/Barnaul|+07 +06|-70 -60|010|1N7v0 3rd0","Asia/Beirut|EET EEST|-20 -30|01010101010101010101010|1LHy0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|22e5","Asia/Kuala_Lumpur|+08|-80|0||71e5","Asia/Kolkata|IST|-5u|0||15e6","Asia/Chita|+10 +08 +09|-a0 -80 -90|012|1N7s0 3re0|33e4","Asia/Ulaanbaatar|+08 +09|-80 -90|01010|1O8G0 1cJ0 1cP0 1cJ0|12e5","Asia/Shanghai|CST|-80|0||23e6","Asia/Colombo|+0530|-5u|0||22e5","Asia/Damascus|EET EEST|-20 -30|01010101010101010101010|1LGK0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0|26e5","Asia/Dili|+09|-90|0||19e4","Asia/Dubai|+04|-40|0||39e5","Asia/Famagusta|EET EEST +03|-20 -30 -30|0101012010101010101010|1LHB0 1o00 11A0 1o00 11A0 15U0 2Ks0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00","Asia/Gaza|EET EEST|-20 -30|01010101010101010101010|1LGK0 1nX0 1210 1nz0 1220 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|18e5","Asia/Hong_Kong|HKT|-80|0||73e5","Asia/Hovd|+07 +08|-70 -80|01010|1O8H0 1cJ0 1cP0 1cJ0|81e3","Asia/Irkutsk|+09 +08|-90 -80|01|1N7t0|60e4","Europe/Istanbul|EET EEST +03|-20 -30 -30|0101012|1LI10 1nA0 11A0 1tA0 U00 15w0|13e6","Asia/Jakarta|WIB|-70|0||31e6","Asia/Jayapura|WIT|-90|0||26e4","Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010|1LGM0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0|81e4","Asia/Kabul|+0430|-4u|0||46e5","Asia/Karachi|PKT|-50|0||24e6","Asia/Kathmandu|+0545|-5J|0||12e5","Asia/Yakutsk|+10 +09|-a0 -90|01|1N7s0|28e4","Asia/Krasnoyarsk|+08 +07|-80 -70|01|1N7u0|10e5","Asia/Magadan|+12 +10 +11|-c0 -a0 -b0|012|1N7q0 3Cq0|95e3","Asia/Makassar|WITA|-80|0||15e5","Asia/Manila|PST|-80|0||24e6","Europe/Athens|EET EEST|-20 -30|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|35e5","Asia/Novosibirsk|+07 +06|-70 -60|010|1N7v0 4eN0|15e5","Asia/Omsk|+07 +06|-70 -60|01|1N7v0|12e5","Asia/Pyongyang|KST KST|-90 -8u|010|1P4D0 6BA0|29e5","Asia/Qyzylorda|+06 +05|-60 -50|01|1Xei0|73e4","Asia/Rangoon|+0630|-6u|0||48e5","Asia/Sakhalin|+11 +10|-b0 -a0|010|1N7r0 3rd0|58e4","Asia/Seoul|KST|-90|0||23e6","Asia/Srednekolymsk|+12 +11|-c0 -b0|01|1N7q0|35e2","Asia/Tehran|+0330 +0430|-3u -4u|01010101010101010101010|1LEku 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0|14e6","Asia/Tokyo|JST|-90|0||38e6","Asia/Tomsk|+07 +06|-70 -60|010|1N7v0 3Qp0|10e5","Asia/Vladivostok|+11 +10|-b0 -a0|01|1N7r0|60e4","Asia/Yekaterinburg|+06 +05|-60 -50|01|1N7w0|14e5","Europe/Lisbon|WET WEST|0 -10|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|27e5","Atlantic/Cape_Verde|-01|10|0||50e4","Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1LKg0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0|40e5","Australia/Adelaide|ACDT ACST|-au -9u|01010101010101010101010|1LKgu 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0|11e5","Australia/Brisbane|AEST|-a0|0||20e5","Australia/Darwin|ACST|-9u|0||12e4","Australia/Eucla|+0845|-8J|0||368","Australia/Lord_Howe|+11 +1030|-b0 -au|01010101010101010101010|1LKf0 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu|347","Australia/Perth|AWST|-80|0||18e5","Pacific/Easter|-05 -06|50 60|010101010101010101010|1LSP0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0|30e2","Europe/Dublin|GMT IST|0 -10|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5","Etc/GMT-1|+01|-10|0|","Pacific/Fakaofo|+13|-d0|0||483","Pacific/Kiritimati|+14|-e0|0||51e2","Etc/GMT-2|+02|-20|0|","Pacific/Tahiti|-10|a0|0||18e4","Pacific/Niue|-11|b0|0||12e2","Etc
42670/GMT+12|-12|c0|0|","Pacific/Galapagos|-06|60|0||25e3","Etc/GMT+7|-07|70|0|","Pacific/Pitcairn|-08|80|0||56","Pacific/Gambier|-09|90|0||125","Etc/UTC|UTC|0|0|","Europe/Ulyanovsk|+04 +03|-40 -30|010|1N7y0 3rd0|13e5","Europe/London|GMT BST|0 -10|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|10e6","Europe/Chisinau|EET EEST|-20 -30|01010101010101010101010|1LHA0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|67e4","Europe/Kaliningrad|+03 EET|-30 -20|01|1N7z0|44e4","Europe/Kirov|+04 +03|-40 -30|01|1N7y0|48e4","Europe/Moscow|MSK MSK|-40 -30|01|1N7y0|16e6","Europe/Saratov|+04 +03|-40 -30|010|1N7y0 5810","Europe/Simferopol|EET MSK MSK|-20 -40 -30|012|1LHA0 1nW0|33e4","Europe/Volgograd|+04 +03|-40 -30|010|1N7y0 9Jd0|10e5","Pacific/Honolulu|HST|a0|0||37e4","MET|MET MEST|-10 -20|01010101010101010101010|1LHB0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00","Pacific/Chatham|+1345 +1245|-dJ -cJ|01010101010101010101010|1LKe0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00|600","Pacific/Apia|+14 +13|-e0 -d0|01010101010101010101010|1LKe0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00|37e3","Pacific/Bougainville|+10 +11|-a0 -b0|01|1NwE0|18e4","Pacific/Fiji|+13 +12|-d0 -c0|01010101010101010101010|1Lfp0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 1VA0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 1VA0|88e4","Pacific/Guam|ChST|-a0|0||17e4","Pacific/Marquesas|-0930|9u|0||86e2","Pacific/Pago_Pago|SST|b0|0||37e2","Pacific/Norfolk|+1130 +11|-bu -b0|01|1PoCu|25e4","Pacific/Tongatapu|+13 +14|-d0 -e0|010|1S4d0 s00|75e3"],links:["Africa/Abidjan|Africa/Accra","Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Bissau","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Monrovia","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|America/Danmarkshavn","Africa/Abidjan|Atlantic/Reykjavik","Africa/Abidjan|Atlantic/St_Helena","Africa/Abidjan|Etc/GMT","Africa/Abidjan|Etc/GMT+0","Africa/Abidjan|Etc/GMT-0","Africa/Abidjan|Etc/GMT0","Africa/Abidjan|Etc/Greenwich","Africa/Abidjan|GMT","Africa/Abidjan|GMT+0","Africa/Abidjan|GMT-0","Africa/Abidjan|GMT0","Africa/Abidjan|Greenwich","Africa/Abidjan|Iceland","Africa/Algiers|Africa/Tunis","Africa/Cairo|Egypt","Africa/Casablanca|Africa/El_Aaiun","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Ndjamena","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Nairobi|Africa/Addis_Ababa","Africa/Nairobi|Africa/Asmara","Africa/Nairobi|Africa/Asmera","Africa/Nairobi|Africa/Dar_es_Salaam","Africa/Nairobi|Africa/Djibouti","Africa/Nairobi|Africa/Juba","Africa/Nairobi|Africa/Kampala","Africa/Nairobi|Africa/Mogadishu","Africa/Nairobi|Indian/Antananarivo","Africa/Nairobi|Indian/Comoro","Africa/Nairobi|Indian/Mayotte","Africa/Tripoli|Libya","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|America/Juneau","America/Anchorage|America/Nome","America/Anchorage|America/Sitka","America/Anchorage|America/Yakutat","America/Anchorage|US/Alaska","America/Campo_Grande|America/Cuiaba","America/Chicago|America/Indiana/Knox","America/Chicago|America/Indiana/Tell_City","America/Chicago|America/Knox_IN","America/Chicago|America/Matamoros","America/Chicago|America/Menominee","America/Chicago|America/North_Dakota/Beulah","America/Chicago|America/North_Dakota/Center","America/Chicago|America/North_Dakota/New_Salem","America/Chicago|America/Rainy_River","America/Chicago|America/Rankin_Inlet","America/Chicago|America/Resolute","America/Chicago|America/Winnipeg","America/Chicago|CST6CDT","America/Chicago|Canada
42670/Central","America/Chicago|US/Central","America/Chicago|US/Indiana-Starke","America/Chihuahua|America/Mazatlan","America/Chihuahua|Mexico/BajaSur","America/Denver|America/Boise","America/Denver|America/Cambridge_Bay","America/Denver|America/Edmonton","America/Denver|America/Inuvik","America/Denver|America/Ojinaga","America/Denver|America/Shiprock","America/Denver|America/Yellowknife","America/Denver|Canada/Mountain","America/Denver|MST7MDT","America/Denver|Navajo","America/Denver|US/Mountain","America/Fortaleza|America/Araguaina","America/Fortaleza|America/Argentina/Buenos_Aires","America/Fortaleza|America/Argentina/Catamarca","America/Fortaleza|America/Argentina/ComodRivadavia","America/Fortaleza|America/Argentina/Cordoba","America/Fortaleza|America/Argentina/Jujuy","America/Fortaleza|America/Argentina/La_Rioja","America/Fortaleza|America/Argentina/Mendoza","America/Fortaleza|America/Argentina/Rio_Gallegos","America/Fortaleza|America/Argentina/Salta","America/Fortaleza|America/Argentina/San_Juan","America/Fortaleza|America/Argentina/San_Luis","America/Fortaleza|America/Argentina/Tucuman","America/Fortaleza|America/Argentina/Ushuaia","America/Fortaleza|America/Bahia","America/Fortaleza|America/Belem","America/Fortaleza|America/Buenos_Aires","America/Fortaleza|America/Catamarca","America/Fortaleza|America/Cayenne","America/Fortaleza|America/Cordoba","America/Fortaleza|America/Jujuy","America/Fortaleza|America/Maceio","America/Fortaleza|America/Mendoza","America/Fortaleza|America/Paramaribo","America/Fortaleza|America/Recife","America/Fortaleza|America/Rosario","America/Fortaleza|America/Santarem","America/Fortaleza|Antarctica/Rothera","America/Fortaleza|Atlantic/Stanley","America/Fortaleza|Etc/GMT+3","America/Halifax|America/Glace_Bay","America/Halifax|America/Goose_Bay","America/Halifax|America/Moncton","America/Halifax|America/Thule","America/Halifax|Atlantic/Bermuda","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/La_Paz|America/Boa_Vista","America/La_Paz|America/Guyana","America/La_Paz|America/Manaus","America/La_Paz|America/Porto_Velho","America/La_Paz|Brazil/West","America/La_Paz|Etc/GMT+4","America/Lima|America/Bogota","America/Lima|America/Eirunepe","America/Lima|America/Guayaquil","America/Lima|America/Porto_Acre","America/Lima|America/Rio_Branco","America/Lima|Brazil/Acre","America/Lima|Etc/GMT+5","America/Los_Angeles|America/Dawson","America/Los_Angeles|America/Ensenada","America/Los_Angeles|America/Santa_Isabel","America/Los_Angeles|America/Tijuana","America/Los_Angeles|America/Vancouver","America/Los_Angeles|America/Whitehorse","America/Los_Angeles|Canada/Pacific","America/Los_Angeles|Canada/Yukon","America/Los_Angeles|Mexico/BajaNorte","America/Los_Angeles|PST8PDT","America/Los_Angeles|US/Pacific","America/Los_Angeles|US/Pacific-New","America/Managua|America/Belize","America/Managua|America/Costa_Rica","America/Managua|America/El_Salvador","America/Managua|America/Guatemala","America/Managua|America/Regina","America/Managua|America/Swift_Current","America/Managua|America/Tegucigalpa","America/Managua|Canada/Saskatchewan","America/Mexico_City|America/Bahia_Banderas","America/Mexico_City|America/Merida","America/Mexico_City|America/Monterrey","America/Mexico_City|Mexico/General","America/New_York|America/Detroit","America/New_York|America/Fort_Wayne","America/New_York|America/Indiana/Indianapolis","America/New_York|America/Indiana/Marengo","America/New_York|America/Indiana/Petersburg","America/New_York|America/Indiana/Vevay","America/New_York|America/Indiana/Vincennes","America/New_York|America/Indiana/Winamac","America/New_York|America/Indianapolis","America/New_York|America/Iqaluit","America/New_York|America/Kentucky/Louisville","America/New_York|America/Kentucky/Monticello","America/New_York|America/Louisville","America/New_York|America/Montreal","America/New_York|America/Nassau","America/New_York|America/Nipigon","America/New_York|America/Pangnirtung","America/New_York|America/Thunder_Bay","America/New_York|America/Toronto","America/New_York|Canada/Eastern","America/New_York|EST5EDT","America/Ne
42670w_York|US/East-Indiana","America/New_York|US/Eastern","America/New_York|US/Michigan","America/Noronha|Atlantic/South_Georgia","America/Noronha|Brazil/DeNoronha","America/Noronha|Etc/GMT+2","America/Panama|America/Atikokan","America/Panama|America/Cayman","America/Panama|America/Coral_Harbour","America/Panama|America/Jamaica","America/Panama|EST","America/Panama|Jamaica","America/Phoenix|America/Creston","America/Phoenix|America/Dawson_Creek","America/Phoenix|America/Hermosillo","America/Phoenix|MST","America/Phoenix|US/Arizona","America/Santiago|Chile/Continental","America/Santo_Domingo|America/Anguilla","America/Santo_Domingo|America/Antigua","America/Santo_Domingo|America/Aruba","America/Santo_Domingo|America/Barbados","America/Santo_Domingo|America/Blanc-Sablon","America/Santo_Domingo|America/Curacao","America/Santo_Domingo|America/Dominica","America/Santo_Domingo|America/Grenada","America/Santo_Domingo|America/Guadeloupe","America/Santo_Domingo|America/Kralendijk","America/Santo_Domingo|America/Lower_Princes","America/Santo_Domingo|America/Marigot","America/Santo_Domingo|America/Martinique","America/Santo_Domingo|America/Montserrat","America/Santo_Domingo|America/Port_of_Spain","America/Santo_Domingo|America/Puerto_Rico","America/Santo_Domingo|America/St_Barthelemy","America/Santo_Domingo|America/St_Kitts","America/Santo_Domingo|America/St_Lucia","America/Santo_Domingo|America/St_Thomas","America/Santo_Domingo|America/St_Vincent","America/Santo_Domingo|America/Tortola","America/Santo_Domingo|America/Virgin","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada
42670/Newfoundland","Antarctica/Palmer|America/Punta_Arenas","Asia/Baghdad|Antarctica/Syowa","Asia/Baghdad|Asia/Aden","Asia/Baghdad|Asia/Bahrain","Asia/Baghdad|Asia/Kuwait","Asia/Baghdad|Asia/Qatar","Asia/Baghdad|Asia/Riyadh","Asia/Baghdad|Etc/GMT-3","Asia/Baghdad|Europe/Minsk","Asia/Bangkok|Antarctica/Davis","Asia/Bangkok|Asia/Ho_Chi_Minh","Asia/Bangkok|Asia/Novokuznetsk","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Saigon","Asia/Bangkok|Asia/Vientiane","Asia/Bangkok|Etc/GMT-7","Asia/Bangkok|Indian/Christmas","Asia/Dhaka|Antarctica/Vostok","Asia/Dhaka|Asia/Almaty","Asia/Dhaka|Asia/Bishkek","Asia/Dhaka|Asia/Dacca","Asia/Dhaka|Asia/Kashgar","Asia/Dhaka|Asia/Qostanay","Asia/Dhaka|Asia/Thimbu","Asia/Dhaka|Asia/Thimphu","Asia/Dhaka|Asia/Urumqi","Asia/Dhaka|Etc/GMT-6","Asia/Dhaka|Indian/Chagos","Asia/Dili|Etc/GMT-9","Asia/Dili|Pacific/Palau","Asia/Dubai|Asia/Muscat","Asia/Dubai|Asia/Tbilisi","Asia/Dubai|Asia/Yerevan","Asia/Dubai|Etc/GMT-4","Asia/Dubai|Europe/Samara","Asia/Dubai|Indian/Mahe","Asia/Dubai|Indian/Mauritius","Asia/Dubai|Indian/Reunion","Asia/Gaza|Asia/Hebron","Asia/Hong_Kong|Hongkong","Asia/Jakarta|Asia/Pontianak","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kamchatka|Asia/Anadyr","Asia/Kamchatka|Etc/GMT-12","Asia/Kamchatka|Kwajalein","Asia/Kamchatka|Pacific/Funafuti","Asia/Kamchatka|Pacific/Kwajalein","Asia/Kamchatka|Pacific/Majuro","Asia/Kamchatka|Pacific/Nauru","Asia/Kamchatka|Pacific/Tarawa","Asia/Kamchatka|Pacific/Wake","Asia/Kamchatka|Pacific/Wallis","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Kuala_Lumpur|Asia/Brunei","Asia/Kuala_Lumpur|Asia/Kuching","Asia/Kuala_Lumpur|Asia/Singapore","Asia/Kuala_Lumpur|Etc/GMT-8","Asia/Kuala_Lumpur|Singapore","Asia/Makassar|Asia/Ujung_Pandang","Asia/Rangoon|Asia/Yangon","Asia/Rangoon|Indian/Cocos","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|Asia/Macao","Asia/Shanghai|Asia/Macau","Asia/Shanghai|Asia/Taipei","Asia/Shanghai|PRC","Asia/Shanghai|ROC","Asia/Tashkent|Antarctica/Mawson","Asia/Tashkent|Asia/Aqtau","Asia/Tashkent|Asia/Aqtobe","Asia/Tashkent|Asia/Ashgabat","Asia/Tashkent|Asia/Ashkhabad","Asia/Tashkent|Asia/Atyrau","Asia/Tashkent|Asia/Dushanbe","Asia/Tashkent|Asia/Oral","Asia/Tashkent|Asia/Samarkand","Asia/Tashkent|Etc/GMT-5","Asia/Tashkent|Indian/Kerguelen","Asia/Tashkent|Indian/Maldives","Asia/Tehran|Iran","Asia/Tokyo|Japan","Asia/Ulaanbaatar|Asia/Choibalsan","Asia/Ulaanbaatar|Asia/Ulan_Bator","Asia/Vladivostok|Asia/Ust-Nera","Asia/Yakutsk|Asia/Khandyga","Atlantic/Azores|America/Scoresbysund","Atlantic/Cape_Verde|Etc/GMT+1","Australia/Adelaide|Australia/Broken_Hill","Australia/Adelaide|Australia/South","Australia/Adelaide|Australia/Yancowinna","Australia/Brisbane|Australia/Lindeman","Australia/Brisbane|Australia/Queensland","Australia/Darwin|Australia/North","Australia/Lord_Howe|Australia/LHI","Australia/Perth|Australia/West","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/Currie","Australia/Sydney|Australia/Hobart","Australia/Sydney|Australia/Melbourne","Australia/Sydney|Australia/NSW","Australia/Sydney|Australia/Tasmania","Australia/Sydney|Australia/Victoria","Etc/UTC|Etc/UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UCT","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Athens|Asia/Nicosia","Europe/Athens|EET","Europe/Athens|Europe/Bucharest","Europe/Athens|Europe/Helsinki","Europe/Athens|Europe/Kiev","Europe/Athens|Europe/Mariehamn","Europe/Athens|Europe/Nicosia","Europe/Athens|Europe/Riga","Europe/Athens|Europe/Sofia","Europe/Athens|Europe/Tallinn","Europe/Athens|Europe/Uzhgorod","Europe/Athens|Europe/Vilnius","Europe/Athens|Europe/Zaporozhye","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Turkey","Europe/Lisbon|Atlantic/Canary","Europe/Lisbon|Atlantic/Faeroe","Europe/Lisbon|Atlantic/Faroe","Europe/Lisbon|Atlantic/Madeira","Europe/Lisbon|Portugal","Europe/Lisbon|WET","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|W-SU","Europe/Paris|Africa/Ceuta","Europe/Paris|Arctic/Longyearbyen","Europe/Paris|Atlantic/Jan_Mayen","Europe/Paris|CET","Europe/Paris|Europe/Amsterdam","Europe/Paris|Europe/Andorra","Europe/Paris|Europe/Belgrade","Europe/Paris|Europe/Berlin","Europe/Paris|Europe/Bratislava","Europe/Paris|Europe/Brussels","Europe/Paris|Europe/Budapest","Europe/Paris|Europe/Busingen","Europe/Paris|Europe/Copenhagen","Europe/Paris|Europe/Gibraltar","Europe/Paris|Europe/Ljubljana","Europe/Paris|Europe/Luxembourg","Europe/Paris|Europe/Madrid","Europe/Paris|Europe/Malta","Europe/Paris|Europe/Monaco","Europe/Paris|Europe/Oslo","Europe/Paris|Europe/Podgorica","Europe/Paris|Europe/Prague","Europe/Paris|Europe/Rome","Europe/Paris|Europe/San_Marino","Europe/Paris|Europe/Sarajevo","Europe/Paris|Europe/Skopje","Europe/Paris|Europe/Stockholm","Europe/Paris|Europe/Tirane","Europe/Paris|Europe/Vaduz","Europe/Paris|Europe/Vatican","Europe/Paris|Europe/Vienna","Europe/Paris|Europe/Warsaw","Europe/Paris|Europe/Zagreb","Europe/Paris|Europe/Zurich","Europe/Paris|Poland","Europe/Ulyanovsk|Europe/Astrakhan","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Easter|Chile/EasterIsland","Pacific/Fakaofo|Et
42670c/GMT-13","Pacific/Fakaofo|Pacific/Enderbury","Pacific/Galapagos|Etc/GMT+6","Pacific/Gambier|Etc/GMT+9","Pacific/Guadalcanal|Antarctica/Macquarie","Pacific/Guadalcanal|Etc/GMT-11","Pacific/Guadalcanal|Pacific/Efate","Pacific/Guadalcanal|Pacific/Kosrae","Pacific/Guadalcanal|Pacific/Noumea","Pacific/Guadalcanal|Pacific/Pohnpei","Pacific/Guadalcanal|Pacific/Ponape","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|HST","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Kiritimati|Etc/GMT-14","Pacific/Niue|Etc/GMT+11","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Pitcairn|Etc/GMT+8","Pacific/Port_Moresby|Antarctica/DumontDUrville","Pacific/Port_Moresby|Etc/GMT-10","Pacific/Port_Moresby|Pacific/Chuuk","Pacific/Port_Moresby|Pacific/Truk","Pacific/Port_Moresby|Pacific/Yap","Pacific/Tahiti|Etc/GMT+10","Pacific/Tahiti|Pacific/Rarotonga"]}),c});
42671/**
42672 * zoom.js - It's the best way to zoom an image
42673 * @version v0.0.2
42674 * @link https://github.com/fat/zoom.js
42675 * @license MIT
42676 */
42677
42678+function(t){"use strict";function o(){this._activeZoom=this._initialScrollPosition=this._initialTouchPosition=this._touchMoveListener=null,this._$document=t(document),this._$window=t(window),this._$body=t(document.body),this._boundClick=t.proxy(this._clickHandler,this)}function i(o){this._fullHeight=this._fullWidth=this._overlay=this._targetImageWrap=null,this._targetImage=o,this._$body=t(document.body)}o.prototype.listen=function(){this._$body.on("click",'[data-action="zoom"]',t.proxy(this._zoom,this))},o.prototype._zoom=function(o){var e=o.target;if(e&&"IMG"==e.tagName&&!this._$body.hasClass("zoom-overlay-open"))return o.metaKey||o.ctrlKey?window.open(o.target.getAttribute("data-original")||o.target.src,"_blank"):void(e.width>=t(window).width()-i.OFFSET||(this._activeZoomClose(!0),this._activeZoom=new i(e),this._activeZoom.zoomImage(),this._$window.on("scroll.zoom",t.proxy(this._scrollHandler,this)),this._$document.on("keyup.zoom",t.proxy(this._keyHandler,this)),this._$document.on("touchstart.zoom",t.proxy(this._touchStart,this)),document.addEventListener?document.addEventListener("click",this._boundClick,!0):document.attachEvent("onclick",this._boundClick,!0),"bubbles"in o?o.bubbles&&o.stopPropagation():o.cancelBubble=!0))},o.prototype._activeZoomClose=function(t){this._activeZoom&&(t?this._activeZoom.dispose():this._activeZoom.close(),this._$window.off(".zoom"),this._$document.off(".zoom"),document.removeEventListener("click",this._boundClick,!0),this._activeZoom=null)},o.prototype._scrollHandler=function(o){null===this._initialScrollPosition&&(this._initialScrollPosition=t(window).scrollTop());var i=this._initialScrollPosition-t(window).scrollTop();Math.abs(i)>=40&&this._activeZoomClose()},o.prototype._keyHandler=function(t){27==t.keyCode&&this._activeZoomClose()},o.prototype._clickHandler=function(t){t.preventDefault?t.preventDefault():event.returnValue=!1,"bubbles"in t?t.bubbles&&t.stopPropagation():t.cancelBubble=!0,this._activeZoomClose()},o.prototype._touchStart=function(o){o=o.originalEvent||o;if(!o.touches||!o.touches[0])return;this._initialTouchPosition=o.touches[0].pageY,t(o.target).on("touchmove.zoom",t.proxy(this._touchMove,this))},o.prototype._touchMove=function(o){o=o.originalEvent||o;if(!o.touches||!o.touches[0])return;Math.abs(o.touches[0].pageY-this._initialTouchPosition)>10&&(this._activeZoomClose(),t(o.target).off("touchmove.zoom"))},i.OFFSET=80,i._MAX_WIDTH=2560,i._MAX_HEIGHT=4096,i.prototype.zoomImage=function(){var o=document.createElement("img");o.onload=t.proxy(function(){this._fullHeight=Number(o.height),this._fullWidth=Number(o.width),this._zoomOriginal()},this),o.src=this._targetImage.src},i.prototype._zoomOriginal=function(){this._targetImageWrap=document.createElement("div"),this._targetImageWrap.className="zoom-img-wrap",this._targetImage.parentNode.insertBefore(this._targetImageWrap,this._targetImage),this._targetImageWrap.appendChild(this._targetImage),t(this._targetImage).addClass("zoom-img").attr("data-action","zoom-out"),this._overlay=document.createElement("div"),this._overlay.className="zoom-overlay",document.body.appendChild(this._overlay),this._calculateZoom(),this._triggerAnimation()},i.prototype._calculateZoom=function(){this._targetImage.offsetWidth;var o=this._fullWidth,e=this._fullHeight,a=(t(window).scrollTop(),o/this._targetImage.width),s=t(window).height()-i.OFFSET,r=t(window).width()-i.OFFSET,n=o/e,h=r/s;this._imgScaleFactor=r>o&&s>e?a:h>n?s/e*a:r/o*a},i.prototype._triggerAnimation=function(){this._targetImage.offsetWidth;var o=t(this._targetImage).offset(),i=t(window).scrollTop(),e=i+t(window).height()/2,a=t(window).width()/2,s=o.top+this._targetImage.height/2,r=o.left+this._targetImage.width/2;this._translateY=e-s,this._translateX=a-r;var n="scale("+this._imgScaleFactor+")",h="translate("+this._translateX+"px, "+this._translateY+"px)";t.support.transition&&(h+=" translateZ(0)"),t(this._targetImage).css({"-webkit-transform":n,"-ms-transform":n,transform:n}),t(this._targetImageWrap).css({"-webkit-transform":h,"-ms-transform":h,transform:h}),this._$body.addClass("zoom-overlay-open")},i.prototype.close=function(){return this._$body.removeClass("zoom-overlay-open").addClass("zoom-overlay-transitioning"),t(this._targetImage).css({"-webkit-transform":"","-ms-transform":"",transform:""}),t(this._targetImageWrap).css({"-webkit-transform":"","-ms-transform":"",transform:""}),t.support.transition?void t(this._targetImage).one(t.support.transition.end,t.proxy(this.dispose,this)).emulateTransitionEnd(300):this.dispose()},i.prototype.dispose=function(){this._targetImageWrap&&this._targetImageWrap.parentNode&&(t(this._targetImage).removeClass("zoom-img").attr("data-action","zoom"),this._targetImageWrap.parentNode.replaceChild(this._targetImage,this._targetImageWrap),this._overlay.parentNode.removeChild(this._overlay),this._$body.removeClass("zoom-overlay-transitioning"))},t(function(){(new o).listen()})}(jQuery);
42679// require self
42680
42681
42682
42683
42684
42685
42686
42687
42688
42689
42690
42691
42692;
42693// This file includes bootstrap 4.0.0.alpha4 and tether
42694/*! tether 1.1.0 */
42695
42696(function(root, factory) {
42697  if (typeof define === 'function' && define.amd) {
42698    define(factory);
42699  } else if (typeof exports === 'object') {
42700    module.exports = factory(require, exports, module);
42701  } else {
42702    root.Tether = factory();
42703  }
42704}(this, function(require, exports, module) {
42705
42706'use strict';
42707
42708var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
42709
42710function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
42711
42712var TetherBase = undefined;
42713if (typeof TetherBase === 'undefined') {
42714  TetherBase = { modules: [] };
42715}
42716
42717function getScrollParent(el) {
42718  var _getComputedStyle = getComputedStyle(el);
42719
42720  var position = _getComputedStyle.position;
42721
42722  if (position === 'fixed') {
42723    return el;
42724  }
42725
42726  var parent = el;
42727  while (parent = parent.parentNode) {
42728    var style = undefined;
42729    try {
42730      style = getComputedStyle(parent);
42731    } catch (err) {}
42732
42733    if (typeof style === 'undefined' || style === null) {
42734      return parent;
42735    }
42736
42737    var _style = style;
42738    var overflow = _style.overflow;
42739    var overflowX = _style.overflowX;
42740    var overflowY = _style.overflowY;
42741
42742    if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {
42743      if (position !== 'absolute' || ['relative', 'absolute', 'fixed'].indexOf(style.position) >= 0) {
42744        return parent;
42745      }
42746    }
42747  }
42748
42749  return document.body;
42750}
42751
42752var uniqueId = (function () {
42753  var id = 0;
42754  return function () {
42755    return ++id;
42756  };
42757})();
42758
42759var zeroPosCache = {};
42760var getOrigin = function getOrigin(doc) {
42761  // getBoundingClientRect is unfortunately too accurate.  It introduces a pixel or two of
42762  // jitter as the user scrolls that messes with our ability to detect if tw
42762o positions
42763  // are equivilant or not.  We place an element at the top left of the page that will
42764  // get the same jitter, so we can cancel the two out.
42765  var node = doc._tetherZeroElement;
42766  if (typeof node === 'undefined') {
42767    node = doc.createElement('div');
42768    node.setAttribute('data-tether-id', uniqueId());
42769    extend(node.style, {
42770      top: 0,
42771      left: 0,
42772      position: 'absolute'
42773    });
42774
42775    doc.body.appendChild(node);
42776
42777    doc._tetherZeroElement = node;
42778  }
42779
42780  var id = node.getAttribute('data-tether-id');
42781  if (typeof zeroPosCache[id] === 'undefined') {
42782    zeroPosCache[id] = {};
42783
42784    var rect = node.getBoundingClientRect();
42785    for (var k in rect) {
42786      // Can't use extend, as on IE9, elements don't resolve to be hasOwnProperty
42787      zeroPosCache[id][k] = rect[k];
42788    }
42789
42790    // Clear the cache when this position call is done
42791    defer(function () {
42792      delete zeroPosCache[id];
42793    });
42794  }
42795
42796  return zeroPosCache[id];
42797};
42798
42799function getBounds(el) {
42800  var doc = undefined;
42801  if (el === document) {
42802    doc = document;
42803    el = document.documentElement;
42804  } else {
42805    doc = el.ownerDocument;
42806  }
42807
42808  var docEl = doc.documentElement;
42809
42810  var box = {};
42811  // The original object returned by getBoundingClientRect is immutable, so we clone it
42812  // We can't use extend because the properties are not considered part of the object by hasOwnProperty in IE9
42813  var rect = el.getBoundingClientRect();
42814  for (var k in rect) {
42815    box[k] = rect[k];
42816  }
42817
42818  var origin = getOrigin(doc);
42819
42820  box.top -= origin.top;
42821  box.left -= origin.left;
42822
42823  if (typeof box.width === 'undefined') {
42824    box.width = document.body.scrollWidth - box.left - box.right;
42825  }
42826  if (typeof box.height === 'undefined') {
42827    box.height = document.body.scrollHeight - box.top - box.bottom;
42828  }
42829
42830  box.top = box.top - docEl.clientTop;
42831  box.left = box.left - docEl.clientLeft;
42832  box.right = doc.body.clientWidth - box.width - box.left;
42833  box.bottom = doc.body.clientHeight - box.height - box.top;
42834
42835  return box;
42836}
42837
42838function getOffsetParent(el) {
42839  return el.offsetParent || document.documentElement;
42840}
42841
42842function getScrollBarSize() {
42843  var inner = document.createElement('div');
42844  inner.style.width = '100%';
42845  inner.style.height = '200px';
42846
42847  var outer = document.createElement('div');
42848  extend(outer.style, {
42849    position: 'absolute',
42850    top: 0,
42851    left: 0,
42852    pointerEvents: 'none',
42853    visibility: 'hidden',
42854    width: '200px',
42855    height: '150px',
42856    overflow: 'hidden'
42857  });
42858
42859  outer.appendChild(inner);
42860
42861  document.body.appendChild(outer);
42862
42863  var widthContained = inner.offsetWidth;
42864  outer.style.overflow = 'scroll';
42865  var widthScroll = inner.offsetWidth;
42866
42867  if (widthContained === widthScroll) {
42868    widthScroll = outer.clientWidth;
42869  }
42870
42871  document.body.removeChild(outer);
42872
42873  var width = widthContained - widthScroll;
42874
42875  return { width: width, height: width };
42876}
42877
42878function extend() {
42879  var out = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
42880
42881  var args = [];
42882
42883  Array.prototype.push.apply(args, arguments);
42884
42885  args.slice(1).forEach(function (obj) {
42886    if (obj) {
42887      for (var key in obj) {
42888        if (({}).hasOwnProperty.call(obj, key)) {
42889          out[key] = obj[key];
42890        }
42891      }
42892    }
42893  });
42894
42895  return out;
42896}
42897
42898function removeClass(el, name) {
42899  if (typeof el.classList !== 'undefined') {
42900    name.split(' ').forEach(function (cls) {
42901      if (cls.trim()) {
42902        el.classList.remove(cls);
42903      }
42904    });
42905  } else {
42906    var regex = new RegExp('(^| )' + name.split(' ').join('|') + '( |$)', 'gi');
42907    var className = getClassName(el).replace(regex, ' ');
42908    setClassName(el, className);
42909  }
42910}
42911
42912function addClass(el, name) {
42913  if (typeof el.classList !== 'undefined') {
42914    name.split(' ').forEach(function (cls) {
42915      if (cls.trim()) {
42916        el.classList.add(cls);
42917      }
42918    });
42919  } else {
42920    removeClass(el, name);
42921    var cls = getClassName(el) + (' ' + name);
42922    setClassName(el, cls);
42923  }
42924}
42925
42926function hasClass(el, name) {
42927  if (typeof el.classList !== 'undefined') {
42928    return el.classList.contains(name);
42929  }
42930  var className = getClassName(el);
42931  return new RegExp('(^| )' + name + '( |$)', 'gi').test(className);
42932}
42933
42934function getClassName(el) {
42935  if (el.className instanceof SVGAnimatedString) {
42936    return el.className.baseVal;
42937  }
42938  return el.className;
42939}
42940
42941function setClassName(el, className) {
42942  el.setAttribute('class', className);
42943}
42944
42945function updateClasses(el, add, all) {
42946  // Of the set of 'all' classes, we need the 'add' classes, and only the
42947  // 'add' classes to be set.
42948  all.forEach(function (cls) {
42949    if (add.indexOf(cls) === -1 && hasClass(el, cls)) {
42950      removeClass(el, cls);
42951    }
42952  });
42953
42954  add.forEach(function (cls) {
42955    if (!hasClass(el, cls)) {
42956      addClass(el, cls);
42957    }
42958  });
42959}
42960
42961var deferred = [];
42962
42963var defer = function defer(fn) {
42964  deferred.push(fn);
42965};
42966
42967var flush = function flush() {
42968  var fn = undefined;
42969  while (fn = deferred.pop()) {
42970    fn();
42971  }
42972};
42973
42974var Evented = (function () {
42975  function Evented() {
42976    _classCallCheck(this, Evented);
42977  }
42978
42979  _createClass(Evented, [{
42980    key: 'on',
42981    value: function on(event, handler, ctx) {
42982      var once = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
42983
42984      if (typeof this.bindings === 'undefined') {
42985        this.bindings = {};
42986      }
42987      if (typeof this.bindings[event] === 'undefined') {
42988        this.bindings[event] = [];
42989      }
42990      this.bindings[event].push({ handler: handler, ctx: ctx, once: once });
42991    }
42992  }, {
42993    key: 'once',
42994    value: function once(event, handler, ctx) {
42995      this.on(event, handler, ctx, true);
42996    }
42997  }, {
42998    key: 'off',
42999    value: function off(event, handler) {
43000      if (typeof this.bindings !== 'undefined' && typeof this.bindings[event] !== 'undefined') {
43001        return;
43002      }
43003
43004      if (typeof handler === 'undefined') {
43005        delete this.bindings[event];
43006      } else {
43007        var i = 0;
43008        while (i < this.bindings[event].length) {
43009          if (this.bindings[event][i].handler === handler) {
43010            this.bindings[event].splice(i, 1);
43011          } else {
43012            ++i;
43013          }
43014        }
43015      }
43016    }
43017  }, {
43018    key: 'trigger',
43019    value: function trigger(event) {
43020      if (typeof this.bindings !== 'undefined' && this.bindings[event]) {
43021        var i = 0;
43022
43023        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
43024          args[_key - 1] = arguments[_key];
43025        }
43026
43027        while (i < this.bindings[event].length) {
43028          var _bindings$event$i = this.bindings[event][i];
43029          var handler = _bindings$event$i.handler;
43030          var ctx = _bindings$event$i.ctx;
43031          var once = _bindings$event$i.once;
43032
43033          var context = ctx;
43034          if (typeof context === 'undefined') {
43035            context = this;
43036          }
43037
43038          handler.apply(context, args);
43039
43040          if (once) {
43041            this.bindings[event].splice(i, 1);
43042          } else {
43043            ++i;
43044          }
43045        }
43046      }
43047    }
43048  }]);
43049
43050  return Evented;
43051})();
43052
43053TetherBase.Utils = {
43054  getScrollParent: getScrollParent,
43055  getBounds: getBounds,
43056  getOffsetParent: getOffsetParent,
43057  extend: extend,
43058  addClass: addClass,
43059  removeClass: removeClass,
43060  hasClass: hasClass,
43061  updateClasses: updateClasses,
43062  defer: defer,
43063  flush: flush,
43064  uniqueId: uniqueId,
43065  Evented: Evented,
43066  getScrollBarSize: getScrollBarSize
43067};
43068/* globals TetherBase, performance */
43069
43070'use strict';
43071
43072var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
43073
43074var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
43075
43076function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
43077
43078if (typeof TetherBase === 'undefined') {
43079  throw new Error('You must include the utils.js file before tether.js');
43080}
43081
43082var _TetherBase$Utils = TetherBase.Utils;
43083var getScrollParent = _TetherBase$Utils.getScrollParent;
43084var getBounds = _TetherBase$Utils.getBounds;
43085var getOffsetParent = _TetherBase$Utils.getOffsetParent;
43086var extend = _TetherBase$Utils.extend;
43087var addClass = _TetherBase$Utils.addClass;
43088var removeClass = _TetherBase$Utils.removeClass;
43089var updateClasses = _TetherBase$Utils.updateClasses;
43090var defer = _TetherBase$Utils.defer;
43091var flush = _TetherBase$Utils.flush;
43092var getScrollBarSize = _TetherBase$Utils.getScrollBarSize;
43093
43094function within(a, b) {
43095  var diff = arguments.length <= 2 || arguments[2] === undefined ? 1 : arguments[2];
43096
43097  return a + diff >= b && b >= a - diff;
43098}
43099
43100var transformKey = (function () {
43101  if (typeof document === 'undefined') {
43102    return '';
43103  }
43104  var el = document.createElement('div');
43105
43106  var transforms = ['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform'];
43107  for (var i = 0; i < transforms.length; ++i) {
43108    var key = transforms[i];
43109    if (el.style[key] !== undefined) {
43110      return key;
43111    }
43112  }
43113})();
43114
43115var tethers = [];
43116
43117var position = function position() {
43118  tethers.forEach(function (tether) {
43119    tether.position(false);
43120  });
43121  flush();
43122};
43123
43124function now() {
43125  if (typeof performance !== 'undefined' && typeof performance.now !== 'undefined') {
43126    return performance.now();
43127  }
43128  return +new Date();
43129}
43130
43131(function () {
43132  var lastCall = null;
43133  var lastDuration = null;
43134  var pendingTimeout = null;
43135
43136  var tick = function tick() {
43137    if (typeof lastDuration !== 'undefined' && lastDuration > 16) {
43138      // We voluntarily throttle ourselves if we can't manage 60fps
43139      lastDuration = Math.min(lastDuration - 16, 250);
43140
43141      // Just in case this is the last event, remember to position just once more
43142      pendingTimeout = setTimeout(tick, 250);
43143      return;
43144    }
43145
43146    if (typeof lastCall !== 'undefined' && now() - lastCall < 10) {
43147      // Some browsers call events a little too frequently, refuse to run more than is reasonable
43148      return;
43149    }
43150
43151    if (typeof pendingTimeout !== 'undefined') {
43152      clearTimeout(pendingTimeout);
43153      pendingTimeout = null;
43154    }
43155
43156    lastCall = now();
43157    position();
43158    lastDuration = now() - lastCall;
43159  };
43160
43161  if (typeof window !== 'undefined') {
43162    ['resize', 'scroll', 'touchmove'].forEach(function (event) {
43163      window.addEventListener(event, tick);
43164    });
43165  }
43166})();
43167
43168var MIRROR_LR = {
43169  center: 'center',
43170  left: 'right',
43171  right: 'left'
43172};
43173
43174var MIRROR_TB = {
43175  middle: 'middle',
43176  top: 'bottom',
43177  bottom: 'top'
43178};
43179
43180var OFFSET_MAP = {
43181  top: 0,
43182  left: 0,
43183  middle: '50%',
43184  center: '50%',
43185  bottom: '100%',
43186  right: '100%'
43187};
43188
43189var autoToFixedAttachment = function autoToFixedAttachment(attachment, relativeToAttachment) {
43190  var left = attachment.left;
43191  var top = attachment.top;
43192
43193  if (left === 'auto') {
43194    left = MIRROR_LR[relativeToAttachment.left];
43195  }
43196
43197  if (top === 'auto') {
43198    top = MIRROR_TB[relativeToAttachment.top];
43199  }
43200
43201  return { left: left, top: top };
43202};
43203
43204var attachmentToOffset = function attachmentToOffset(attachment) {
43205  var left = attachment.left;
43206  var top = attachment.top;
43207
43208  if (typeof OFFSET_MAP[attachment.left] !== 'undefined') {
43209    left = OFFSET_MAP[attachment.left];
43210  }
43211
43212  if (typeof OFFSET_MAP[attachment.top] !== 'undefined') {
43213    top = OFFSET_MAP[attachment.top];
43214  }
43215
43216  return { left: left, top: top };
43217};
43218
43219function addOffset() {
43220  var out = { top: 0, left: 0 };
43221
43222  for (var _len = arguments.length, offsets = Array(_len), _key = 0; _key < _len; _key++) {
43223    offsets[_key] = arguments[_key];
43224  }
43225
43226  offsets.forEach(function (_ref) {
43227    var top = _ref.top;
43228    var left = _ref.left;
43229
43230    if (typeof top === 'string') {
43231      top = parseFloat(top, 10);
43232    }
43233    if (typeof left === 'string') {
43234      left = parseFloat(left, 10);
43235    }
43236
43237    out.top += top;
43238    out.left += left;
43239  });
43240
43241  return out;
43242}
43243
43244function offsetToPx(offset, size) {
43245  if (typeof offset.left === 'string' && offset.left.indexOf('%') !== -1) {
43246    offset.left = parseFloat(offset.left, 10) / 100 * size.width;
43247  }
43248  if (typeof offset.top === 'string' && offset.top.indexOf('%') !== -1) {
43249    offset.top = parseFloat(offset.top, 10) / 100 * size.height;
43250  }
43251
43252  return offset;
43253}
43254
43255var parseOffset = function parseOffset(value) {
43256  var _value$split = value.split(' ');
43257
43258  var _value$split2 = _slicedToArray(_value$split, 2);
43259
43260  var top = _value$split2[0];
43261  var left = _value$split2[1];
43262
43263  return { top: top, left: left };
43264};
43265var parseAttachment = parseOffset;
43266
43267var TetherClass = (function () {
43268  function TetherClass(options) {
43269    var _this = this;
43270
43271    _classCallCheck(this, TetherClass);
43272
43273    this.position = this.position.bind(this);
43274
43275    tethers.push(this);
43276
43277    this.history = [];
43278
43279    this.setOptions(options, false);
43280
43281    TetherBase.modules.forEach(function (module) {
43282      if (typeof module.initialize !== 'undefined') {
43283        module.initialize.call(_this);
43284      }
43285    });
43286
43287    this.position();
43288  }
43289
43290  _createClass(TetherClass, [{
43291    key: 'getClass',
43292    value: function getClass() {
43293      var key = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
43294      var classes = this.options.classes;
43295
43296      if (typeof classes !== 'undefined' && classes[key]) {
43297        return this.options.classes[key];
43298      } else if (this.options.classPrefix) {
43299        return this.options.classPrefix + '-' + key;
43300      } else {
43301        return key;
43302      }
43303    }
43304  }, {
43305    key: 'setOptions',
43306    value: function setOptions(options) {
43307      var _this2 = this;
43308
43309      var pos = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
43310
43311      var defaults = {
43312        offset: '0 0',
43313        targetOffset: '0 0',
43314        targetAttachment: 'auto auto',
43315        classPrefix: 'tether'
43316      };
43317
43318      this.options = extend(defaults, options);
43319
43320      var _options = this.options;
43321      var element = _options.element;
43322      var target = _options.target;
43323      var targetModifier = _options.targetModifier;
43324
43325      this.element = element;
43326      this.target = target;
43327      this.targetModifier = targetModifier;
43328
43329      if (this.target === 'viewport') {
43330        this.target = document.body;
43331        this.targetModifier = 'visible';
43332      } else if (this.target === 'scroll-handle') {
43333        this.target = document.body;
43334        this.targetModifier = 'scroll-handle';
43335      }
43336
43337      ['element', 'target'].forEach(function (key) {
43338        if (typeof _this2[key] === 'undefined') {
43339          throw new Error('Tether Error: Both element and target must be defined');
43340        }
43341
43342        if (typeof _this2[key].jquery !== 'undefined') {
43343          _this2[key] = _this2[key][0];
43344        } else if (typeof _this2[key] === 'string') {
43345          _this2[key] = document.querySelector(_this2[key]);
43346        }
43347      });
43348
43349      addClass(this.element, this.getClass('element'));
43350      if (!(this.options.addTargetClasses === false)) {
43351        addClass(this.target, this.getClass('target'));
43352      }
43353
43354      if (!this.options.attachment) {
43355        throw new Error('Tether Error: You must provide an attachment');
43356      }
43357
43358      this.targetAttachment = parseAttachment(this.options.targetAttachment);
43359      this.attachment = parseAttachment(this.options.attachment);
43360      this.offset = parseOffset(this.options.offset);
43361      this.targetOffset = parseOffset(this.options.targetOffset);
43362
43363      if (typeof this.scrollParent !== 'undefined') {
43364        this.disable();
43365      }
43366
43367      if (this.targetModifier === 'scroll-handle') {
43368        this.scrollParent = this.target;
43369      } else {
43370        this.scrollParent = getScrollParent(this.target);
43371      }
43372
43373      if (!(this.options.enabled === false)) {
43374        this.enable(pos);
43375      }
43376    }
43377  }, {
43378    key: 'getTargetBounds',
43379    value: function getTargetBounds() {
43380      if (typeof this.targetModifier !== 'undefined') {
43381        if (this.targetModifier === 'visible') {
43382          if (this.target === document.body) {
43383            return { top: pageYOffset, left: pageXOffset, height: innerHe
43383ight, width: innerWidth };
43384          } else {
43385            var bounds = getBounds(this.target);
43386
43387            var out = {
43388              height: bounds.height,
43389              width: bounds.width,
43390              top: bounds.top,
43391              left: bounds.left
43392            };
43393
43394            out.height = Math.min(out.height, bounds.height - (pageYOffset - bounds.top));
43395            out.height = Math.min(out.height, bounds.height - (bounds.top + bounds.height - (pageYOffset + innerHeight)));
43396            out.height = Math.min(innerHeight, out.height);
43397            out.height -= 2;
43398
43399            out.width = Math.min(out.width, bounds.width - (pageXOffset - bounds.left));
43400            out.width = Math.min(out.width, bounds.width - (bounds.left + bounds.width - (pageXOffset + innerWidth)));
43401            out.width = Math.min(innerWidth, out.width);
43402            out.width -= 2;
43403
43404            if (out.top < pageYOffset) {
43405              out.top = pageYOffset;
43406            }
43407            if (out.left < pageXOffset) {
43408              out.left = pageXOffset;
43409            }
43410
43411            return out;
43412          }
43413        } else if (this.targetModifier === 'scroll-handle') {
43414          var bounds = undefined;
43415          var target = this.target;
43416          if (target === document.body) {
43417            target = document.documentElement;
43418
43419            bounds = {
43420              left: pageXOffset,
43421              top: pageYOffset,
43422              height: innerHeight,
43423              width: innerWidth
43424            };
43425          } else {
43426            bounds = getBounds(target);
43427          }
43428
43429          var style = getComputedStyle(target);
43430
43431          var hasBottomScroll = target.scrollWidth > target.clientWidth || [style.overflow, style.overflowX].indexOf('scroll') >= 0 || this.target !== document.body;
43432
43433          var scrollBottom = 0;
43434          if (hasBottomScroll) {
43435            scrollBottom = 15;
43436          }
43437
43438          var height = bounds.height - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth) - scrollBottom;
43439
43440          var out = {
43441            width: 15,
43442            height: height * 0.975 * (height / target.scrollHeight),
43443            left: bounds.left + bounds.width - parseFloat(style.borderLeftWidth) - 15
43444          };
43445
43446          var fitAdj = 0;
43447          if (height < 408 && this.target === document.body) {
43448            fitAdj = -0.00011 * Math.pow(height, 2) - 0.00727 * height + 22.58;
43449          }
43450
43451          if (this.target !== document.body) {
43452            out.height = Math.max(out.height, 24);
43453          }
43454
43455          var scrollPercentage = this.target.scrollTop / (target.scrollHeight - height);
43456          out.top = scrollPercentage * (height - out.height - fitAdj) + bounds.top + parseFloat(style.borderTopWidth);
43457
43458          if (this.target === document.body) {
43459            out.height = Math.max(out.height, 24);
43460          }
43461
43462          return out;
43463        }
43464      } else {
43465        return getBounds(this.target);
43466      }
43467    }
43468  }, {
43469    key: 'clearCache',
43470    value: function clearCache() {
43471      this._cache = {};
43472    }
43473  }, {
43474    key: 'cache',
43475    value: function cache(k, getter) {
43476      // More than one module will often need the same DOM info, so
43477      // we keep a cache which is cleared on each position call
43478      if (typeof this._cache === 'undefined') {
43479        this._cache = {};
43480      }
43481
43482      if (typeof this._cache[k] === 'undefined') {
43483        this._cache[k] = getter.call(this);
43484      }
43485
43486      return this._cache[k];
43487    }
43488  }, {
43489    key: 'enable',
43490    value: function enable() {
43491      var pos = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
43492
43493      if (!(this.options.addTargetClasses === false)) {
43494        addClass(this.target, this.getClass('enabled'));
43495      }
43496      addClass(this.element, this.getClass('enabled'));
43497      this.enabled = true;
43498
43499      if (this.scrollParent !== document) {
43500        this.scrollParent.addEventListener('scroll', this.position);
43501      }
43502
43503      if (pos) {
43504        this.position();
43505      }
43506    }
43507  }, {
43508    key: 'disable',
43509    value: function disable() {
43510      removeClass(this.target, this.getClass('enabled'));
43511      removeClass(this.element, this.getClass('enabled'));
43512      this.enabled = false;
43513
43514      if (typeof this.scrollParent !== 'undefined') {
43515        this.scrollParent.removeEventListener('scroll', this.position);
43516      }
43517    }
43518  }, {
43519    key: 'destroy',
43520    value: function destroy() {
43521      var _this3 = this;
43522
43523      this.disable();
43524
43525      tethers.forEach(function (tether, i) {
43526        if (tether === _this3) {
43527          tethers.splice(i, 1);
43528          return;
43529        }
43530      });
43531    }
43532  }, {
43533    key: 'updateAttachClasses',
43534    value: function updateAttachClasses(elementAttach, targetAttach) {
43535      var _this4 = this;
43536
43537      elementAttach = elementAttach || this.attachment;
43538      targetAttach = targetAttach || this.targetAttachment;
43539      var sides = ['left', 'top', 'bottom', 'right', 'middle', 'center'];
43540
43541      if (typeof this._addAttachClasses !== 'undefined' && this._addAttachClasses.length) {
43542        // updateAttachClasses can be called more than once in a position call, so
43543        // we need to clean up after ourselves such that when the last defer gets
43544        // ran it doesn't add any extra classes from previous calls.
43545        this._addAttachClasses.splice(0, this._addAttachClasses.length);
43546      }
43547
43548      if (typeof this._addAttachClasses === 'undefined') {
43549        this._addAttachClasses = [];
43550      }
43551      var add = this._addAttachClasses;
43552
43553      if (elementAttach.top) {
43554        add.push(this.getClass('element-attached') + '-' + elementAttach.top);
43555      }
43556      if (elementAttach.left) {
43557        add.push(this.getClass('element-attached') + '-' + elementAttach.left);
43558      }
43559      if (targetAttach.top) {
43560        add.push(this.getClass('target-attached') + '-' + targetAttach.top);
43561      }
43562      if (targetAttach.left) {
43563        add.push(this.getClass('target-attached') + '-' + targetAttach.left);
43564      }
43565
43566      var all = [];
43567      sides.forEach(function (side) {
43568        all.push(_this4.getClass('element-attached') + '-' + side);
43569        all.push(_this4.getClass('target-attached') + '-' + side);
43570      });
43571
43572      defer(function () {
43573        if (!(typeof _this4._addAttachClasses !== 'undefined')) {
43574          return;
43575        }
43576
43577        updateClasses(_this4.element, _this4._addAttachClasses, all);
43578        if (!(_this4.options.addTargetClasses === false)) {
43579          updateClasses(_this4.target, _this4._addAttachClasses, all);
43580        }
43581
43582        delete _this4._addAttachClasses;
43583      });
43584    }
43585  }, {
43586    key: 'position',
43587    value: function position() {
43588      var _this5 = this;
43589
43590      var flushChanges = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
43591
43592      // flushChanges commits the changes immediately, leave true unless you are positioning multiple
43593      // tethers (in which case call Tether.Utils.flush yourself when you're done)
43594
43595      if (!this.enabled) {
43596        return;
43597      }
43598
43599      this.clearCache();
43600
43601      // Turn 'auto' attachments into the appropriate corner or edge
43602      var targetAttachment = autoToFixedAttachment(this.targetAttachment, this.attachment);
43603
43604      this.updateAttachClasses(this.attachment, targetAttachment);
43605
43606      var elementPos = this.cache('element-bounds', function () {
43607        return getBounds(_this5.element);
43608      });
43609
43610      var width = elementPos.width;
43611      var height = elementPos.height;
43612
43613      if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') {
43614        var _lastSize = this.lastSize;
43615
43616        // We cache the height and width to make it possible to position elements that are
43617        // getting hidden.
43618        width = _lastSize.width;
43619        height = _lastSize.height;
43620      } else {
43621        this.lastSize = { width: width, height: height };
43622      }
43623
43624      var targetPos = this.cache('target-bounds', function () {
43625        return _this5.getTargetBounds();
43626      });
43627      var targetSize = targetPos;
43628
43629      // Get an actual px offset from the attachment
43630      var offset = offsetToPx(attachmentToOffset(this.attachment), { width: width, height: height });
43631      var targetOffset = offsetToPx(attachmentToOffset(targetAttachment), targetSize);
43632
43633      var manualOffset = offsetToPx(this.offset, { width: width, height: height });
43634      var manualTargetOffset = offsetToPx(this.targetOffset, targetSize);
43635
43636      // Add the manually provided offset
43637      offset = addOffset(offset, manualOffset);
43638      targetOffset = addOffset(targetOffset, manualTargetOffset);
43639
43640      // It's now our goal to make (element position + offset) == (target position + target offset)
43641      var left = targetPos.left + targetOffset.left - offset.left;
43642      var top = targetPos.top + targetOffset.top - offset.top;
43643
43644      for (var i = 0; i < TetherBase.modules.length; ++i) {
43645        var _module2 = TetherBase.modules[i];
43646        var ret = _module2.position.call(this, {
43647          left: left,
43648          top: top,
43649          targetAttachment: targetAttachment,
43650          targetPos: targetPos,
43651          elementPos: elementPos,
43652          offset: offset,
43653          targetOffset: targetOffset,
43654          manualOffset: manualOffset,
43655          manualTargetOffset: manualTargetOffset,
43656          scrollbarSize: scrollbarSize,
43657          attachment: this.attachment
43658        });
43659
43660        if (ret === false) {
43661          return false;
43662        } else if (typeof ret === 'undefined' || typeof ret !== 'object') {
43663          continue;
43664        } else {
43665          top = ret.top;
43666          left = ret.left;
43667        }
43668      }
43669
43670      // We describe the position three different ways to give the optimizer
43671      // a chance to decide the best possible way to position the element
43672      // with the fewest repaints.
43673      var next = {
43674        // It's position relative to the page (absolute positioning when
43675        // the element is a child of the body)
43676        page: {
43677          top: top,
43678          left: left
43679        },
43680
43681        // It's position relative to the viewport (fixed positioning)
43682        viewport: {
43683          top: top - pageYOffset,
43684          bottom: pageYOffset - top - height + innerHeight,
43685          left: left - pageXOffset,
43686          right: pageXOffset - left - width + innerWidth
43687        }
43688      };
43689
43690      var scrollbarSize = undefined;
43691      if (document.body.scrollWidth > window.innerWidth) {
43692        scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);
43693        next.viewport.bottom -= scrollbarSize.height;
43694      }
43695
43696      if (document.body.scrollHeight > window.innerHeight) {
43697        scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);
43698        next.viewport.right -= scrollbarSize.width;
43699      }
43700
43701      if (['', 'static'].indexOf(document.body.style.position) === -1 || ['', 'static'].indexOf(document.body.parentElement.style.position) === -1) {
43702        // Absolute positioning in the body will be relative to the page, not the 'initial containing block'
43703        next.page.bottom = document.body.scrollHeight - top - height;
43704        next.page.right = document.body.scrollWidth - left - width;
43705      }
43706
43707      if (typeof this.options.optimizations !== 'undefined' && this.options.optimizations.moveElement !== false && !(typeof this.targetModifier !== 'undefined')) {
43708        (function () {
43709          var offsetParent = _this5.cache('target-offsetparent', function () {
43710            return getOffsetParent(_this5.target);
43711          });
43712          var offsetPosition = _this5.cache('target-offsetparent-bounds', function () {
43713            return getBounds(offsetParent);
43714          });
43715          var offsetParentStyle = getComputedStyle(offsetParent);
43716          var offsetParentSize = offsetPosition;
43717
43718          var offsetBorder = {};
43719          ['Top', 'Left', 'Bottom', 'Right'].forEach(function (side) {
43720            offsetBorder[side.toLowerCase()] = parseFloat(offsetParentStyle['border' + side + 'Width']);
43721          });
43722
43723          offsetPosition.right = document.body.scrollWidth - offsetPosition.left - offsetParentSize.width + offsetBorder.right;
43724          offsetPosition.bottom = document.body.scrollHeight - offsetPosition.top - offsetParentSize.height + offsetBorder.bottom;
43725
43726          if (next.page.top >= offsetPosition.top + offsetBorder.top && next.page.bottom >= offsetPosition.bottom) {
43727            if (next.page.left >= offsetPosition.left + offsetBorder.left && next.page.right >= offsetPosition.right) {
43728              // We're within the visible part of the target's scroll parent
43729              var scrollTop = offsetParent.scrollTop;
43730              var scrollLeft = offsetParent.scrollLeft;
43731
43732              // It's position relative to the target's offset parent (absolute positioning when
43733              // the element is moved to be a child of the target's offset parent).
43734              next.offset = {
43735                top: next.page.top - offsetPosition.top + scrollTop - offsetBorder.top,
43736                left: next.page.left - offsetPosition.left + scrollLeft - offsetBorder.left
43737              };
43738            }
43739          }
43740        })();
43741      }
43742
43743      // We could also travel up the DOM and try each containing context, rather than only
43744      // looking at the body, but we're gonna get diminishing returns.
43745
43746      this.move(next);
43747
43748      this.history.unshift(next);
43749
43750      if (this.history.length > 3) {
43751        this.history.pop();
43752      }
43753
43754      if (flushChanges) {
43755        flush();
43756      }
43757
43758      return true;
43759    }
43760
43761    // THE ISSUE
43762  }, {
43763    key: 'move',
43764    value: function move(pos) {
43765      var _this6 = this;
43766
43767      if (!(typeof this.element.parentNode !== 'undefined')) {
43768        return;
43769      }
43770
43771      var same = {};
43772
43773      for (var type in pos) {
43774        same[type] = {};
43775
43776        for (var key in pos[type]) {
43777          var found = false;
43778
43779          for (var i = 0; i < this.history.length; ++i) {
43780            var point = this.history[i];
43781            if (typeof point[type] !== 'undefined' && !within(point[type][key], pos[type][key])) {
43782              found = true;
43783              break;
43784            }
43785          }
43786
43787          if (!found) {
43788            same[type][key] = true;
43789          }
43790        }
43791      }
43792
43793      var css = { top: '', left: '', right: '', bottom: '' };
43794
43795      var transcribe = function transcribe(_same, _pos) {
43796        var hasOptimizations = typeof _this6.options.optimizations !== 'undefined';
43797        var gpu = hasOptimizations ? _this6.options.optimizations.gpu : null;
43798        if (gpu !== false) {
43799          var yPos = undefined,
43800              xPos = undefined;
43801          if (_same.top) {
43802            css.top = 0;
43803            yPos = _pos.top;
43804          } else {
43805            css.bottom = 0;
43806            yPos = -_pos.bottom;
43807          }
43808
43809          if (_same.left) {
43810            css.left = 0;
43811            xPos = _pos.left;
43812          } else {
43813            css.right = 0;
43814            xPos = -_pos.right;
43815          }
43816
43817          css[transformKey] = 'translateX(' + Math.round(xPos) + 'px) translateY(' + Math.round(yPos) + 'px)';
43818
43819          if (transformKey !== 'msTransform') {
43820            // The Z transform will keep this in the GPU (faster, and prevents artifacts),
43821            // but IE9 doesn't support 3d transforms and will choke.
43822            css[transformKey] += " translateZ(0)";
43823          }
43824        } else {
43825          if (_same.top) {
43826            css.top = _pos.top + 'px';
43827          } else {
43828            css.bottom = _pos.bottom + 'px';
43829          }
43830
43831          if (_same.left) {
43832            css.left = _pos.left + 'px';
43833          } else {
43834            css.right = _pos.right + 'px';
43835          }
43836        }
43837      };
43838
43839      var moved = false;
43840      if ((same.page.top || same.page.bottom) && (same.page.left || same.page.right)) {
43841        css.position = 'absolute';
43842        transcribe(same.page, pos.page);
43843      } else if ((same.viewport.top || same.viewport.bottom) && (same.viewport.left || same.viewport.right)) {
43844        css.position = 'fixed';
43845        transcribe(same.viewport, pos.viewport);
43846      } else if (typeof same.offset !== 'undefined' && same.offset.top && same.offset.left) {
43847        (function () {
43848          css.position = 'absolute';
43849          var offsetParent = _this6.cache('target-offsetparent', function () {
43850            return getOffsetParent(_this6.target);
43851          });
43852
43853          if (getOffsetParent(_this6.element) !== offsetParent) {
43854            defer(function () {
43855              _this6.element.parentNode.removeChild(_this6.element);
43856              offsetParent.appendChild(_this6.element);
43857            });
43858          }
43859
43860          transcribe(same.offset, pos.offset);
43861          moved = true;
43862        })();
43863      } else {
43864        css.position = 'absolute';
43865        transcribe({ top: true, left: true }, pos.page);
43866      }
43867
43868      if (!moved) {
43869        var offsetParentIsBody = true;
43870        var currentNode = this.element.parentNode;
43871        while (currentNode && currentNode.tagName !== 'BODY') {
43872          if (getComputedStyle(currentNode).position !== 'static') {
43873            offsetParentIsBody = false;
43874            break;
43875          }
43876
43877          currentNode = currentNode.parentNode;
43878        }
43879
43880        if (!offsetParentIsBody) {
43881          this.element.parentNode.removeChild(this.element);
43882          document.body.appendChild(this.element);
43883        }
43884      }
43885
43886      // Any css change will trigger a repaint, so let's avoid one if nothing changed
43887      var writeCSS = {};
43888      var write = false;
43889      for (var key in css) {
43890        var val = css[key];
43891        var elVal = this.element.style[key];
43892
43893        if (elVal !== '' && val !== '' && ['top', 'left', 'bottom', 'right'].indexOf(key) >= 0) {
43894          elVal = parseFloat(elVal);
43895          val = parseFloat(val);
43896        }
43897
43898        if (elVal !== val) {
43899          write = true;
43900          writeCSS[key] = val;
43901        }
43902      }
43903
43904      if (write) {
43905        defer(function () {
43906          extend(_this6.element.style, writeCSS);
43907        });
43908      }
43909    }
43910  }]);
43911
43912  return TetherClass;
43913})();
43914
43915TetherClass.modules = [];
43916
43917TetherBase.position = position;
43918
43919var Tether = extend(TetherClass, TetherBase);
43920/* globals TetherBase */
43921
43922'use strict';
43923
43924var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
43925
43926var _TetherBase$Utils = TetherBase.Utils;
43927var getBounds = _TetherBase$Utils.getBounds;
43928var extend = _TetherBase$Utils.extend;
43929var updateClasses = _TetherBase$Utils.updateClasses;
43930var defer = _TetherBase$Utils.defer;
43931
43932var BOUNDS_FORMAT = ['left', 'top', 'right', 'bottom'];
43933
43934function getBoundingRect(tether, to) {
43935  if (to === 'scrollParent') {
43936    to = tether.scrollParent;
43937  } else if (to === 'window') {
43938    to = [pageXOffset, pageYOffset, innerWidth + pageXOffset, innerHeight + pageYOffset];
43939  }
43940
43941  if (to === document) {
43942    to = to.documentElement;
43943  }
43944
43945  if (typeof to.nodeType !== 'undefined') {
43946    (function () {
43947      var size = getBounds(to);
43948      var pos = size;
43949      var style = getComputedStyle(to);
43950
43951      to = [pos.left, pos.top, size.width + pos.left, size.height + pos.top];
43952
43953      BOUNDS_FORMAT.forEach(function (side, i) {
43954        side = side[0].toUpperCase() + side.substr(1);
43955        if (side === 'Top' || side === 'Left') {
43956          to[i] += parseFloat(style['border' + side + 'Width']);
43957        } else {
43958          to[i] -= parseFloat(style['border' + side + 'Width']);
43959        }
43960      });
43961    })();
43962  }
43963
43964  return to;
43965}
43966
43967TetherBase.modules.push({
43968  position: function position(_ref) {
43969    var _this = this;
43970
43971    var top = _ref.top;
43972    var left = _ref.left;
43973    var targetAttachment = _ref.targetAttachment;
43974
43975    if (!this.options.constraints) {
43976      return true;
43977    }
43978
43979    var _cache = this.cache('element-bounds', function () {
43980      return getBounds(_this.element);
43981    });
43982
43983    var height = _cache.height;
43984    var width = _cache.width;
43985
43986    if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') {
43987      var _lastSize = this.lastSize;
43988
43989      // Handle the item getting hidden as a result of our positioning without glitching
43990      // the classes in and out
43991      width = _lastSize.width;
43992      height = _lastSize.height;
43993    }
43994
43995    var targetSize = this.cache('target-bounds', function () {
43996      return _this.getTargetBounds();
43997    });
43998
43999    var targetHeight = targetSize.height;
44000    var targetWidth = targetSize.width;
44001
44002    var allClasses = [this.getClass('pinned'), this.getClass('out-of-bounds')];
44003
44004    this.options.constraints.forEach(function (constraint) {
44005      var outOfBoundsClass = constraint.outOfBoundsClass;
44006      var pinnedClass = constraint.pinnedClass;
44007
44008      if (outOfBoundsClass) {
44009        allClasses.push(outOfBoundsClass);
44010      }
44011      if (pinnedClass) {
44012        allClasses.push(pinnedClass);
44013      }
44014    });
44015
44016    allClasses.forEach(function (cls) {
44017      ['left', 'top', 'right', 'bottom'].forEach(function (side) {
44018        allClasses.push(cls + '-' + side);
44019      });
44020    });
44021
44022    var addClasses = [];
44023
44024    var tAttachment = extend({}, targetAttachment);
44025    var eAttachment = extend({}, this.attachment);
44026
44027    this.options.constraints.forEach(function (constraint) {
44028      var to = constraint.to;
44029      var attachment = constraint.attachment;
44030      var pin = constraint.pin;
44031
44032      if (typeof attachment === 'undefined') {
44033        attachment = '';
44034      }
44035
44036      var changeAttachX = undefined,
44037          changeAttachY = undefined;
44038      if (attachment.indexOf(' ') >= 0) {
44039        var _attachment$split = attachment.split(' ');
44040
44041        var _attachment$split2 = _slicedToArray(_attachment$split, 2);
44042
44043        changeAttachY = _attachment$split2[0];
44044        changeAttachX = _attachment$split2[1];
44045      } else {
44046        changeAttachX = changeAttachY = attachment;
44047      }
44048
44049      var bounds = getBoundingRect(_this, to);
44050
44051      if (changeAttachY === 'target' || changeAttachY === 'both') {
44052        if (top < bounds[1] && tAttachment.top === 'top') {
44053          top += targetHeight;
44054          tAttachment.top = 'bottom';
44055        }
44056
44057        if (top + height > bounds[3] && tAttachment.top === 'bottom') {
44058          top -= targetHeight;
44059          tAttachment.top = 'top';
44060        }
44061      }
44062
44063      if (changeAttachY === 'together') {
44064        if (top < bounds[1] && tAttachment.top === 'top') {
44065          if (eAttachment.top === 'bottom') {
44066            top += targetHeight;
44067            tAttachment.top = 'bottom';
44068
44069            top += height;
44070            eAttachment.top = 'top';
44071          } else if (eAttachment.top === 'top') {
44072            top += targetHeight;
44073            tAttachment.top = 'bottom';
44074
44075            top -= height;
44076            eAttachment.top = 'bottom';
44077          }
44078        }
44079
44080        if (top + height > bounds[3] && tAttachment.top === 'bottom') {
44081          if (eAttachment.top === 'top') {
44082            top -= targetHeight;
44083            tAttachment.top = 'top';
44084
44085            top -= height;
44086            eAttachment.top = 'bottom';
44087          } else if (eAttachment.top === 'bottom') {
44088            top -= targetHeight;
44089            tAttachment.top = 'top';
44090
44091            top += height;
44092            eAttachment.top = 'top';
44093          }
44094        }
44095
44096        if (tAttachment.top === 'middle') {
44097          if (top + height > bounds[3] && eAttachment.top === 'top') {
44098            top -= height;
44099            eAttachment.top = 'bottom';
44100          } else if (top < bounds[1] && eAttachment.top === 'bottom') {
44101            top += height;
44102            eAttachment.top = 'top';
44103          }
44104        }
44105      }
44106
44107      if (changeAttachX === 'target' || changeAttachX === 'both') {
44108        if (left < bounds[0] && tAttachment.left === 'left') {
44109          left += targetWidth;
44110          tAttachment.left = 'right';
44111        }
44112
44113        if (left + width > bounds[2] && tAttachment.left === 'right') {
44114          left -= targetWidth;
44115          tAttachment.left = 'left';
44116        }
44117      }
44118
44119      if (changeAttachX === 'together') {
44120        if (left < bounds[0] && tAttachment.left === 'left') {
44121          if (eAttachment.left === 'right') {
44122            left += targetWidth;
44123            tAttachment.left = 'right';
44124
44125            left += width;
44126            eAttachment.left = 'left';
44127          } else if (eAttachment.left === 'left') {
44128            left += targetWidth;
44129            tAttachment.left = 'right';
44130
44131            left -= width;
44132            eAttachment.left = 'right';
44133          }
44134        } else if (left + width > bounds[2] && tAttachment.left === 'right') {
44135          if (eAttachment.left === 'left') {
44136            left -= targetWidth;
44137            tAttachment.left = 'left';
44138
44139            left -= width;
44140            eAttachment.left = 'right';
44141          } else if (eAttachment.left === 'right') {
44142            left -= targetWidth;
44143            tAttachment.left = 'left';
44144
44145            left += width;
44146            eAttachment.left = 'left';
44147          }
44148        } else if (tAttachment.left === 'center') {
44149          if (left + width > bounds[2] && eAttachment.left === 'left') {
44150            left -= width;
44151            eAttachment.left = 'right';
44152          } else if (left < bounds[0] && eAttachment.left === 'right') {
44153            left += width;
44154            eAttachment.left = 'left';
44155          }
44156        }
44157      }
44158
44159      if (changeAttachY === 'element' || changeAttachY === 'both') {
44160        if (top < bounds[1] && eAttachment.top === 'bottom') {
44161          top += height;
44162          eAttachment.top = 'top';
44163        }
44164
44165        if (top + height > bounds[3] && eAttachment.top === 'top') {
44166          top -= height;
44167          eAttachment.top = 'bottom';
44168        }
44169      }
44170
44171      if (changeAttachX === 'element' || changeAttachX === 'both') {
44172        if (left < bounds[0] && eAttachment.left === 'right') {
44173          left += width;
44174          eAttachment.left = 'left';
44175        }
44176
44177        if (left + width > bounds[2] && eAttachment.left === 'left') {
44178          left -= width;
44179          eAttachment.left = 'right';
44180        }
44181      }
44182
44183      if (typeof pin === 'string') {
44184        pin = pin.split(',').map(function (p) {
44185          return p.trim();
44186        });
44187      } else if (pin === true) {
44188        pin = ['top', 'left', 'right', 'bottom'];
44189      }
44190
44191      pin = pin || [];
44192
44193      var pinned = [];
44194      var oob = [];
44195
44196      if (top < bounds[1]) {
44197        if (pin.indexOf('top') >= 0) {
44198          top = bounds[1];
44199          pinned.push('top');
44200        } else {
44201          oob.push('top');
44202        }
44203      }
44204
44205      if (top + height > bounds[3]) {
44206        if (pin.indexOf('bottom') >= 0) {
44207          top = bounds[3] - height;
44208          pinned.push('bottom');
44209        } else {
44210          oob.push('bottom');
44211        }
44212      }
44213
44214      if (left < bounds[0]) {
44215        if (pin.indexOf('left') >= 0) {
44216          left = bounds[0];
44217          pinned.push('left');
44218        } else {
44219          oob.push('left');
44220        }
44221      }
44222
44223      if (left + width > bounds[2]) {
44224        if (pin.indexOf('right') >= 0) {
44225          left = bounds[2] - width;
44226          pinned.push('right');
44227        } else {
44228          oob.push('right');
44229        }
44230      }
44231
44232      if (pinned.length) {
44233        (function () {
44234          var pinnedClass = undefined;
44235          if (typeof _this.options.pinnedClass !== 'undefined') {
44236            pinnedClass = _this.options.pinnedClass;
44237          } else {
44238            pinnedClass = _this.getClass('pinned');
44239          }
44240
44241          addClasses.push(pinnedClass);
44242          pinned.forEach(function (side) {
44243            addClasses.push(pinnedClass + '-' + side);
44244          });
44245        })();
44246      }
44247
44248      if (oob.length) {
44249        (function () {
44250          var oobClass = undefined;
44251          if (typeof _this.options.outOfBoundsClass !== 'undefined') {
44252            oobClass = _this.options.outOfBoundsClass;
44253          } else {
44254            oobClass = _this.getClass('out-of-bounds');
44255          }
44256
44257          addClasses.push(oobClass);
44258          oob.forEach(function (side) {
44259            addClasses.push(oobClass + '-' + side);
44260          });
44261        })();
44262      }
44263
44264      if (pinned.indexOf('left') >= 0 || pinned.indexOf('right') >= 0) {
44265        eAttachment.left = tAttachment.left = false;
44266      }
44267      if (pinned.indexOf('top') >= 0 || pinned.indexOf('bottom') >= 0) {
44268        eAttachment.top = tAttachment.top = false;
44269      }
44270
44271      if (tAttachment.top !== targetAttachment.top || tAttachment.left !== targetAttachment.left || eAttachment.top !== _this.attachment.top || eAttachment.left !== _this.attachment.left) {
44272        _this.updateAttachClasses(eAttachment, tAttachment);
44273      }
44274    });
44275
44276    defer(function () {
44277      if (!(_this.options.addTargetClasses === false)) {
44278        updateClasses(_this.target, addClasses, allClasses);
44279      }
44280      updateClasses(_this.element, addClasses, allClasses);
44281    });
44282
44283    return { top: top, left: left };
44284  }
44285});
44286/* globals TetherBase */
44287
44288'use strict';
44289
44290var _TetherBase$Utils = TetherBase.Utils;
44291var getBounds = _TetherBase$Utils.getBounds;
44292var updateClasses = _TetherBase$Utils.updateClasses;
44293var defer = _TetherBase$Utils.defer;
44294
44295TetherBase.modules.push({
44296  position: function position(_ref) {
44297    var _this = this;
44298
44299    var top = _ref.top;
44300    var left = _ref.left;
44301
44302    var _cache = this.cache('element-bounds', function () {
44303      return getBounds(_this.element);
44304    });
44305
44306    var height = _cache.height;
44307    var width = _cache.width;
44308
44309    var targetPos = this.getTargetBounds();
44310
44311    var bottom = top + height;
44312    var right = left + width;
44313
44314    var abutted = [];
44315    if (top <= targetPos.bottom && bottom >= targetPos.top) {
44316      ['left', 'right'].forEach(function (side) {
44317        var targetPosSide = targetPos[side];
44318        if (targetPosSide === left || targetPosSide === right) {
44319          abutted.push(side);
44320        }
44321      });
44322    }
44323
44324    if (left <= targetPos.right && right >= targetPos.left) {
44325      ['top', 'bottom'].forEach(function (side) {
44326        var targetPosSide = targetPos[side];
44327        if (targetPosSide === top || targetPosSide === bottom) {
44328          abutted.push(side);
44329        }
44330      });
44331    }
44332
44333    var allClasses = [];
44334    var addClasses = [];
44335
44336    var sides = ['left', 'top', 'right', 'bottom'];
44337    allClasses.push(this.getClass('abutted'));
44338    sides.forEach(function (side) {
44339      allClasses.push(_this.getClass('abutted') + '-' + side);
44340    });
44341
44342    if (abutted.length) {
44343      addClasses.push(this.getClass('abutted'));
44344    }
44345
44346    abutted.forEach(function (side) {
44347      addClasses.push(_this.getClass('abutted') + '-' + side);
44348    });
44349
44350    defer(function () {
44351      if (!(_this.options.addTargetClasses === false)) {
44352        updateClasses(_this.target, addClasses, allClasses);
44353      }
44354      updateClasses(_this.element, addClasses, allClasses);
44355    });
44356
44357    return true;
44358  }
44359});
44360/* globals TetherBase */
44361
44362'use strict';
44363
44364var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
44365
44366TetherBase.modules.push({
44367  position: function position(_ref) {
44368    var top = _ref.top;
44369    var left = _ref.left;
44370
44371    if (!this.options.shift) {
44372      return;
44373    }
44374
44375    var shift = this.options.shift;
44376    if (typeof this.options.shift === 'function') {
44377      shift = this.options.shift.call(this, { top: top, left: left });
44378    }
44379
44380    var shiftTop = undefined,
44381        shiftLeft = undefined;
44382    if (typeof shift === 'string') {
44383      shift = shift.split(' ');
44384      shift[1] = shift[1] || shift[0];
44385
44386      var _shift = shift;
44387
44388      var _shift2 = _slicedToArray(_shift, 2);
44389
44390      shiftTop = _shift2[0];
44391      shiftLeft = _shift2[1];
44392
44393      shiftTop = parseFloat(shiftTop, 10);
44394      shiftLeft = parseFloat(shiftLeft, 10);
44395    } else {
44396      shiftTop = shift.top;
44397      shiftLeft = shift.left;
44398    }
44399
44400    top += shiftTop;
44401    left += shiftLeft;
44402
44403    return { top: top, left: left };
44404  }
44405});
44406return Tether;
44407
44408}));
44409/*!
44410 * Bootstrap v4.0.0-alpha.4 (http://getbootstrap.com)
44411 * Copyright 2011-2016 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
44412 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
44413 */
44414
44415if (typeof jQuery === 'undefined') {
44416  throw new Error('Bootstrap\'s JavaScript requires jQuery')
44417}
44418
44419+function ($) {
44420  var version = $.fn.jquery.split(' ')[0].split('.')
44421  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 4)) {
44422    throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')
44423  }
44424}(jQuery);
44425
44426
44427+function ($) {
44428
44429/**
44430 * --------------------------------------------------------------------------
44431 * Bootstrap (v4.0.0-alpha.4): util.js
44432 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
44433 * --------------------------------------------------------------------------
44434 */
44435
44436'use strict';
44437
44438var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
44439
44440var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
44441
44442function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
44442onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
44443
44444function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
44445
44446var Util = (function ($) {
44447
44448  /**
44449   * ------------------------------------------------------------------------
44450   * Private TransitionEnd Helpers
44451   * ------------------------------------------------------------------------
44452   */
44453
44454  var transition = false;
44455
44456  var MAX_UID = 1000000;
44457
44458  var TransitionEndEvent = {
44459    WebkitTransition: 'webkitTransitionEnd',
44460    MozTransition: 'transitionend',
44461    OTransition: 'oTransitionEnd otransitionend',
44462    transition: 'transitionend'
44463  };
44464
44465  // shoutout AngusCroll (https://goo.gl/pxwQGp)
44466  function toType(obj) {
44467    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
44468  }
44469
44470  function isElement(obj) {
44471    return (obj[0] || obj).nodeType;
44472  }
44473
44474  function getSpecialTransitionEndEvent() {
44475    return {
44476      bindType: transition.end,
44477      delegateType: transition.end,
44478      handle: function handle(event) {
44479        if ($(event.target).is(this)) {
44480          return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
44481        }
44482        return undefined;
44483      }
44484    };
44485  }
44486
44487  function transitionEndTest() {
44488    if (window.QUnit) {
44489      return false;
44490    }
44491
44492    var el = document.createElement('bootstrap');
44493
44494    for (var _name in TransitionEndEvent) {
44495      if (el.style[_name] !== undefined) {
44496        return { end: TransitionEndEvent[_name] };
44497      }
44498    }
44499
44500    return false;
44501  }
44502
44503  function transitionEndEmulator(duration) {
44504    var _this = this;
44505
44506    var called = false;
44507
44508    $(this).one(Util.TRANSITION_END, function () {
44509      called = true;
44510    });
44511
44512    setTimeout(function () {
44513      if (!called) {
44514        Util.triggerTransitionEnd(_this);
44515      }
44516    }, duration);
44517
44518    return this;
44519  }
44520
44521  function setTransitionEndSupport() {
44522    transition = transitionEndTest();
44523
44524    $.fn.emulateTransitionEnd = transitionEndEmulator;
44525
44526    if (Util.supportsTransitionEnd()) {
44527      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
44528    }
44529  }
44530
44531  /**
44532   * --------------------------------------------------------------------------
44533   * Public Util Api
44534   * --------------------------------------------------------------------------
44535   */
44536
44537  var Util = {
44538
44539    TRANSITION_END: 'bsTransitionEnd',
44540
44541    getUID: function getUID(prefix) {
44542      do {
44543        /* eslint-disable no-bitwise */
44544        prefix += ~ ~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
44545        /* eslint-enable no-bitwise */
44546      } while (document.getElementById(prefix));
44547      return prefix;
44548    },
44549
44550    getSelectorFromElement: function getSelectorFromElement(element) {
44551      var selector = element.getAttribute('data-target');
44552
44553      if (!selector) {
44554        selector = element.getAttribute('href') || '';
44555        selector = /^#[a-z]/i.test(selector) ? selector : null;
44556      }
44557
44558      return selector;
44559    },
44560
44561    reflow: function reflow(element) {
44562      new Function('bs', 'return bs')(element.offsetHeight);
44563    },
44564
44565    triggerTransitionEnd: function triggerTransitionEnd(element) {
44566      $(element).trigger(transition.end);
44567    },
44568
44569    supportsTransitionEnd: function supportsTransitionEnd() {
44570      return Boolean(transition);
44571    },
44572
44573    typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
44574      for (var property in configTypes) {
44575        if (configTypes.hasOwnProperty(property)) {
44576          var expectedTypes = configTypes[property];
44577          var value = config[property];
44578          var valueType = undefined;
44579
44580          if (value && isElement(value)) {
44581            valueType = 'element';
44582          } else {
44583            valueType = toType(value);
44584          }
44585
44586          if (!new RegExp(expectedTypes).test(valueType)) {
44587            throw new Error(componentName.toUpperCase() + ': ' + ('Option "' + property + '" provided type "' + valueType + '" ') + ('but expected type "' + expectedTypes + '".'));
44588          }
44589        }
44590      }
44591    }
44592  };
44593
44594  setTransitionEndSupport();
44595
44596  return Util;
44597})(jQuery);
44598
44599/**
44600 * --------------------------------------------------------------------------
44601 * Bootstrap (v4.0.0-alpha.4): alert.js
44602 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
44603 * --------------------------------------------------------------------------
44604 */
44605
44606var Alert = (function ($) {
44607
44608  /**
44609   * ------------------------------------------------------------------------
44610   * Constants
44611   * ------------------------------------------------------------------------
44612   */
44613
44614  var NAME = 'alert';
44615  var VERSION = '4.0.0-alpha.4';
44616  var DATA_KEY = 'bs.alert';
44617  var EVENT_KEY = '.' + DATA_KEY;
44618  var DATA_API_KEY = '.data-api';
44619  var JQUERY_NO_CONFLICT = $.fn[NAME];
44620  var TRANSITION_DURATION = 150;
44621
44622  var Selector = {
44623    DISMISS: '[data-dismiss="alert"]'
44624  };
44625
44626  var Event = {
44627    CLOSE: 'close' + EVENT_KEY,
44628    CLOSED: 'closed' + EVENT_KEY,
44629    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
44630  };
44631
44632  var ClassName = {
44633    ALERT: 'alert',
44634    FADE: 'fade',
44635    IN: 'in'
44636  };
44637
44638  /**
44639   * ------------------------------------------------------------------------
44640   * Class Definition
44641   * ------------------------------------------------------------------------
44642   */
44643
44644  var Alert = (function () {
44645    function Alert(element) {
44646      _classCallCheck(this, Alert);
44647
44648      this._element = element;
44649    }
44650
44651    /**
44652     * ------------------------------------------------------------------------
44653     * Data Api implementation
44654     * ------------------------------------------------------------------------
44655     */
44656
44657    // getters
44658
44659    _createClass(Alert, [{
44660      key: 'close',
44661
44662      // public
44663
44664      value: function close(element) {
44665        element = element || this._element;
44666
44667        var rootElement = this._getRootElement(element);
44668        var customEvent = this._triggerCloseEvent(rootElement);
44669
44670        if (customEvent.isDefaultPrevented()) {
44671          return;
44672        }
44673
44674        this._removeElement(rootElement);
44675      }
44676    }, {
44677      key: 'dispose',
44678      value: function dispose() {
44679        $.removeData(this._element, DATA_KEY);
44680        this._element = null;
44681      }
44682
44683      // private
44684
44685    }, {
44686      key: '_getRootElement',
44687      value: function _getRootElement(element) {
44688        var selector = Util.getSelectorFromElement(element);
44689        var parent = false;
44690
44691        if (selector) {
44692          parent = $(selector)[0];
44693        }
44694
44695        if (!parent) {
44696          parent = $(element).closest('.' + ClassName.ALERT)[0];
44697        }
44698
44699        return parent;
44700      }
44701    }, {
44702      key: '_triggerCloseEvent',
44703      value: function _triggerCloseEvent(element) {
44704        var closeEvent = $.Event(Event.CLOSE);
44705
44706        $(element).trigger(closeEvent);
44707        return closeEvent;
44708      }
44709    }, {
44710      key: '_removeElement',
44711      value: function _removeElement(element) {
44712        $(element).removeClass(ClassName.IN);
44713
44714        if (!Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) {
44715          this._destroyElement(element);
44716          return;
44717        }
44718
44719        $(element).one(Util.TRANSITION_END, $.proxy(this._destroyElement, this, element)).emulateTransitionEnd(TRANSITION_DURATION);
44720      }
44721    }, {
44722      key: '_destroyElement',
44723      value: function _destroyElement(element) {
44724        $(element).detach().trigger(Event.CLOSED).remove();
44725      }
44726
44727      // static
44728
44729    }], [{
44730      key: '_jQueryInterface',
44731      value: function _jQueryInterface(config) {
44732        return this.each(function () {
44733          var $element = $(this);
44734          var data = $element.data(DATA_KEY);
44735
44736          if (!data) {
44737            data = new Alert(this);
44738            $element.data(DATA_KEY, data);
44739          }
44740
44741          if (config === 'close') {
44742            data[config](this);
44743          }
44744        });
44745      }
44746    }, {
44747      key: '_handleDismiss',
44748      value: function _handleDismiss(alertInstance) {
44749        return function (event) {
44750          if (event) {
44751            event.preventDefault();
44752          }
44753
44754          alertInstance.close(this);
44755        };
44756      }
44757    }, {
44758      key: 'VERSION',
44759      get: function get() {
44760        return VERSION;
44761      }
44762    }]);
44763
44764    return Alert;
44765  })();
44766
44767  $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert()));
44768
44769  /**
44770   * ------------------------------------------------------------------------
44771   * jQuery
44772   * ------------------------------------------------------------------------
44773   */
44774
44775  $.fn[NAME] = Alert._jQueryInterface;
44776  $.fn[NAME].Constructor = Alert;
44777  $.fn[NAME].noConflict = function () {
44778    $.fn[NAME] = JQUERY_NO_CONFLICT;
44779    return Alert._jQueryInterface;
44780  };
44781
44782  return Alert;
44783})(jQuery);
44784
44785/**
44786 * --------------------------------------------------------------------------
44787 * Bootstrap (v4.0.0-alpha.4): button.js
44788 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
44789 * --------------------------------------------------------------------------
44790 */
44791
44792var Button = (function ($) {
44793
44794  /**
44795   * ------------------------------------------------------------------------
44796   * Constants
44797   * ------------------------------------------------------------------------
44798   */
44799
44800  var NAME = 'button';
44801  var VERSION = '4.0.0-alpha.4';
44802  var DATA_KEY = 'bs.button';
44803  var EVENT_KEY = '.' + DATA_KEY;
44804  var DATA_API_KEY = '.data-api';
44805  var JQUERY_NO_CONFLICT = $.fn[NAME];
44806
44807  var ClassName = {
44808    ACTIVE: 'active',
44809    BUTTON: 'btn',
44810    FOCUS: 'focus'
44811  };
44812
44813  var Selector = {
44814    DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
44815    DATA_TOGGLE: '[data-toggle="buttons"]',
44816    INPUT: 'input',
44817    ACTIVE: '.active',
44818    BUTTON: '.btn'
44819  };
44820
44821  var Event = {
44822    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
44823    FOCUS_BLUR_DATA_API: 'focus' + EVENT_KEY + DATA_API_KEY + ' ' + ('blur' + EVENT_KEY + DATA_API_KEY)
44824  };
44825
44826  /**
44827   * ------------------------------------------------------------------------
44828   * Class Definition
44829   * ------------------------------------------------------------------------
44830   */
44831
44832  var Button = (function () {
44833    function Button(element) {
44834      _classCallCheck(this, Button);
44835
44836      this._element = element;
44837    }
44838
44839    /**
44840     * ------------------------------------------------------------------------
44841     * Data Api implementation
44842     * ------------------------------------------------------------------------
44843     */
44844
44845    // getters
44846
44847    _createClass(Button, [{
44848      key: 'toggle',
44849
44850      // public
44851
44852      value: function toggle() {
44853        var triggerChangeEvent = true;
44854        var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0];
44855
44856        if (rootElement) {
44857          var input = $(this._element).find(Selector.INPUT)[0];
44858
44859          if (input) {
44860            if (input.type === 'radio') {
44861              if (input.checked && $(this._element).hasClass(ClassName.ACTIVE)) {
44862                triggerChangeEvent = false;
44863              } else {
44864                var activeElement = $(rootElement).find(Selector.ACTIVE)[0];
44865
44866                if (activeElement) {
44867                  $(activeElement).removeClass(ClassName.ACTIVE);
44868                }
44869              }
44870            }
44871
44872            if (triggerChangeEvent) {
44873              input.checked = !$(this._element).hasClass(ClassName.ACTIVE);
44874              $(this._element).trigger('change');
44875            }
44876
44877            input.focus();
44878          }
44879        } else {
44880          this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE));
44881        }
44882
44883        if (triggerChangeEvent) {
44884          $(this._element).toggleClass(ClassName.ACTIVE);
44885        }
44886      }
44887    }, {
44888      key: 'dispose',
44889      value: function dispose() {
44890        $.removeData(this._element, DATA_KEY);
44891        this._element = null;
44892      }
44893
44894      // static
44895
44896    }], [{
44897      key: '_jQueryInterface',
44898      value: function _jQueryInterface(config) {
44899        return this.each(function () {
44900          var data = $(this).data(DATA_KEY);
44901
44902          if (!data) {
44903            data = new Button(this);
44904            $(this).data(DATA_KEY, data);
44905          }
44906
44907          if (config === 'toggle') {
44908            data[config]();
44909          }
44910        });
44911      }
44912    }, {
44913      key: 'VERSION',
44914      get: function get() {
44915        return VERSION;
44916      }
44917    }]);
44918
44919    return Button;
44920  })();
44921
44922  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
44923    event.preventDefault();
44924
44925    var button = event.target;
44926
44927    if (!$(button).hasClass(ClassName.BUTTON)) {
44928      button = $(button).closest(Selector.BUTTON);
44929    }
44930
44931    Button._jQueryInterface.call($(button), 'toggle');
44932  }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
44933    var button = $(event.target).closest(Selector.BUTTON)[0];
44934    $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type));
44935  });
44936
44937  /**
44938   * ------------------------------------------------------------------------
44939   * jQuery
44940   * ------------------------------------------------------------------------
44941   */
44942
44943  $.fn[NAME] = Button._jQueryInterface;
44944  $.fn[NAME].Constructor = Button;
44945  $.fn[NAME].noConflict = function () {
44946    $.fn[NAME] = JQUERY_NO_CONFLICT;
44947    return Button._jQueryInterface;
44948  };
44949
44950  return Button;
44951})(jQuery);
44952
44953/**
44954 * --------------------------------------------------------------------------
44955 * Bootstrap (v4.0.0-alpha.4): carousel.js
44956 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
44957 * --------------------------------------------------------------------------
44958 */
44959
44960var Carousel = (function ($) {
44961
44962  /**
44963   * ------------------------------------------------------------------------
44964   * Constants
44965   * ------------------------------------------------------------------------
44966   */
44967
44968  var NAME = 'carousel';
44969  var VERSION = '4.0.0-alpha.4';
44970  var DATA_KEY = 'bs.carousel';
44971  var EVENT_KEY = '.' + DATA_KEY;
44972  var DATA_API_KEY = '.data-api';
44973  var JQUERY_NO_CONFLICT = $.fn[NAME];
44974  var TRANSITION_DURATION = 600;
44975  var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
44976  var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
44977
44978  var Default = {
44979    interval: 5000,
44980    keyboard: true,
44981    slide: false,
44982    pause: 'hover',
44983    wrap: true
44984  };
44985
44986  var DefaultType = {
44987    interval: '(number|boolean)',
44988    keyboard: 'boolean',
44989    slide: '(boolean|string)',
44990    pause: '(string|boolean)',
44991    wrap: 'boolean'
44992  };
44993
44994  var Direction = {
44995    NEXT: 'next',
44996    PREVIOUS: 'prev'
44997  };
44998
44999  var Event = {
45000    SLIDE: 'slide' + EVENT_KEY,
45001    SLID: 'slid' + EVENT_KEY,
45002    KEYDOWN: 'keydown' + EVENT_KEY,
45003    MOUSEENTER: 'mouseenter' + EVENT_KEY,
45004    MOUSELEAVE: 'mouseleave' + EVENT_KEY,
45005    LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY,
45006    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
45007  };
45008
45009  var ClassName = {
45010    CAROUSEL: 'carousel',
45011    ACTIVE: 'active',
45012    SLIDE: 'slide',
45013    RIGHT: 'right',
45014    LEFT: 'left',
45015    ITEM: 'carousel-item'
45016  };
45017
45018  var Selector = {
45019    ACTIVE: '.active',
45020    ACTIVE_ITEM: '.active.carousel-item',
45021    ITEM: '.carousel-item',
45022    NEXT_PREV: '.next, .prev',
45023    INDICATORS: '.carousel-indicators',
45024    DATA_SLIDE: '[data-slide], [data-slide-to]',
45025    DATA_RIDE: '[data-ride="carousel"]'
45026  };
45027
45028  /**
45029   * ------------------------------------------------------------------------
45030   * Class Definition
45031   * ------------------------------------------------------------------------
45032   */
45033
45034  var Carousel = (function () {
45035    function Carousel(element, config) {
45036      _classCallCheck(this, Carousel);
45037
45038      this._items = null;
45039      this._interval = null;
45040      this._activeElement = null;
45041
45042      this._isPaused = false;
45043      this._isSliding = false;
45044
45045      this._config = this._getConfig(config);
45046      this._element = $(element)[0];
45047      this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0];
45048
45049      this._addEventListeners();
45050    }
45051
45052    /**
45053     * ------------------------------------------------------------------------
45054     * Data Api implementation
45055     * ------------------------------------------------------------------------
45056     */
45057
45058    // getters
45059
45060    _createClass(Carousel, [{
45061      key: 'next',
45062
45063      // public
45064
45065      value: function next() {
45066        if (!this._isSliding) {
45067          this._slide(Direction.NEXT);
45068        }
45069      }
45070    }, {
45071      key: 'nextWhenVisible',
45072      value: function nextWhenVisible() {
45073        // Don't call next when the page isn't visible
45074        if (!document.hidden) {
45075          this.next();
45076        }
45077      }
45078    }, {
45079      key: 'prev',
45080      value: function prev() {
45081        if (!this._isSliding) {
45082          this._slide(Direction.PREVIOUS);
45083        }
45084      }
45085    }, {
45086      key: 'pause',
45087      value: function pause(event) {
45088        if (!event) {
45089          this._isPaused = true;
45090        }
45091
45092        if ($(this._element).find(Selector.NEXT_PREV)[0] && Util.supportsTransitionEnd()) {
45093          Util.triggerTransitionEnd(this._element);
45094          this.cycle(true);
45095        }
45096
45097        clearInterval(this._interval);
45098        this._interval = null;
45099      }
45100    }, {
45101      key: 'cycle',
45102      value: function cycle(event) {
45103        if (!event) {
45104          this._isPaused = false;
45105        }
45106
45107        if (this._interval) {
45108          clearInterval(this._interval);
45109          this._interval = null;
45110        }
45111
45112        if (this._config.interval && !this._isPaused) {
45113          this._interval = setInterval($.proxy(document.visibilityState ? this.nextWhenVisible : this.next, this), this._config.interval);
45114        }
45115      }
45116    }, {
45117      key: 'to',
45118      value: function to(index) {
45119        var _this2 = this;
45120
45121        this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
45122
45123        var activeIndex = this._getItemIndex(this._activeElement);
45124
45125        if (index > this._items.length - 1 || index < 0) {
45126          return;
45127        }
45128
45129        if (this._isSliding) {
45130          $(this._element).one(Event.SLID, function () {
45131            return _this2.to(index);
45132          });
45133          return;
45134        }
45135
45136        if (activeIndex === index) {
45137          this.pause();
45138          this.cycle();
45139          return;
45140        }
45141
45142        var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS;
45143
45144        this._slide(direction, this._items[index]);
45145      }
45146    }, {
45147      key: 'dispose',
45148      value: function dispose() {
45149        $(this._element).off(EVENT_KEY);
45150        $.removeData(this._element, DATA_KEY);
45151
45152        this._items = null;
45153        this._config = null;
45154        this._element = null;
45155        this._interval = null;
45156        this._isPaused = null;
45157        this._isSliding = null;
45158        this._activeElement = null;
45159        this._indicatorsElement = null;
45160      }
45161
45162      // private
45163
45164    }, {
45165      key: '_getConfig',
45166      value: function _getConfig(config) {
45167        config = $.extend({}, Default, config);
45168        Util.typeCheckConfig(NAME, config, DefaultType);
45169        return config;
45170      }
45171    }, {
45172      key: '_addEventListeners',
45173      value: function _addEventListeners() {
45174        if (this._config.keyboard) {
45175          $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
45176        }
45177
45178        if (this._config.pause === 'hover' && !('ontouchstart' in document.documentElement)) {
45179          $(this._element).on(Event.MOUSEENTER, $.proxy(this.pause, this)).on(Event.MOUSELEAVE, $.proxy(this.cycle, this));
45180        }
45181      }
45182    }, {
45183      key: '_keydown',
45184      value: function _keydown(event) {
45185        event.preventDefault();
45186
45187        if (/input|textarea/i.test(event.target.tagName)) {
45188          return;
45189        }
45190
45191        switch (event.which) {
45192          case ARROW_LEFT_KEYCODE:
45193            this.prev();
45194            break;
45195          case ARROW_RIGHT_KEYCODE:
45196            this.next();
45197            break;
45198          default:
45199            return;
45200        }
45201      }
45202    }, {
45203      key: '_getItemIndex',
45204      value: function _getItemIndex(element) {
45205        this._items = $.makeArray($(element).parent().find(Selector.ITEM));
45206        return this._items.indexOf(element);
45207      }
45208    }, {
45209      key: '_getItemByDirection',
45210      value: function _getItemByDirection(direction, activeElement) {
45211        var isNextDirection = direction === Direction.NEXT;
45212        var isPrevDirection = direction === Direction.PREVIOUS;
45213        var activeIndex = this._getItemIndex(activeElement);
45214        var lastItemIndex = this._items.length - 1;
45215        var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
45216
45217        if (isGoingToWrap && !this._config.wrap) {
45218          return activeElement;
45219        }
45220
45221        var delta = direction === Direction.PREVIOUS ? -1 : 1;
45222        var itemIndex = (activeIndex + delta) % this._items.length;
45223
45224        return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
45225      }
45226    }, {
45227      key: '_triggerSlideEvent',
45228      value: function _triggerSlideEvent(relatedTarget, directionalClassname) {
45229        var slideEvent = $.Event(Event.SLIDE, {
45230          relatedTarget: relatedTarget,
45231          direction: directionalClassname
45232        });
45233
45234        $(this._element).trigger(slideEvent);
45235
45236        return slideEvent;
45237      }
45238    }, {
45239      key: '_setActiveIndicatorElement',
45240      value: function _setActiveIndicatorElement(element) {
45241        if (this._indicatorsElement) {
45242          $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
45243
45244          var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
45245
45246          if (nextIndicator) {
45247            $(nextIndicator).addClass(ClassName.ACTIVE);
45248          }
45249        }
45250      }
45251    }, {
45252      key: '_slide',
45253      value: function _slide(direction, element) {
45254        var _this3 = this;
45255
45256        var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
45257        var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
45258
45259        var isCycling = Boolean(this._interval);
45260
45261        var directionalClassName = direction === Direction.NEXT ? ClassName.LEFT : ClassName.RIGHT;
45262
45263        if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
45264          this._isSliding = false;
45265          return;
45266        }
45267
45268        var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName);
45269        if (slideEvent.isDefaultPrevented()) {
45270          return;
45271        }
45272
45273        if (!activeElement || !nextElement) {
45274          // some weirdness is happening, so we bail
45275          return;
45276        }
45277
45278        this._isSliding = true;
45279
45280        if (isCycling) {
45281          this.pause();
45282        }
45283
45284        this._setActiveIndicatorElement(nextElement);
45285
45286        var slidEvent = $.Event(Event.SLID, {
45287          relatedTarget: nextElement,
45288          direction: directionalClassName
45289        });
45290
45291        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) {
45292
45293          $(nextElement).addClass(direction);
45294
45295          Util.reflow(nextElement);
45296
45297          $(activeElement).addClass(directionalClassName);
45298          $(nextElement).addClass(directionalClassName);
45299
45300          $(activeElement).one(Util.TRANSITION_END, function () {
45301            $(nextElement).removeClass(directionalClassName).removeClass(direction);
45302
45303            $(nextElement).addClass(ClassName.ACTIVE);
45304
45305            $(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName);
45306
45307            _this3._isSliding = false;
45308
45309            setTimeout(function () {
45310              return $(_this3._element).trigger(slidEvent);
45311            }, 0);
45312          }).emulateTransitionEnd(TRANSITION_DURATION);
45313        } else {
45314          $(activeElement).removeClass(ClassName.ACTIVE);
45315          $(nextElement).addClass(ClassName.ACTIVE);
45316
45317          this._isSliding = false;
45318          $(this._element).trigger(slidEvent);
45319        }
45320
45321        if (isCycling) {
45322          this.cycle();
45323        }
45324      }
45325
45326      // static
45327
45328    }], [{
45329      key: '_jQueryInterface',
45330      value: function _jQueryInterface(config) {
45331        return this.each(function () {
45332          var data = $(this).data(DATA_KEY);
45333          var _config = $.extend({}, Default, $(this).data());
45334
45335          if (typeof config === 'object') {
45336            $.extend(_config, config);
45337          }
45338
45339          var action = typeof config === 'string' ? config : _config.slide;
45340
45341          if (!data) {
45342            data = new Carousel(this, _config);
45343            $(this).data(DATA_KEY, data);
45344          }
45345
45346          if (typeof config === 'number') {
45347            data.to(config);
45348          } else if (typeof action === 'string') {
45349            if (data[action] === undefined) {
45350              throw new Error('No method named "' + action + '"');
45351            }
45352            data[action]();
45353          } else if (_config.interval) {
45354            data.pause();
45355            data.cycle();
45356          }
45357        });
45358      }
45359    }, {
45360      key: '_dataApiClickHandler',
45361      value: function _dataApiClickHandler(event) {
45362        var selector = Util.getSelectorFromElement(this);
45363
45364        if (!selector) {
45365          return;
45366        }
45367
45368        var target = $(selector)[0];
45369
45370        if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
45371          return;
45372        }
45373
45374        var config = $.extend({}, $(target).data(), $(this).data());
45375        var slideIndex = this.getAttribute('data-slide-to');
45376
45377        if (slideIndex) {
45378          config.interval = false;
45379        }
45380
45381        Carousel._jQueryInterface.call($(target), config);
45382
45383        if (slideIndex) {
45384          $(target).data(DATA_KEY).to(slideIndex);
45385        }
45386
45387        event.preventDefault();
45388      }
45389    }, {
45390      key: 'VERSION',
45391      get: function get() {
45392        return VERSION;
45393      }
45394    }, {
45395      key: 'Default',
45396      get: function get() {
45397        return Default;
45398      }
45399    }]);
45400
45401    return Carousel;
45402  })();
45403
45404  $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);
45405
45406  $(window).on(Event.LOAD_DATA_API, function () {
45407    $(Selector.DATA_RIDE).each(function () {
45408      var $carousel = $(this);
45409      Carousel._jQueryInterface.call($carousel, $carousel.data());
45410    });
45411  });
45412
45413  /**
45414   * ------------------------------------------------------------------------
45415   * jQuery
45416   * ------------------------------------------------------------------------
45417   */
45418
45419  $.fn[NAME] = Carousel._jQueryInterface;
45420  $.fn[NAME].Constructor = Carousel;
45421  $.fn[NAME].noConflict = function () {
45422    $.fn[NAME] = JQUERY_NO_CONFLICT;
45423    return Carousel._jQueryInterface;
45424  };
45425
45426  return Carousel;
45427})(jQuery);
45428
45429/**
45430 * --------------------------------------------------------------------------
45431 * Bootstrap (v4.0.0-alpha.4): collapse.js
45432 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
45433 * --------------------------------------------------------------------------
45434 */
45435
45436var Collapse = (function ($) {
45437
45438  /**
45439   * ------------------------------------------------------------------------
45440   * Constants
45441   * ------------------------------------------------------------------------
45442   */
45443
45444  var NAME = 'collapse';
45445  var VERSION = '4.0.0-alpha.4';
45446  var DATA_KEY = 'bs.collapse';
45447  var EVENT_KEY = '.' + DATA_KEY;
45448  var DATA_API_KEY = '.data-api';
45449  var JQUERY_NO_CONFLICT = $.fn[NAME];
45450  var TRANSITION_DURATION = 600;
45451
45452  var Default = {
45453    toggle: true,
45454    parent: ''
45455  };
45456
45457  var DefaultType = {
45458    toggle: 'boolean',
45459    parent: 'string'
45460  };
45461
45462  var Event = {
45463    SHOW: 'show' + EVENT_KEY,
45464    SHOWN: 'shown' + EVENT_KEY,
45465    HIDE: 'hide' + EVENT_KEY,
45466    HIDDEN: 'hidden' + EVENT_KEY,
45467    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
45468  };
45469
45470  var ClassName = {
45471    IN: 'in',
45472    COLLAPSE: 'collapse',
45473    COLLAPSING: 'collapsing',
45474    COLLAPSED: 'collapsed'
45475  };
45476
45477  var Dimension = {
45478    WIDTH: 'width',
45479    HEIGHT: 'height'
45480  };
45481
45482  var Selector = {
45483    ACTIVES: '.panel > .in, .panel > .collapsing',
45484    DATA_TOGGLE: '[data-toggle="collapse"]'
45485  };
45486
45487  /**
45488   * ------------------------------------------------------------------------
45489   * Class Definition
45490   * ------------------------------------------------------------------------
45491   */
45492
45493  var Collapse = (function () {
45494    function Collapse(element, config) {
45495      _classCallCheck(this, Collapse);
45496
45497      this._isTransitioning = false;
45498      this._element = element;
45499      this._config = this._getConfig(config);
45500      this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]')));
45501
45502      this._parent = this._config.parent ? this._getParent() : null;
45503
45504      if (!this._config.parent) {
45505        this._addAriaAndCollapsedClass(this._element, this._triggerArray);
45506      }
45507
45508      if (this._config.toggle) {
45509        this.toggle();
45510      }
45511    }
45512
45513    /**
45514     * ------------------------------------------------------------------------
45515     * Data Api implementation
45516     * ------------------------------------------------------------------------
45517     */
45518
45519    // getters
45520
45521    _createClass(Collapse, [{
45522      key: 'toggle',
45523
45524      // public
45525
45526      value: function toggle() {
45527        if ($(this._element).hasClass(ClassName.IN)) {
45528          this.hide();
45529        } else {
45530          this.show();
45531        }
45532      }
45533    }, {
45534      key: 'show',
45535      value: function show() {
45536        var _this4 = this;
45537
45538        if (this._isTransitioning || $(this._element).hasClass(ClassName.IN)) {
45539          return;
45540        }
45541
45542        var actives = undefined;
45543        var activesData = undefined;
45544
45545        if (this._parent) {
45546          actives = $.makeArray($(Selector.ACTIVES));
45547          if (!actives.length) {
45548            actives = null;
45549          }
45550        }
45551
45552        if (actives) {
45553          activesData = $(actives).data(DATA_KEY);
45554          if (activesData && activesData._isTransitioning) {
45555            return;
45556          }
45557        }
45558
45559        var startEvent = $.Event(Event.SHOW);
45560        $(this._element).trigger(startEvent);
45561        if (startEvent.isDefaultPrevented()) {
45562          return;
45563        }
45564
45565        if (actives) {
45566          Collapse._jQueryInterface.call($(actives), 'hide');
45567          if (!activesData) {
45568            $(actives).data(DATA_KEY, null);
45569          }
45570        }
45571
45572        var dimension = this._getDimension();
45573
45574        $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING);
45575
45576        this._element.style[dimension] = 0;
45577        this._element.setAttribute('aria-expanded', true);
45578
45579        if (this._triggerArray.length) {
45580          $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true);
45581        }
45582
45583        this.setTransitioning(true);
45584
45585        var complete = function complete() {
45586          $(_this4._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.IN);
45587
45588          _this4._element.style[dimension] = '';
45589
45590          _this4.setTransitioning(false);
45591
45592          $(_this4._element).trigger(Event.SHOWN);
45593        };
45594
45595        if (!Util.supportsTransitionEnd()) {
45596          complete();
45597          return;
45598        }
45599
45600        var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
45601        var scrollSize = 'scroll' + capitalizedDimension;
45602
45603        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
45604
45605        this._element.style[dimension] = this._element[scrollSize] + 'px';
45606      }
45607    }, {
45608      key: 'hide',
45609      value: function hide() {
45610        var _this5 = this;
45611
45612        if (this._isTransitioning || !$(this._element).hasClass(ClassName.IN)) {
45613          return;
45614        }
45615
45616        var startEvent = $.Event(Event.HIDE);
45617        $(this._element).trigger(startEvent);
45618        if (startEvent.isDefaultPrevented()) {
45619          return;
45620        }
45621
45622        var dimension = this._getDimension();
45623        var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight';
45624
45625        this._element.style[dimension] = this._element[offsetDimension] + 'px';
45626
45627        Util.reflow(this._element);
45628
45629        $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.IN);
45630
45631        this._element.setAttribute('aria-expanded', false);
45632
45633        if (this._triggerArray.length) {
45634          $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
45635        }
45636
45637        this.setTransitioning(true);
45638
45639        var complete = function complete() {
45640          _this5.setTransitioning(false);
45641          $(_this5._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
45642        };
45643
45644        this._element.style[dimension] = 0;
45645
45646        if (!Util.supportsTransitionEnd()) {
45647          complete();
45648          return;
45649        }
45650
45651        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
45652      }
45653    }, {
45654      key: 'setTransitioning',
45655      value: function setTransitioning(isTransitioning) {
45656        this._isTransitioning = isTransitioning;
45657      }
45658    }, {
45659      key: 'dispose',
45660      value: function dispose() {
45661        $.removeData(this._element, DATA_KEY);
45662
45663        this._config = null;
45664        this._parent = null;
45665        this._element = null;
45666        this._triggerArray = null;
45667        this._isTransitioning = null;
45668      }
45669
45670      // private
45671
45672    }, {
45673      key: '_getConfig',
45674      value: function _getConfig(config) {
45675        config = $.extend({}, Default, config);
45676        config.toggle = Boolean(config.toggle); // coerce string values
45677        Util.typeCheckConfig(NAME, config, DefaultType);
45678        return config;
45679      }
45680    }, {
45681      key: '_getDimension',
45682      value: function _getDimension() {
45683        var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
45684        return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
45685      }
45686    }, {
45687      key: '_getParent',
45688      value: function _getParent() {
45689        var _this6 = this;
45690
45691        var parent = $(this._config.parent)[0];
45692        var selector = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]';
45693
45694        $(parent).find(selector).each(function (i, element) {
45695          _this6._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
45696        });
45697
45698        return parent;
45699      }
45700    }, {
45701      key: '_addAriaAndCollapsedClass',
45702      value: function _addAriaAndCollapsedClass(element, triggerArray) {
45703        if (element) {
45704          var isOpen = $(element).hasClass(ClassName.IN);
45705          element.setAttribute('aria-expanded', isOpen);
45706
45707          if (triggerArray.length) {
45708            $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
45709          }
45710        }
45711      }
45712
45713      // static
45714
45715    }], [{
45716      key: '_getTargetFromElement',
45717      value: function _getTargetFromElement(element) {
45718        var selector = Util.getSelectorFromElement(element);
45719        return selector ? $(selector)[0] : null;
45720      }
45721    }, {
45722      key: '_jQueryInterface',
45723      value: function _jQueryInterface(config) {
45724        return this.each(function () {
45725          var $this = $(this);
45726          var data = $this.data(DATA_KEY);
45727          var _config = $.extend({}, Default, $this.data(), typeof config === 'object' && config);
45728
45729          if (!data && _config.toggle && /show|hide/.test(config)) {
45730            _config.toggle = false;
45731          }
45732
45733          if (!data) {
45734            data = new Collapse(this, _config);
45735            $this.data(DATA_KEY, data);
45736          }
45737
45738          if (typeof config === 'string') {
45739            if (data[config] === undefined) {
45740              throw new Error('No method named "' + config + '"');
45741            }
45742            data[config]();
45743          }
45744        });
45745      }
45746    }, {
45747      key: 'VERSION',
45748      get: function get() {
45749        return VERSION;
45750      }
45751    }, {
45752      key: 'Default',
45753      get: function get() {
45754        return Default;
45755      }
45756    }]);
45757
45758    return Collapse;
45759  })();
45760
45761  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
45762    event.preventDefault();
45763
45764    var target = Collapse._getTargetFromElement(this);
45765    var data = $(target).data(DATA_KEY);
45766    var config = data ? 'toggle' : $(this).data();
45767
45768    Collapse._jQueryInterface.call($(target), config);
45769  });
45770
45771  /**
45772   * ------------------------------------------------------------------------
45773   * jQuery
45774   * ------------------------------------------------------------------------
45775   */
45776
45777  $.fn[NAME] = Collapse._jQueryInterface;
45778  $.fn[NAME].Constructor = Collapse;
45779  $.fn[NAME].noConflict = function () {
45780    $.fn[NAME] = JQUERY_NO_CONFLICT;
45781    return Collapse._jQueryInterface;
45782  };
45783
45784  return Collapse;
45785})(jQuery);
45786
45787/**
45788 * --------------------------------------------------------------------------
45789 * Bootstrap (v4.0.0-alpha.4): dropdown.js
45790 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
45791 * --------------------------------------------------------------------------
45792 */
45793
45794var Dropdown = (function ($) {
45795
45796  /**
45797   * ------------------------------------------------------------------------
45798   * Constants
45799   * ------------------------------------------------------------------------
45800   */
45801
45802  var NAME = 'dropdown';
45803  var VERSION = '4.0.0-alpha.4';
45804  var DATA_KEY = 'bs.dropdown';
45805  var EVENT_KEY = '.' + DATA_KEY;
45806  var DATA_API_KEY = '.data-api';
45807  var JQUERY_NO_CONFLICT = $.fn[NAME];
45808  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
45809  var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
45810  var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
45811  var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
45812
45813  var Event = {
45814    HIDE: 'hide' + EVENT_KEY,
45815    HIDDEN: 'hidden' + EVENT_KEY,
45816    SHOW: 'show' + EVENT_KEY,
45817    SHOWN: 'shown' + EVENT_KEY,
45818    CLICK: 'click' + EVENT_KEY,
45819    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
45820    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY
45821  };
45822
45823  var ClassName = {
45824    BACKDROP: 'dropdown-backdrop',
45825    DISABLED: 'disabled',
45826    OPEN: 'open'
45827  };
45828
45829  var Selector = {
45830    BACKDROP: '.dropdown-backdrop',
45831    DATA_TOGGLE: '[data-toggle="dropdown"]',
45832    FORM_CHILD: '.dropdown form',
45833    ROLE_MENU: '[role="menu"]',
45834    ROLE_LISTBOX: '[role="listbox"]',
45835    NAVBAR_NAV: '.navbar-nav',
45836    VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a'
45837  };
45838
45839  /**
45840   * ------------------------------------------------------------------------
45841   * Class Definition
45842   * ------------------------------------------------------------------------
45843   */
45844
45845  var Dropdown = (function () {
45846    function Dropdown(element) {
45847      _classCallCheck(this, Dropdown);
45848
45849      this._element = element;
45850
45851      this._addEventListeners();
45852    }
45853
45854    /**
45855     * ------------------------------------------------------------------------
45856     * Data Api implementation
45857     * ------------------------------------------------------------------------
45858     */
45859
45860    // getters
45861
45862    _createClass(Dropdown, [{
45863      key: 'toggle',
45864
45865      // public
45866
45867      value: function toggle() {
45868        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
45869          return false;
45870        }
45871
45872        var parent = Dropdown._getParentFromElement(this);
45873        var isActive = $(parent).hasClass(ClassName.OPEN);
45874
45875        Dropdown._clearMenus();
45876
45877        if (isActive) {
45878          return false;
45879        }
45880
45881        if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
45882
45883          // if mobile we use a backdrop because click events don't delegate
45884          var dropdown = document.createElement('div');
45885          dropdown.className = ClassName.BACKDROP;
45886          $(dropdown).insertBefore(this);
45887          $(dropdown).on('click', Dropdown._clearMenus);
45888        }
45889
45890        var relatedTarget = { relatedTarget: this };
45891        var showEvent = $.Event(Event.SHOW, relatedTarget);
45892
45893        $(parent).trigger(showEvent);
45894
45895        if (showEvent.isDefaultPrevented()) {
45896          return false;
45897        }
45898
45899        this.focus();
45900        this.setAttribute('aria-expanded', 'true');
45901
45902        $(parent).toggleClass(ClassName.OPEN);
45903        $(parent).trigger($.Event(Event.SHOWN, relatedTarget));
45904
45905        return false;
45906      }
45907    }, {
45908      key: 'dispose',
45909      value: function dispose() {
45910        $.removeData(this._element, DATA_KEY);
45911        $(this._element).off(EVENT_KEY);
45912        this._element = null;
45913      }
45914
45915      // private
45916
45917    }, {
45918      key: '_addEventListeners',
45919      value: function _addEventListeners() {
45920        $(this._element).on(Event.CLICK, this.toggle);
45921      }
45922
45923      // static
45924
45925    }], [{
45926      key: '_jQueryInterface',
45927      value: function _jQueryInterface(config) {
45928        return this.each(function () {
45929          var data = $(this).data(DATA_KEY);
45930
45931          if (!data) {
45932            $(this).data(DATA_KEY, data = new Dropdown(this));
45933          }
45934
45935          if (typeof config === 'string') {
45936            if (data[config] === undefined) {
45937              throw new Error('No method named "' + config + '"');
45938            }
45939            data[config].call(this);
45940          }
45941        });
45942      }
45943    }, {
45944      key: '_clearMenus',
45945      value: function _clearMenus(event) {
45946        if (event && event.which === RIGHT_MOUSE_BUTTON_WHICH) {
45947          return;
45948        }
45949
45950        var backdrop = $(Selector.BACKDROP)[0];
45951        if (backdrop) {
45952          backdrop.parentNode.removeChild(backdrop);
45953        }
45954
45955        var toggles = $.makeArray($(Selector.DATA_TOGGLE));
45956
45957        for (var i = 0; i < toggles.length; i++) {
45958          var _parent = Dropdown._getParentFromElement(toggles[i]);
45959          var relatedTarget = { relatedTarget: toggles[i] };
45960
45961          if (!$(_parent).hasClass(ClassName.OPEN)) {
45962            continue;
45963          }
45964
45965          if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) {
45966            continue;
45967          }
45968
45969          var hideEvent = $.Event(Event.HIDE, relatedTarget);
45970          $(_parent).trigger(hideEvent);
45971          if (hideEvent.isDefaultPrevented()) {
45972            continue;
45973          }
45974
45975          toggles[i].setAttribute('aria-expanded', 'false');
45976
45977          $(_parent).removeClass(ClassName.OPEN).trigger($.Event(Event.HIDDEN, relatedTarget));
45978        }
45979      }
45980    }, {
45981      key: '_getParentFromElement',
45982      value: function _getParentFromElement(element) {
45983        var parent = undefined;
45984        var selector = Util.getSelectorFromElement(element);
45985
45986        if (selector) {
45987          parent = $(selector)[0];
45988        }
45989
45990        return parent || element.parentNode;
45991      }
45992    }, {
45993      key: '_dataApiKeydownHandler',
45994      value: function _dataApiKeydownHandler(event) {
45995        if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
45996          return;
45997        }
45998
45999        event.preventDefault();
46000        event.stopPropagation();
46001
46002        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
46003          return;
46004        }
46005
46006        var parent = Dropdown._getParentFromElement(this);
46007        var isActive = $(parent).hasClass(ClassName.OPEN);
46008
46009        if (!isActive && event.which !== ESCAPE_KEYCODE || isActive && event.which === ESCAPE_KEYCODE) {
46010
46011          if (event.which === ESCAPE_KEYCODE) {
46012            var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
46013            $(toggle).trigger('focus');
46014          }
46015
46016          $(this).trigger('click');
46017          return;
46018        }
46019
46020        var items = $.makeArray($(Selector.VISIBLE_ITEMS));
46021
46022        items = items.filter(function (item) {
46023          return item.offsetWidth || item.offsetHeight;
46024        });
46025
46026        if (!items.length) {
46027          return;
46028        }
46029
46030        var index = items.indexOf(event.target);
46031
46032        if (event.which === ARROW_UP_KEYCODE && index > 0) {
46033          // up
46034          index--;
46035        }
46036
46037        if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
46038          // down
46039          index++;
46040        }
46041
46042        if (index < 0) {
46043          index = 0;
46044        }
46045
46046        items[index].focus();
46047      }
46048    }, {
46049      key: 'VERSION',
46050      get: function get() {
46051        return VERSION;
46052      }
46053    }]);
46054
46055    return Dropdown;
46056  })();
46057
46058  $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
46059    e.stopPropagation();
46060  });
46061
46062  /**
46063   * ------------------------------------------------------------------------
46064   * jQuery
46065   * ------------------------------------------------------------------------
46066   */
46067
46068  $.fn[NAME] = Dropdown._jQueryInterface;
46069  $.fn[NAME].Constructor = Dropdown;
46070  $.fn[NAME].noConflict = function () {
46071    $.fn[NAME] = JQUERY_NO_CONFLICT;
46072    return Dropdown._jQueryInterface;
46073  };
46074
46075  return Dropdown;
46076})(jQuery);
46077
46078/**
46079 * --------------------------------------------------------------------------
46080 * Bootstrap (v4.0.0-alpha.4): modal.js
46081 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
46082 * --------------------------------------------------------------------------
46083 */
46084
46085var Modal = (function ($) {
46086
46087  /**
46088   * ------------------------------------------------------------------------
46089   * Constants
46090   * ------------------------------------------------------------------------
46091   */
46092
46093  var NAME = 'modal';
46094  var VERSION = '4.0.0-alpha.4';
46095  var DATA_KEY = 'bs.modal';
46096  var EVENT_KEY = '.' + DATA_KEY;
46097  var DATA_API_KEY = '.data-api';
46098  var JQUERY_NO_CONFLICT = $.fn[NAME];
46099  var TRANSITION_DURATION = 300;
46100  var BACKDROP_TRANSITION_DURATION = 150;
46101  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
46102
46103  var Default = {
46104    backdrop: true,
46105    keyboard: true,
46106    focus: true,
46107    show: true
46108  };
46109
46110  var DefaultType = {
46111    backdrop: '(boolean|string)',
46112    keyboard: 'boolean',
46113    focus: 'boolean',
46114    show: 'boolean'
46115  };
46116
46117  var Event = {
46118    HIDE: 'hide' + EVENT_KEY,
46119    HIDDEN: 'hidden' + EVENT_KEY,
46120    SHOW: 'show' + EVENT_KEY,
46121    SHOWN: 'shown' + EVENT_KEY,
46122    FOCUSIN: 'focusin' + EVENT_KEY,
46123    RESIZE: 'resize' + EVENT_KEY,
46124    CLICK_DISMISS: 'click.dismiss' + EVENT_KEY,
46125    KEYDOWN_DISMISS: 'keydown.dismiss' + EVENT_KEY,
46126    MOUSEUP_DISMISS: 'mouseup.dismiss' + EVENT_KEY,
46127    MOUSEDOWN_DISMISS: 'mousedown.dismiss' + EVENT_KEY,
46128    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
46129  };
46130
46131  var ClassName = {
46132    SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
46133    BACKDROP: 'modal-backdrop',
46134    OPEN: 'modal-open',
46135    FADE: 'fade',
46136    IN: 'in'
46137  };
46138
46139  var Selector = {
46140    DIALOG: '.modal-dialog',
46141    DATA_TOGGLE: '[data-toggle="modal"]',
46142    DATA_DISMISS: '[data-dismiss="modal"]',
46143    FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed'
46144  };
46145
46146  /**
46147   * ------------------------------------------------------------------------
46148   * Class Definition
46149   * ------------------------------------------------------------------------
46150   */
46151
46152  var Modal = (function () {
46153    function Modal(element, config) {
46154      _classCallCheck(this, Modal);
46155
46156      this._config = this._getConfig(config);
46157      this._element = element;
46158      this._dialog = $(element).find(Selector.DIALOG)[0];
46159      this._backdrop = null;
46160      this._isShown = false;
46161      this._isBodyOverflowing = false;
46162      this._ignoreBackdropClick = false;
46163      this._originalBodyPadding = 0;
46164      this._scrollbarWidth = 0;
46165    }
46166
46167    /**
46168     * ------------------------------------------------------------------------
46169     * Data Api implementation
46170     * ------------------------------------------------------------------------
46171     */
46172
46173    // getters
46174
46175    _createClass(Modal, [{
46176      key: 'toggle',
46177
46178      // public
46179
46180      value: function toggle(relatedTarget) {
46181        return this._isShown ? this.hide() : this.show(relatedTarget);
46182      }
46183    }, {
46184      key: 'show',
46185      value: function show(relatedTarget) {
46186        var _this7 = this;
46187
46188        var showEvent = $.Event(Event.SHOW, {
46189          relatedTarget: relatedTarget
46190        });
46191
46192        $(this._element).trigger(showEvent);
46193
46194        if (this._isShown || showEvent.isDefaultPrevented()) {
46195          return;
46196        }
46197
46198        this._isShown = true;
46199
46200        this._checkScrollbar();
46201        this._setScrollbar();
46202
46203        $(document.body).addClass(ClassName.OPEN);
46204
46205        this._setEscapeEvent();
46206        this._setResizeEvent();
46207
46208        $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, $.proxy(this.hide, this));
46209
46210        $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
46211          $(_this7._element).one(Event.MOUSEUP_DISMISS, function (event) {
46212            if ($(event.target).is(_this7._element)) {
46213              _this7._ignoreBackdropClick = true;
46214            }
46215          });
46216        });
46217
46218        this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
46219      }
46220    }, {
46221      key: 'hide',
46222      value: function hide(event) {
46223        if (event) {
46224          event.preventDefault();
46225        }
46226
46227        var hideEvent = $.Event(Event.HIDE);
46228
46229        $(this._element).trigger(hideEvent);
46230
46231        if (!this._isShown || hideEvent.isDefaultPrevented()) {
46232          return;
46233        }
46234
46235        this._isShown = false;
46236
46237        this._setEscapeEvent();
46238        this._setResizeEvent();
46239
46240        $(document).off(Event.FOCUSIN);
46241
46242        $(this._element).removeClass(ClassName.IN);
46243
46244        $(this._element).off(Event.CLICK_DISMISS);
46245        $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
46246
46247        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
46248
46249          $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION);
46250        } else {
46251          this._hideModal();
46252        }
46253      }
46254    }, {
46255      key: 'dispose',
46256      value: function dispose() {
46257        $.removeData(this._element, DATA_KEY);
46258
46259        $(window).off(EVENT_KEY);
46260        $(document).off(EVENT_KEY);
46261        $(this._element).off(EVENT_KEY);
46262        $(this._backdrop).off(EVENT_KEY);
46263
46264        this._config = null;
46265        this._element = null;
46266        this._dialog = null;
46267        this._backdrop = null;
46268        this._isShown = null;
46269        this._isBodyOverflowing = null;
46270        this._ignoreBackdropClick = null;
46271        this._originalBodyPadding = null;
46272        this._scrollbarWidth = null;
46273      }
46274
46275      // private
46276
46277    }, {
46278      key: '_getConfig',
46279      value: function _getConfig(config) {
46280        config = $.extend({}, Default, config);
46281        Util.typeCheckConfig(NAME, config, DefaultType);
46282        return config;
46283      }
46284    }, {
46285      key: '_showElement',
46286      value: function _showElement(relatedTarget) {
46287        var _this8 = this;
46288
46289        var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
46290
46291        if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
46292          // don't move modals dom position
46293          document.body.appendChild(this._element);
46294        }
46295
46296        this._element.style.display = 'block';
46297        this._element.removeAttribute('aria-hidden');
46298        this._element.scrollTop = 0;
46299
46300        if (transition) {
46301          Util.reflow(this._element);
46302        }
46303
46304        $(this._element).addClass(ClassName.IN);
46305
46306        if (this._config.focus) {
46307          this._enforceFocus();
46308        }
46309
46310        var shownEvent = $.Event(Event.SHOWN, {
46311          relatedTarget: relatedTarget
46312        });
46313
46314        var transitionComplete = function transitionComplete() {
46315          if (_this8._config.focus) {
46316            _this8._element.focus();
46317          }
46318          $(_this8._element).trigger(shownEvent);
46319        };
46320
46321        if (transition) {
46322          $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
46323        } else {
46324          transitionComplete();
46325        }
46326      }
46327    }, {
46328      key: '_enforceFocus',
46329      value: function _enforceFocus() {
46330        var _this9 = this;
46331
46332        $(document).off(Event.FOCUSIN) // guard against infinite focus loop
46333        .on(Event.FOCUSIN, function (event) {
46334          if (document !== event.target && _this9._element !== event.target && !$(_this9._element).has(event.target).length) {
46335            _this9._element.focus();
46336          }
46337        });
46338      }
46339    }, {
46340      key: '_setEscapeEvent',
46341      value: function _setEscapeEvent() {
46342        var _this10 = this;
46343
46344        if (this._isShown && this._config.keyboard) {
46345          $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
46346            if (event.which === ESCAPE_KEYCODE) {
46347              _this10.hide();
46348            }
46349          });
46350        } else if (!this._isShown) {
46351          $(this._element).off(Event.KEYDOWN_DISMISS);
46352        }
46353      }
46354    }, {
46355      key: '_setResizeEvent',
46356      value: function _setResizeEvent() {
46357        if (this._isShown) {
46358          $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this));
46359        } else {
46360          $(window).off(Event.RESIZE);
46361        }
46362      }
46363    }, {
46364      key: '_hideModal',
46365      value: function _hideModal() {
46366        var _this11 = this;
46367
46368        this._element.style.display = 'none';
46369        this._element.setAttribute('aria-hidden', 'true');
46370        this._showBackdrop(function () {
46371          $(document.body).removeClass(ClassName.OPEN);
46372          _this11._resetAdjustments();
46373          _this11._resetScrollbar();
46374          $(_this11._element).trigger(Event.HIDDEN);
46375        });
46376      }
46377    }, {
46378      key: '_removeBackdrop',
46379      value: function _removeBackdrop() {
46380        if (this._backdrop) {
46381          $(this._backdrop).remove();
46382          this._backdrop = null;
46383        }
46384      }
46385    }, {
46386      key: '_showBackdrop',
46387      value: function _showBackdrop(callback) {
46388        var _this12 = this;
46389
46390        var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
46391
46392        if (this._isShown && this._config.backdrop) {
46393          var doAnimate = Util.supportsTransitionEnd() && animate;
46394
46395          this._backdrop = document.createElement('div');
46396          this._backdrop.className = ClassName.BACKDROP;
46397
46398          if (animate) {
46399            $(this._backdrop).addClass(animate);
46400          }
46401
46402          $(this._backdrop).appendTo(document.body);
46403
46404          $(this._element).on(Event.CLICK_DISMISS, function (event) {
46405            if (_this12._ignoreBackdropClick) {
46406              _this12._ignoreBackdropClick = false;
46407              return;
46408            }
46409            if (event.target !== event.currentTarget) {
46410              return;
46411            }
46412            if (_this12._config.backdrop === 'static') {
46413              _this12._element.focus();
46414            } else {
46415              _this12.hide();
46416            }
46417          });
46418
46419          if (doAnimate) {
46420            Util.reflow(this._backdrop);
46421          }
46422
46423          $(this._backdrop).addClass(ClassName.IN);
46424
46425          if (!callback) {
46426            return;
46427          }
46428
46429          if (!doAnimate) {
46430            callback();
46431            return;
46432          }
46433
46434          $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
46435        } else if (!this._isShown && this._backdrop) {
46436          $(this._backdrop).removeClass(ClassName.IN);
46437
46438          var callbackRemove = function callbackRemove() {
46439            _this12._removeBackdrop();
46440            if (callback) {
46441              callback();
46442            }
46443          };
46444
46445          if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
46446            $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
46447          } else {
46448            callbackRemove();
46449          }
46450        } else if (callback) {
46451          callback();
46452        }
46453      }
46454
46455      // ----------------------------------------------------------------------
46456      // the following methods are used to handle overflowing modals
46457      // todo (fat): these should probably be refactored out of modal.js
46458      // ----------------------------------------------------------------------
46459
46460    }, {
46461      key: '_handleUpdate',
46462      value: function _handleUpdate() {
46463        this._adjustDialog();
46464      }
46465    }, {
46466      key: '_adjustDialog',
46467      value: function _adjustDialog() {
46468        var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
46469
46470        if (!this._isBodyOverflowing && isModalOverflowing) {
46471          this._element.style.paddingLeft = this._scrollbarWidth + 'px';
46472        }
46473
46474        if (this._isBodyOverflowing && !isModalOverflowing) {
46475          this._element.style.paddingRight = this._scrollbarWidth + 'px';
46476        }
46477      }
46478    }, {
46479      key: '_resetAdjustments',
46480      value: function _resetAdjustments() {
46481        this._element.style.paddingLeft = '';
46482        this._element.style.paddingRight = '';
46483      }
46484    }, {
46485      key: '_checkScrollbar',
46486      value: function _checkScrollbar() {
46487        this._isBodyOverflowing = document.body.clientWidth < window.innerWidth;
46488        this._scrollbarWidth = this._getScrollbarWidth();
46489      }
46490    }, {
46491      key: '_setScrollbar',
46492      value: function _setScrollbar() {
46493        var bodyPadding = parseInt($(Selector.FIXED_CONTENT).css('padding-right') || 0, 10);
46494
46495        this._originalBodyPadding = document.body.style.paddingRight || '';
46496
46497        if (this._isBodyOverflowing) {
46498          document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
46499        }
46500      }
46501    }, {
46502      key: '_resetScrollbar',
46503      value: function _resetScrollbar() {
46504        document.body.style.paddingRight = this._originalBodyPadding;
46505      }
46506    }, {
46507      key: '_getScrollbarWidth',
46508      value: function _getScrollbarWidth() {
46509        // thx d.walsh
46510        var scrollDiv = document.createElement('div');
46511        scrollDiv.className = ClassName.SCROLLBAR_MEASURER;
46512        document.body.appendChild(scrollDiv);
46513        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
46514        document.body.removeChild(scrollDiv);
46515        return scrollbarWidth;
46516      }
46517
46518      // static
46519
46520    }], [{
46521      key: '_jQueryInterface',
46522      value: function _jQueryInterface(config, relatedTarget) {
46523        return this.each(function () {
46524          var data = $(this).data(DATA_KEY);
46525          var _config = $.extend({}, Modal.Default, $(this).data(), typeof config === 'object' && config);
46526
46527          if (!data) {
46528            data = new Modal(this, _config);
46529            $(this).data(DATA_KEY, data);
46530          }
46531
46532          if (typeof config === 'string') {
46533            if (data[config] === undefined) {
46534              throw new Error('No method named "' + config + '"');
46535            }
46536            data[config](relatedTarget);
46537          } else if (_config.show) {
46538            data.show(relatedTarget);
46539          }
46540        });
46541      }
46542    }, {
46543      key: 'VERSION',
46544      get: function get() {
46545        return VERSION;
46546      }
46547    }, {
46548      key: 'Default',
46549      get: function get() {
46550        return Default;
46551      }
46552    }]);
46553
46554    return Modal;
46555  })();
46556
46557  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
46558    var _this13 = this;
46559
46560    var target = undefined;
46561    var selector = Util.getSelectorFromElement(this);
46562
46563    if (selector) {
46564      target = $(selector)[0];
46565    }
46566
46567    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
46568
46569    if (this.tagName === 'A') {
46570      event.preventDefault();
46571    }
46572
46573    var $target = $(target).one(Event.SHOW, function (showEvent) {
46574      if (showEvent.isDefaultPrevented()) {
46575        // only register focus restorer if modal will actually get shown
46576        return;
46577      }
46578
46579      $target.one(Event.HIDDEN, function () {
46580        if ($(_this13).is(':visible')) {
46581          _this13.focus();
46582        }
46583      });
46584    });
46585
46586    Modal._jQueryInterface.call($(target), config, this);
46587  });
46588
46589  /**
46590   * ------------------------------------------------------------------------
46591   * jQuery
46592   * ------------------------------------------------------------------------
46593   */
46594
46595  $.fn[NAME] = Modal._jQueryInterface;
46596  $.fn[NAME].Constructor = Modal;
46597  $.fn[NAME].noConflict = function () {
46598    $.fn[NAME] = JQUERY_NO_CONFLICT;
46599    return Modal._jQueryInterface;
46600  };
46601
46602  return Modal;
46603})(jQuery);
46604
46605/**
46606 * --------------------------------------------------------------------------
46607 * Bootstrap (v4.0.0-alpha.4): scrollspy.js
46608 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
46609 * --------------------------------------------------------------------------
46610 */
46611
46612var ScrollSpy = (function ($) {
46613
46614  /**
46615   * ------------------------------------------------------------------------
46616   * Constants
46617   * ------------------------------------------------------------------------
46618   */
46619
46620  var NAME = 'scrollspy';
46621  var VERSION = '4.0.0-alpha.4';
46622  var DATA_KEY = 'bs.scrollspy';
46623  var EVENT_KEY = '.' + DATA_KEY;
46624  var DATA_API_KEY = '.data-api';
46625  var JQUERY_NO_CONFLICT = $.fn[NAME];
46626
46627  var Default = {
46628    offset: 10,
46629    method: 'auto',
46630    target: ''
46631  };
46632
46633  var DefaultType = {
46634    offset: 'number',
46635    method: 'string',
46636    target: '(string|element)'
46637  };
46638
46639  var Event = {
46640    ACTIVATE: 'activate' + EVENT_KEY,
46641    SCROLL: 'scroll' + EVENT_KEY,
46642    LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY
46643  };
46644
46645  var ClassName = {
46646    DROPDOWN_ITEM: 'dropdown-item',
46647    DROPDOWN_MENU: 'dropdown-menu',
46648    NAV_LINK: 'nav-link',
46649    NAV: 'nav',
46650    ACTIVE: 'active'
46651  };
46652
46653  var Selector = {
46654    DATA_SPY: '[data-spy="scroll"]',
46655    ACTIVE: '.active',
46656    LIST_ITEM: '.list-item',
46657    LI: 'li',
46658    LI_DROPDOWN: 'li.dropdown',
46659    NAV_LINKS: '.nav-link',
46660    DROPDOWN: '.dropdown',
46661    DROPDOWN_ITEMS: '.dropdown-item',
46662    DROPDOWN_TOGGLE: '.dropdown-toggle'
46663  };
46664
46665  var OffsetMethod = {
46666    OFFSET: 'offset',
46667    POSITION: 'position'
46668  };
46669
46670  /**
46671   * ------------------------------------------------------------------------
46672   * Class Definition
46673   * ------------------------------------------------------------------------
46674   */
46675
46676  var ScrollSpy = (function () {
46677    function ScrollSpy(element, config) {
46678      _classCallCheck(this, ScrollSpy);
46679
46680      this._element = element;
46681      this._scrollElement = element.tagName === 'BODY' ? window : element;
46682      this._config = this._getConfig(config);
46683      this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS);
46684      this._offsets = [];
46685      this._targets = [];
46686      this._activeTarget = null;
46687      this._scrollHeight = 0;
46688
46689      $(this._scrollElement).on(Event.SCROLL, $.proxy(this._process, this));
46690
46691      this.refresh();
46692      this._process();
46693    }
46694
46695    /**
46696     * ------------------------------------------------------------------------
46697     * Data Api implementation
46698     * ------------------------------------------------------------------------
46699     */
46700
46701    // getters
46702
46703    _createClass(ScrollSpy, [{
46704      key: 'refresh',
46705
46706      // public
46707
46708      value: function refresh() {
46709        var _this14 = this;
46710
46711        var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
46712
46713        var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
46714
46715        var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
46716
46717        this._offsets = [];
46718        this._targets = [];
46719
46720        this._scrollHeight = this._getScrollHeight();
46721
46722        var targets = $.makeArray($(this._selector));
46723
46724        targets.map(function (element) {
46725          var target = undefined;
46726          var targetSelector = Util.getSelectorFromElement(element);
46727
46728          if (targetSelector) {
46729            target = $(targetSelector)[0];
46730          }
46731
46732          if (target && (target.offsetWidth || target.offsetHeight)) {
46733            // todo (fat): remove sketch reliance on jQuery position/offset
46734            return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
46735          }
46736          return null;
46737        }).filter(function (item) {
46738          return item;
46739        }).sort(function (a, b) {
46740          return a[0] - b[0];
46741        }
46741).forEach(function (item) {
46742          _this14._offsets.push(item[0]);
46743          _this14._targets.push(item[1]);
46744        });
46745      }
46746    }, {
46747      key: 'dispose',
46748      value: function dispose() {
46749        $.removeData(this._element, DATA_KEY);
46750        $(this._scrollElement).off(EVENT_KEY);
46751
46752        this._element = null;
46753        this._scrollElement = null;
46754        this._config = null;
46755        this._selector = null;
46756        this._offsets = null;
46757        this._targets = null;
46758        this._activeTarget = null;
46759        this._scrollHeight = null;
46760      }
46761
46762      // private
46763
46764    }, {
46765      key: '_getConfig',
46766      value: function _getConfig(config) {
46767        config = $.extend({}, Default, config);
46768
46769        if (typeof config.target !== 'string') {
46770          var id = $(config.target).attr('id');
46771          if (!id) {
46772            id = Util.getUID(NAME);
46773            $(config.target).attr('id', id);
46774          }
46775          config.target = '#' + id;
46776        }
46777
46778        Util.typeCheckConfig(NAME, config, DefaultType);
46779
46780        return config;
46781      }
46782    }, {
46783      key: '_getScrollTop',
46784      value: function _getScrollTop() {
46785        return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop;
46786      }
46787    }, {
46788      key: '_getScrollHeight',
46789      value: function _getScrollHeight() {
46790        return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
46791      }
46792    }, {
46793      key: '_process',
46794      value: function _process() {
46795        var scrollTop = this._getScrollTop() + this._config.offset;
46796        var scrollHeight = this._getScrollHeight();
46797        var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight;
46798
46799        if (this._scrollHeight !== scrollHeight) {
46800          this.refresh();
46801        }
46802
46803        if (scrollTop >= maxScroll) {
46804          var target = this._targets[this._targets.length - 1];
46805
46806          if (this._activeTarget !== target) {
46807            this._activate(target);
46808          }
46809        }
46810
46811        if (this._activeTarget && scrollTop < this._offsets[0]) {
46812          this._activeTarget = null;
46813          this._clear();
46814          return;
46815        }
46816
46817        for (var i = this._offsets.length; i--;) {
46818          var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (this._offsets[i + 1] === undefined || scrollTop < this._offsets[i + 1]);
46819
46820          if (isActiveTarget) {
46821            this._activate(this._targets[i]);
46822          }
46823        }
46824      }
46825    }, {
46826      key: '_activate',
46827      value: function _activate(target) {
46828        this._activeTarget = target;
46829
46830        this._clear();
46831
46832        var queries = this._selector.split(',');
46833        queries = queries.map(function (selector) {
46834          return selector + '[data-target="' + target + '"],' + (selector + '[href="' + target + '"]');
46835        });
46836
46837        var $link = $(queries.join(','));
46838
46839        if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
46840          $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
46841          $link.addClass(ClassName.ACTIVE);
46842        } else {
46843          // todo (fat) this is kinda sus...
46844          // recursively add actives to tested nav-links
46845          $link.parents(Selector.LI).find(Selector.NAV_LINKS).addClass(ClassName.ACTIVE);
46846        }
46847
46848        $(this._scrollElement).trigger(Event.ACTIVATE, {
46849          relatedTarget: target
46850        });
46851      }
46852    }, {
46853      key: '_clear',
46854      value: function _clear() {
46855        $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
46856      }
46857
46858      // static
46859
46860    }], [{
46861      key: '_jQueryInterface',
46862      value: function _jQueryInterface(config) {
46863        return this.each(function () {
46864          var data = $(this).data(DATA_KEY);
46865          var _config = typeof config === 'object' && config || null;
46866
46867          if (!data) {
46868            data = new ScrollSpy(this, _config);
46869            $(this).data(DATA_KEY, data);
46870          }
46871
46872          if (typeof config === 'string') {
46873            if (data[config] === undefined) {
46874              throw new Error('No method named "' + config + '"');
46875            }
46876            data[config]();
46877          }
46878        });
46879      }
46880    }, {
46881      key: 'VERSION',
46882      get: function get() {
46883        return VERSION;
46884      }
46885    }, {
46886      key: 'Default',
46887      get: function get() {
46888        return Default;
46889      }
46890    }]);
46891
46892    return ScrollSpy;
46893  })();
46894
46895  $(window).on(Event.LOAD_DATA_API, function () {
46896    var scrollSpys = $.makeArray($(Selector.DATA_SPY));
46897
46898    for (var i = scrollSpys.length; i--;) {
46899      var $spy = $(scrollSpys[i]);
46900      ScrollSpy._jQueryInterface.call($spy, $spy.data());
46901    }
46902  });
46903
46904  /**
46905   * ------------------------------------------------------------------------
46906   * jQuery
46907   * ------------------------------------------------------------------------
46908   */
46909
46910  $.fn[NAME] = ScrollSpy._jQueryInterface;
46911  $.fn[NAME].Constructor = ScrollSpy;
46912  $.fn[NAME].noConflict = function () {
46913    $.fn[NAME] = JQUERY_NO_CONFLICT;
46914    return ScrollSpy._jQueryInterface;
46915  };
46916
46917  return ScrollSpy;
46918})(jQuery);
46919
46920/**
46921 * --------------------------------------------------------------------------
46922 * Bootstrap (v4.0.0-alpha.4): tab.js
46923 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
46924 * --------------------------------------------------------------------------
46925 */
46926
46927var Tab = (function ($) {
46928
46929  /**
46930   * ------------------------------------------------------------------------
46931   * Constants
46932   * ------------------------------------------------------------------------
46933   */
46934
46935  var NAME = 'tab';
46936  var VERSION = '4.0.0-alpha.4';
46937  var DATA_KEY = 'bs.tab';
46938  var EVENT_KEY = '.' + DATA_KEY;
46939  var DATA_API_KEY = '.data-api';
46940  var JQUERY_NO_CONFLICT = $.fn[NAME];
46941  var TRANSITION_DURATION = 150;
46942
46943  var Event = {
46944    HIDE: 'hide' + EVENT_KEY,
46945    HIDDEN: 'hidden' + EVENT_KEY,
46946    SHOW: 'show' + EVENT_KEY,
46947    SHOWN: 'shown' + EVENT_KEY,
46948    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
46949  };
46950
46951  var ClassName = {
46952    DROPDOWN_MENU: 'dropdown-menu',
46953    ACTIVE: 'active',
46954    FADE: 'fade',
46955    IN: 'in'
46956  };
46957
46958  var Selector = {
46959    A: 'a',
46960    LI: 'li',
46961    DROPDOWN: '.dropdown',
46962    UL: 'ul:not(.dropdown-menu)',
46963    FADE_CHILD: '> .nav-item .fade, > .fade',
46964    ACTIVE: '.active',
46965    ACTIVE_CHILD: '> .nav-item > .active, > .active',
46966    DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]',
46967    DROPDOWN_TOGGLE: '.dropdown-toggle',
46968    DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
46969  };
46970
46971  /**
46972   * ------------------------------------------------------------------------
46973   * Class Definition
46974   * ------------------------------------------------------------------------
46975   */
46976
46977  var Tab = (function () {
46978    function Tab(element) {
46979      _classCallCheck(this, Tab);
46980
46981      this._element = element;
46982    }
46983
46984    /**
46985     * ------------------------------------------------------------------------
46986     * Data Api implementation
46987     * ------------------------------------------------------------------------
46988     */
46989
46990    // getters
46991
46992    _createClass(Tab, [{
46993      key: 'show',
46994
46995      // public
46996
46997      value: function show() {
46998        var _this15 = this;
46999
47000        if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName.ACTIVE)) {
47001          return;
47002        }
47003
47004        var target = undefined;
47005        var previous = undefined;
47006        var ulElement = $(this._element).closest(Selector.UL)[0];
47007        var selector = Util.getSelectorFromElement(this._element);
47008
47009        if (ulElement) {
47010          previous = $.makeArray($(ulElement).find(Selector.ACTIVE));
47011          previous = previous[previous.length - 1];
47012        }
47013
47014        var hideEvent = $.Event(Event.HIDE, {
47015          relatedTarget: this._element
47016        });
47017
47018        var showEvent = $.Event(Event.SHOW, {
47019          relatedTarget: previous
47020        });
47021
47022        if (previous) {
47023          $(previous).trigger(hideEvent);
47024        }
47025
47026        $(this._element).trigger(showEvent);
47027
47028        if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
47029          return;
47030        }
47031
47032        if (selector) {
47033          target = $(selector)[0];
47034        }
47035
47036        this._activate(this._element, ulElement);
47037
47038        var complete = function complete() {
47039          var hiddenEvent = $.Event(Event.HIDDEN, {
47040            relatedTarget: _this15._element
47041          });
47042
47043          var shownEvent = $.Event(Event.SHOWN, {
47044            relatedTarget: previous
47045          });
47046
47047          $(previous).trigger(hiddenEvent);
47048          $(_this15._element).trigger(shownEvent);
47049        };
47050
47051        if (target) {
47052          this._activate(target, target.parentNode, complete);
47053        } else {
47054          complete();
47055        }
47056      }
47057    }, {
47058      key: 'dispose',
47059      value: function dispose() {
47060        $.removeClass(this._element, DATA_KEY);
47061        this._element = null;
47062      }
47063
47064      // private
47065
47066    }, {
47067      key: '_activate',
47068      value: function _activate(element, container, callback) {
47069        var active = $(container).find(Selector.ACTIVE_CHILD)[0];
47070        var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || Boolean($(container).find(Selector.FADE_CHILD)[0]));
47071
47072        var complete = $.proxy(this._transitionComplete, this, element, active, isTransitioning, callback);
47073
47074        if (active && isTransitioning) {
47075          $(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
47076        } else {
47077          complete();
47078        }
47079
47080        if (active) {
47081          $(active).removeClass(ClassName.IN);
47082        }
47083      }
47084    }, {
47085      key: '_transitionComplete',
47086      value: function _transitionComplete(element, active, isTransitioning, callback) {
47087        if (active) {
47088          $(active).removeClass(ClassName.ACTIVE);
47089
47090          var dropdownChild = $(active).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
47091
47092          if (dropdownChild) {
47093            $(dropdownChild).removeClass(ClassName.ACTIVE);
47094          }
47095
47096          active.setAttribute('aria-expanded', false);
47097        }
47098
47099        $(element).addClass(ClassName.ACTIVE);
47100        element.setAttribute('aria-expanded', true);
47101
47102        if (isTransitioning) {
47103          Util.reflow(element);
47104          $(element).addClass(ClassName.IN);
47105        } else {
47106          $(element).removeClass(ClassName.FADE);
47107        }
47108
47109        if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
47110
47111          var dropdownElement = $(element).closest(Selector.DROPDOWN)[0];
47112          if (dropdownElement) {
47113            $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
47114          }
47115
47116          element.setAttribute('aria-expanded', true);
47117        }
47118
47119        if (callback) {
47120          callback();
47121        }
47122      }
47123
47124      // static
47125
47126    }], [{
47127      key: '_jQueryInterface',
47128      value: function _jQueryInterface(config) {
47129        return this.each(function () {
47130          var $this = $(this);
47131          var data = $this.data(DATA_KEY);
47132
47133          if (!data) {
47134            data = data = new Tab(this);
47135            $this.data(DATA_KEY, data);
47136          }
47137
47138          if (typeof config === 'string') {
47139            if (data[config] === undefined) {
47140              throw new Error('No method named "' + config + '"');
47141            }
47142            data[config]();
47143          }
47144        });
47145      }
47146    }, {
47147      key: 'VERSION',
47148      get: function get() {
47149        return VERSION;
47150      }
47151    }]);
47152
47153    return Tab;
47154  })();
47155
47156  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
47157    event.preventDefault();
47158    Tab._jQueryInterface.call($(this), 'show');
47159  });
47160
47161  /**
47162   * ------------------------------------------------------------------------
47163   * jQuery
47164   * ------------------------------------------------------------------------
47165   */
47166
47167  $.fn[NAME] = Tab._jQueryInterface;
47168  $.fn[NAME].Constructor = Tab;
47169  $.fn[NAME].noConflict = function () {
47170    $.fn[NAME] = JQUERY_NO_CONFLICT;
47171    return Tab._jQueryInterface;
47172  };
47173
47174  return Tab;
47175})(jQuery);
47176
47177/* global Tether */
47178
47179/**
47180 * --------------------------------------------------------------------------
47181 * Bootstrap (v4.0.0-alpha.4): tooltip.js
47182 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
47183 * --------------------------------------------------------------------------
47184 */
47185
47186var Tooltip = (function ($) {
47187
47188  /**
47189   * Check for Tether dependency
47190   * Tether - http://github.hubspot.com/tether/
47191   */
47192  if (window.Tether === undefined) {
47193    throw new Error('Bootstrap tooltips require Tether (http://github.hubspot.com/tether/)');
47194  }
47195
47196  /**
47197   * ------------------------------------------------------------------------
47198   * Constants
47199   * ------------------------------------------------------------------------
47200   */
47201
47202  var NAME = 'tooltip';
47203  var VERSION = '4.0.0-alpha.4';
47204  var DATA_KEY = 'bs.tooltip';
47205  var EVENT_KEY = '.' + DATA_KEY;
47206  var JQUERY_NO_CONFLICT = $.fn[NAME];
47207  var TRANSITION_DURATION = 150;
47208  var CLASS_PREFIX = 'bs-tether';
47209
47210  var Default = {
47211    animation: true,
47212    template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div></div>',
47213    trigger: 'hover focus',
47214    title: '',
47215    delay: 0,
47216    html: false,
47217    selector: false,
47218    placement: 'top',
47219    offset: '0 0',
47220    constraints: []
47221  };
47222
47223  var DefaultType = {
47224    animation: 'boolean',
47225    template: 'string',
47226    title: '(string|element|function)',
47227    trigger: 'string',
47228    delay: '(number|object)',
47229    html: 'boolean',
47230    selector: '(string|boolean)',
47231    placement: '(string|function)',
47232    offset: 'string',
47233    constraints: 'array'
47234  };
47235
47236  var AttachmentMap = {
47237    TOP: 'bottom center',
47238    RIGHT: 'middle left',
47239    BOTTOM: 'top center',
47240    LEFT: 'middle right'
47241  };
47242
47243  var HoverState = {
47244    IN: 'in',
47245    OUT: 'out'
47246  };
47247
47248  var Event = {
47249    HIDE: 'hide' + EVENT_KEY,
47250    HIDDEN: 'hidden' + EVENT_KEY,
47251    SHOW: 'show' + EVENT_KEY,
47252    SHOWN: 'shown' + EVENT_KEY,
47253    INSERTED: 'inserted' + EVENT_KEY,
47254    CLICK: 'click' + EVENT_KEY,
47255    FOCUSIN: 'focusin' + EVENT_KEY,
47256    FOCUSOUT: 'focusout' + EVENT_KEY,
47257    MOUSEENTER: 'mouseenter' + EVENT_KEY,
47258    MOUSELEAVE: 'mouseleave' + EVENT_KEY
47259  };
47260
47261  var ClassName = {
47262    FADE: 'fade',
47263    IN: 'in'
47264  };
47265
47266  var Selector = {
47267    TOOLTIP: '.tooltip',
47268    TOOLTIP_INNER: '.tooltip-inner'
47269  };
47270
47271  var TetherClass = {
47272    element: false,
47273    enabled: false
47274  };
47275
47276  var Trigger = {
47277    HOVER: 'hover',
47278    FOCUS: 'focus',
47279    CLICK: 'click',
47280    MANUAL: 'manual'
47281  };
47282
47283  /**
47284   * ------------------------------------------------------------------------
47285   * Class Definition
47286   * ------------------------------------------------------------------------
47287   */
47288
47289  var Tooltip = (function () {
47290    function Tooltip(element, config) {
47291      _classCallCheck(this, Tooltip);
47292
47293      // private
47294      this._isEnabled = true;
47295      this._timeout = 0;
47296      this._hoverState = '';
47297      this._activeTrigger = {};
47298      this._tether = null;
47299
47300      // protected
47301      this.element = element;
47302      this.config = this._getConfig(config);
47303      this.tip = null;
47304
47305      this._setListeners();
47306    }
47307
47308    /**
47309     * ------------------------------------------------------------------------
47310     * jQuery
47311     * ------------------------------------------------------------------------
47312     */
47313
47314    // getters
47315
47316    _createClass(Tooltip, [{
47317      key: 'enable',
47318
47319      // public
47320
47321      value: function enable() {
47322        this._isEnabled = true;
47323      }
47324    }, {
47325      key: 'disable',
47326      value: function disable() {
47327        this._isEnabled = false;
47328      }
47329    }, {
47330      key: 'toggleEnabled',
47331      value: function toggleEnabled() {
47332        this._isEnabled = !this._isEnabled;
47333      }
47334    }, {
47335      key: 'toggle',
47336      value: function toggle(event) {
47337        if (event) {
47338          var dataKey = this.constructor.DATA_KEY;
47339          var context = $(event.currentTarget).data(dataKey);
47340
47341          if (!context) {
47342            context = new this.constructor(event.currentTarget, this._getDelegateConfig());
47343            $(event.currentTarget).data(dataKey, context);
47344          }
47345
47346          context._activeTrigger.click = !context._activeTrigger.click;
47347
47348          if (context._isWithActiveTrigger()) {
47349            context._enter(null, context);
47350          } else {
47351            context._leave(null, context);
47352          }
47353        } else {
47354
47355          if ($(this.getTipElement()).hasClass(ClassName.IN)) {
47356            this._leave(null, this);
47357            return;
47358          }
47359
47360          this._enter(null, this);
47361        }
47362      }
47363    }, {
47364      key: 'dispose',
47365      value: function dispose() {
47366        clearTimeout(this._timeout);
47367
47368        this.cleanupTether();
47369
47370        $.removeData(this.element, this.constructor.DATA_KEY);
47371
47372        $(this.element).off(this.constructor.EVENT_KEY);
47373
47374        if (this.tip) {
47375          $(this.tip).remove();
47376        }
47377
47378        this._isEnabled = null;
47379        this._timeout = null;
47380        this._hoverState = null;
47381        this._activeTrigger = null;
47382        this._tether = null;
47383
47384        this.element = null;
47385        this.config = null;
47386        this.tip = null;
47387      }
47388    }, {
47389      key: 'show',
47390      value: function show() {
47391        var _this16 = this;
47392
47393        var showEvent = $.Event(this.constructor.Event.SHOW);
47394
47395        if (this.isWithContent() && this._isEnabled) {
47396          $(this.element).trigger(showEvent);
47397
47398          var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
47399
47400          if (showEvent.isDefaultPrevented() || !isInTheDom) {
47401            return;
47402          }
47403
47404          var tip = this.getTipElement();
47405          var tipId = Util.getUID(this.constructor.NAME);
47406
47407          tip.setAttribute('id', tipId);
47408          this.element.setAttribute('aria-describedby', tipId);
47409
47410          this.setContent();
47411
47412          if (this.config.animation) {
47413            $(tip).addClass(ClassName.FADE);
47414          }
47415
47416          var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
47417
47418          var attachment = this._getAttachment(placement);
47419
47420          $(tip).data(this.constructor.DATA_KEY, this).appendTo(document.body);
47421
47422          $(this.element).trigger(this.constructor.Event.INSERTED);
47423
47424          this._tether = new Tether({
47425            attachment: attachment,
47426            element: tip,
47427            target: this.element,
47428            classes: TetherClass,
47429            classPrefix: CLASS_PREFIX,
47430            offset: this.config.offset,
47431            constraints: this.config.constraints,
47432            addTargetClasses: false
47433          });
47434
47435          Util.reflow(tip);
47436          this._tether.position();
47437
47438          $(tip).addClass(ClassName.IN);
47439
47440          var complete = function complete() {
47441            var prevHoverState = _this16._hoverState;
47442            _this16._hoverState = null;
47443
47444            $(_this16.element).trigger(_this16.constructor.Event.SHOWN);
47445
47446            if (prevHoverState === HoverState.OUT) {
47447              _this16._leave(null, _this16);
47448            }
47449          };
47450
47451          if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
47452            $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION);
47453            return;
47454          }
47455
47456          complete();
47457        }
47458      }
47459    }, {
47460      key: 'hide',
47461      value: function hide(callback) {
47462        var _this17 = this;
47463
47464        var tip = this.getTipElement();
47465        var hideEvent = $.Event(this.constructor.Event.HIDE);
47466        var complete = function complete() {
47467          if (_this17._hoverState !== HoverState.IN && tip.parentNode) {
47468            tip.parentNode.removeChild(tip);
47469          }
47470
47471          _this17.element.removeAttribute('aria-describedby');
47472          $(_this17.element).trigger(_this17.constructor.Event.HIDDEN);
47473          _this17.cleanupTether();
47474
47475          if (callback) {
47476            callback();
47477          }
47478        };
47479
47480        $(this.element).trigger(hideEvent);
47481
47482        if (hideEvent.isDefaultPrevented()) {
47483          return;
47484        }
47485
47486        $(tip).removeClass(ClassName.IN);
47487
47488        if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
47489
47490          $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
47491        } else {
47492          complete();
47493        }
47494
47495        this._hoverState = '';
47496      }
47497
47498      // protected
47499
47500    }, {
47501      key: 'isWithContent',
47502      value: function isWithContent() {
47503        return Boolean(this.getTitle());
47504      }
47505    }, {
47506      key: 'getTipElement',
47507      value: function getTipElement() {
47508        return this.tip = this.tip || $(this.config.template)[0];
47509      }
47510    }, {
47511      key: 'setContent',
47512      value: function setContent() {
47513        var $tip = $(this.getTipElement());
47514
47515        this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle());
47516
47517        $tip.removeClass(ClassName.FADE).removeClass(ClassName.IN);
47518
47519        this.cleanupTether();
47520      }
47521    }, {
47522      key: 'setElementContent',
47523      value: function setElementContent($element, content) {
47524        var html = this.config.html;
47525        if (typeof content === 'object' && (content.nodeType || content.jquery)) {
47526          // content is a DOM node or a jQuery
47527          if (html) {
47528            if (!$(content).parent().is($element)) {
47529              $element.empty().append(content);
47530            }
47531          } else {
47532            $element.text($(content).text());
47533          }
47534        } else {
47535          $element[html ? 'html' : 'text'](content);
47536        }
47537      }
47538    }, {
47539      key: 'getTitle',
47540      value: function getTitle() {
47541        var title = this.element.getAttribute('data-original-title');
47542
47543        if (!title) {
47544          title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
47545        }
47546
47547        return title;
47548      }
47549    }, {
47550      key: 'cleanupTether',
47551      value: function cleanupTether() {
47552        if (this._tether) {
47553          this._tether.destroy();
47554        }
47555      }
47556
47557      // private
47558
47559    }, {
47560      key: '_getAttachment',
47561      value: function _getAttachment(placement) {
47562        return AttachmentMap[placement.toUpperCase()];
47563      }
47564    }, {
47565      key: '_setListeners',
47566      value: function _setListeners() {
47567        var _this18 = this;
47568
47569        var triggers = this.config.trigger.split(' ');
47570
47571        triggers.forEach(function (trigger) {
47572          if (trigger === 'click') {
47573            $(_this18.element).on(_this18.constructor.Event.CLICK, _this18.config.selector, $.proxy(_this18.toggle, _this18));
47574          } else if (trigger !== Trigger.MANUAL) {
47575            var eventIn = trigger === Trigger.HOVER ? _this18.constructor.Event.MOUSEENTER : _this18.constructor.Event.FOCUSIN;
47576            var eventOut = trigger === Trigger.HOVER ? _this18.constructor.Event.MOUSELEAVE : _this18.constructor.Event.FOCUSOUT;
47577
47578            $(_this18.element).on(eventIn, _this18.config.selector, $.proxy(_this18._enter, _this18)).on(eventOut, _this18.config.selector, $.proxy(_this18._leave, _this18));
47579          }
47580        });
47581
47582        if (this.config.selector) {
47583          this.config = $.extend({}, this.config, {
47584            trigger: 'manual',
47585            selector: ''
47586          });
47587        } else {
47588          this._fixTitle();
47589        }
47590      }
47591    }, {
47592      key: '_fixTitle',
47593      value: function _fixTitle() {
47594        var titleType = typeof this.element.getAttribute('data-original-title');
47595        if (this.element.getAttribute('title') || titleType !== 'string') {
47596          this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
47597          this.element.setAttribute('title', '');
47598        }
47599      }
47600    }, {
47601      key: '_enter',
47602      value: function _enter(event, context) {
47603        var dataKey = this.constructor.DATA_KEY;
47604
47605        context = context || $(event.currentTarget).data(dataKey);
47606
47607        if (!context) {
47608          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
47609          $(event.currentTarget).data(dataKey, context);
47610        }
47611
47612        if (event) {
47613          context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;
47614        }
47615
47616        if ($(context.getTipElement()).hasClass(ClassName.IN) || context._hoverState === HoverState.IN) {
47617          context._hoverState = HoverState.IN;
47618          return;
47619        }
47620
47621        clearTimeout(context._timeout);
47622
47623        context._hoverState = HoverState.IN;
47624
47625        if (!context.config.delay || !context.config.delay.show) {
47626          context.show();
47627          return;
47628        }
47629
47630        context._timeout = setTimeout(function () {
47631          if (context._hoverState === HoverState.IN) {
47632            context.show();
47633          }
47634        }, context.config.delay.show);
47635      }
47636    }, {
47637      key: '_leave',
47638      value: function _leave(event, context) {
47639        var dataKey = this.constructor.DATA_KEY;
47640
47641        context = context || $(event.currentTarget).data(dataKey);
47642
47643        if (!context) {
47644          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
47645          $(event.currentTarget).data(dataKey, context);
47646        }
47647
47648        if (event) {
47649          context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
47650        }
47651
47652        if (context._isWithActiveTrigger()) {
47653          return;
47654        }
47655
47656        clearTimeout(context._timeout);
47657
47658        context._hoverState = HoverState.OUT;
47659
47660        if (!context.config.delay || !context.config.delay.hide) {
47661          context.hide();
47662          return;
47663        }
47664
47665        context._timeout = setTimeout(function () {
47666          if (context._hoverState === HoverState.OUT) {
47667            context.hide();
47668          }
47669        }, context.config.delay.hide);
47670      }
47671    }, {
47672      key: '_isWithActiveTrigger',
47673      value: function _isWithActiveTrigger() {
47674        for (var trigger in this._activeTrigger) {
47675          if (this._activeTrigger[trigger]) {
47676            return true;
47677          }
47678        }
47679
47680        return false;
47681      }
47682    }, {
47683      key: '_getConfig',
47684      value: function _getConfig(config) {
47685        config = $.extend({}, this.constructor.Default, $(this.element).data(), config);
47686
47687        if (config.delay && typeof config.delay === 'number') {
47688          config.delay = {
47689            show: config.delay,
47690            hide: config.delay
47691          };
47692        }
47693
47694        Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
47695
47696        return config;
47697      }
47698    }, {
47699      key: '_getDelegateConfig',
47700      value: function _getDelegateConfig() {
47701        var config = {};
47702
47703        if (this.config) {
47704          for (var key in this.config) {
47705            if (this.constructor.Default[key] !== this.config[key]) {
47706              config[key] = this.config[key];
47707            }
47708          }
47709        }
47710
47711        return config;
47712      }
47713
47714      // static
47715
47716    }], [{
47717      key: '_jQueryInterface',
47718      value: function _jQueryInterface(config) {
47719        return this.each(function () {
47720          var data = $(this).data(DATA_KEY);
47721          var _config = typeof config === 'object' ? config : null;
47722
47723          if (!data && /destroy|hide/.test(config)) {
47724            return;
47725          }
47726
47727          if (!data) {
47728            data = new Tooltip(this, _config);
47729            $(this).data(DATA_KEY, data);
47730          }
47731
47732          if (typeof config === 'string') {
47733            if (data[config] === undefined) {
47734              throw new Error('No method named "' + config + '"');
47735            }
47736            data[config]();
47737          }
47738        });
47739      }
47740    }, {
47741      key: 'VERSION',
47742      get: function get() {
47743        return VERSION;
47744      }
47745    }, {
47746      key: 'Default',
47747      get: function get() {
47748        return Default;
47749      }
47750    }, {
47751      key: 'NAME',
47752      get: function get() {
47753        return NAME;
47754      }
47755    }, {
47756      key: 'DATA_KEY',
47757      get: function get() {
47758        return DATA_KEY;
47759      }
47760    }, {
47761      key: 'Event',
47762      get: function get() {
47763        return Event;
47764      }
47765    }, {
47766      key: 'EVENT_KEY',
47767      get: function get() {
47768        return EVENT_KEY;
47769      }
47770    }, {
47771      key: 'DefaultType',
47772      get: function get() {
47773        return DefaultType;
47774      }
47775    }]);
47776
47777    return Tooltip;
47778  })();
47779
47780  $.fn[NAME] = Tooltip._jQueryInterface;
47781  $.fn[NAME].Constructor = Tooltip;
47782  $.fn[NAME].noConflict = function () {
47783    $.fn[NAME] = JQUERY_NO_CONFLICT;
47784    return Tooltip._jQueryInterface;
47785  };
47786
47787  return Tooltip;
47788})(jQuery);
47789
47790/**
47791 * --------------------------------------------------------------------------
47792 * Bootstrap (v4.0.0-alpha.4): popover.js
47793 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
47794 * --------------------------------------------------------------------------
47795 */
47796
47797var Popover = (function ($) {
47798
47799  /**
47800   * ------------------------------------------------------------------------
47801   * Constants
47802   * ------------------------------------------------------------------------
47803   */
47804
47805  var NAME = 'popover';
47806  var VERSION = '4.0.0-alpha.4';
47807  var DATA_KEY = 'bs.popover';
47808  var EVENT_KEY = '.' + DATA_KEY;
47809  var JQUERY_NO_CONFLICT = $.fn[NAME];
47810
47811  var Default = $.extend({}, Tooltip.Default, {
47812    placement: 'right',
47813    trigger: 'click',
47814    content: '',
47815    template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
47816  });
47817
47818  var DefaultType = $.extend({}, Tooltip.DefaultType, {
47819    content: '(string|element|function)'
47820  });
47821
47822  var ClassName = {
47823    FADE: 'fade',
47824    IN: 'in'
47825  };
47826
47827  var Selector = {
47828    TITLE: '.popover-title',
47829    CONTENT: '.popover-content',
47830    ARROW: '.popover-arrow'
47831  };
47832
47833  var Event = {
47834    HIDE: 'hide' + EVENT_KEY,
47835    HIDDEN: 'hidden' + EVENT_KEY,
47836    SHOW: 'show' + EVENT_KEY,
47837    SHOWN: 'shown' + EVENT_KEY,
47838    INSERTED: 'inserted' + EVENT_KEY,
47839    CLICK: 'click' + EVENT_KEY,
47840    FOCUSIN: 'focusin' + EVENT_KEY,
47841    FOCUSOUT: 'focusout' + EVENT_KEY,
47842    MOUSEENTER: 'mouseenter' + EVENT_KEY,
47843    MOUSELEAVE: 'mouseleave' + EVENT_KEY
47844  };
47845
47846  /**
47847   * ------------------------------------------------------------------------
47848   * Class Definition
47849   * ------------------------------------------------------------------------
47850   */
47851
47852  var Popover = (function (_Tooltip) {
47853    _inherits(Popover, _Tooltip);
47854
47855    function Popover() {
47856      _classCallCheck(this, Popover);
47857
47858      _get(Object.getPrototypeOf(Popover.prototype), 'constructor', this).apply(this, arguments);
47859    }
47860
47861    /**
47862     * ------------------------------------------------------------------------
47863     * jQuery
47864     * ------------------------------------------------------------------------
47865     */
47866
47867    _createClass(Popover, [{
47868      key: 'isWithContent',
47869
47870      // overrides
47871
47872      value: function isWithContent() {
47873        return this.getTitle() || this._getContent();
47874      }
47875    }, {
47876      key: 'getTipElement',
47877      value: function getTipElement() {
47878        return this.tip = this.tip || $(this.config.template)[0];
47879      }
47880    }, {
47881      key: 'setContent',
47882      value: function setContent() {
47883        var $tip = $(this.getTipElement());
47884
47885        // we use append for html objects to maintain js events
47886        this.setElementContent($tip.find(Selector.TITLE), this.getTitle());
47887        this.setElementContent($tip.find(Selector.CONTENT), this._getContent());
47888
47889        $tip.removeClass(ClassName.FADE).removeClass(ClassName.IN);
47890
47891        this.cleanupTether();
47892      }
47893
47894      // private
47895
47896    }, {
47897      key: '_getContent',
47898      value: function _getContent() {
47899        return this.element.getAttribute('data-content') || (typeof this.config.content === 'function' ? this.config.content.call(this.element) : this.config.content);
47900      }
47901
47902      // static
47903
47904    }], [{
47905      key: '_jQueryInterface',
47906      value: function _jQueryInterface(config) {
47907        return this.each(function () {
47908          var data = $(this).data(DATA_KEY);
47909          var _config = typeof config === 'object' ? config : null;
47910
47911          if (!data && /destroy|hide/.test(config)) {
47912            return;
47913          }
47914
47915          if (!data) {
47916            data = new Popover(this, _config);
47917            $(this).data(DATA_KEY, data);
47918          }
47919
47920          if (typeof config === 'string') {
47921            if (data[config] === undefined) {
47922              throw new Error('No method named "' + config + '"');
47923            }
47924            data[config]();
47925          }
47926        });
47927      }
47928    }, {
47929      key: 'VERSION',
47930
47931      // getters
47932
47933      get: function get() {
47934        return VERSION;
47935      }
47936    }, {
47937      key: 'Default',
47938      get: function get() {
47939        return Default;
47940      }
47941    }, {
47942      key: 'NAME',
47943      get: function get() {
47944        return NAME;
47945      }
47946    }, {
47947      key: 'DATA_KEY',
47948      get: function get() {
47949        return DATA_KEY;
47950      }
47951    }, {
47952      key: 'Event',
47953      get: function get() {
47954        return Event;
47955      }
47956    }, {
47957      key: 'EVENT_KEY',
47958      get: function get() {
47959        return EVENT_KEY;
47960      }
47961    }, {
47962      key: 'DefaultType',
47963      get: function get() {
47964        return DefaultType;
47965      }
47966    }]);
47967
47968    return Popover;
47969  })(Tooltip);
47970
47971  $.fn[NAME] = Popover._jQueryInterface;
47972  $.fn[NAME].Constructor = Popover;
47973  $.fn[NAME].noConflict = function () {
47974    $.fn[NAME] = JQUERY_NO_CONFLICT;
47975    return Popover._jQueryInterface;
47976  };
47977
47978  return Popover;
47979})(jQuery);
47980
47981}(jQuery);
47982// require self
47983
47984;
47985Selectize.define('selectable_placeholder', function (options) {
47986    var self = this;
47987
47988    options = $.extend({
47989        placeholder: self.settings.placeholder,
47990        html: function (data) {
47991            return (
47992                '<div class="selectize-dropdown-content placeholder-container">' +
47993                '<div data-selectable class="option">' + data.placeholder + '</div>' +
47994                '</div>');
47995        }
47996    }, options);
47997
47998    // override the setup method to add an extra "click" handler
47999    self.setup = (function () {
48000        var original = self.setup;
48001        return function () {
48002            original.apply(this, arguments);
48003            self.$placeholder_container = $(options.html(options));
48004            self.$dropdown.prepend(self.$placeholder_container);
48005            self.$dropdown.find('.placeholder-container').on('mousedown',  function () {
48006                //self.setValue('');
48007                self.clear();
48008                self.close();
48009                self.blur();
48010                return false;
48011            });
48012        };
48013    })();
48014
48015});
48016
48017$('#test').selectize({
48018    create: false,
48019    dropdownParent: 'body',
48020    plugins: {
48021        'selectable_placeholder': {}
48022    }
48023});
48024/*
48025     _ _      _       _
48026 ___| (_) ___| | __  (_)___
48027/ __| | |/ __| |/ /  | / __|
48028\__ \ | | (__|   < _ | \__ \
48029|___/_|_|\___|_|\_(_)/ |___/
48030                   |__/
48031
48032 Version: 1.3.15
48033  Author: Ken Wheeler
48034 Website: http://kenwheeler.github.io
48035    Docs: http://kenwheeler.github.io/slick
48036    Repo: http://github.com/kenwheeler/slick
48037  Issues: http://github.com/kenwheeler/slick/issues
48038
48039 */
48040
48041/* global window, document, define, jQuery, setInterval, clearInterval */
48042
48043(function(factory) {
48044    'use strict';
48045    if (typeof define === 'function' && define.amd) {
48046        define(['jquery'], factory);
48047    } else if (typeof exports !== 'undefined') {
48048        module.exports = factory(require('jquery'));
48049    } else {
48050        factory(jQuery);
48051    }
48052
48053}(function($) {
48054    'use strict';
48055    var Slick = window.Slick || {};
48056
48057    Slick = (function() {
48058
48059        var instanceUid = 0;
48060
48061        function Slick(element, settings) {
48062
48063            var _ = this,
48064                responsiveSettings, breakpoint;
48065
48066            _.defaults = {
48067                accessibility: true,
48068                adaptiveHeight: false,
48069                appendArrows: $(element),
48070                appendDots: $(element),
48071                arrows: true,
48072                asNavFor: null,
48073                prevArrow: '<button type="button" data-role="none" class="slick-prev">Previous</button>',
48074                nextArrow: '<button type="button" data-role="none" class="slick-next">Next</button>',
48075                autoplay: false,
48076                autoplaySpeed: 3000,
48077                centerMode: false,
48078                centerPadding: '50px',
48079                cssEase: 'ease',
48080                customPaging: function(slider, i) {
48081                    return '<button type="button" data-role="none">' + (i + 1) + '</button>';
48082                },
48083                dots: false,
48084                dotsClass: 'slick-dots',
48085                draggable: true,
48086                easing: 'linear',
48087                fade: false,
48088                focusOnSelect: false,
48089                infinite: true,
48090                initialSlide: 0,
48091                lazyLoad: 'ondemand',
48092                onBeforeChange: null,
48093                onAfterChange: null,
48094                onInit: null,
48095                onReInit: null,
48096                onSetPosition: null,
48097                pauseOnHover: true,
48098                pauseOnDotsHover: false,
48099                respondTo: 'window',
48100                responsive: null,
48101                rtl: false,
48102                slide: 'div',
48103                slidesToShow: 1,
48104                slidesToScroll: 1,
48105                speed: 500,
48106                swipe: true,
48107                swipeToSlide: false,
48108                touchMove: true,
48109                touchThreshold: 5,
48110                useCSS: true,
48111                variableWidth: false,
48112                vertical: false,
48113                waitForAnimate: true
48114            };
48115
48116            _.initials = {
48117                animating: false,
48118                dragging: false,
48119                autoPlayTimer: null,
48120                currentDirection: 0,
48121                currentLeft: null,
48122                currentSlide: 0,
48123                direction: 1,
48124                $dots: null,
48125                listWidth: null,
48126                listHeight: null,
48127                loadIndex: 0,
48128                $nextArrow: null,
48129                $prevArrow: null,
48130                slideCount: null,
48131                slideWidth: null,
48132                $slideTrack: null,
48133                $slides: null,
48134                sliding: false,
48135                slideOffset: 0,
48136                swipeLeft: null,
48137                $list: null,
48138                touchObject: {},
48139                transformsEnabled: false
48140            };
48141
48142            $.extend(_, _.initials);
48143
48144            _.activeBreakpoint = null;
48145            _.animType = null;
48146            _.animProp = null;
48147            _.breakpoints = [];
48148            _.breakpointSettings = [];
48149            _.cssTransitions = false;
48150            _.paused = false;
vendor: 7,060 bytes, lines 48151-48368
48151            _.positionProp = null;
48152            _.respondTo = null;
48153            _.shouldClick = true;
48154            _.$slider = $(element);
48155            _.$slidesCache = null;
48156            _.transformType = null;
48157            _.transitionType = null;
48158            _.windowWidth = 0;
48159            _.windowTimer = null;
48160
48161            _.options = $.extend({}, _.defaults, settings);
48162
48163            _.currentSlide = _.options.initialSlide;
48164
48165            _.originalSettings = _.options;
48166            responsiveSettings = _.options.responsive || null;
48167
48168            if (responsiveSettings && responsiveSettings.length > -1) {
48169                _.respondTo = _.options.respondTo || "window";
48170                for (breakpoint in responsiveSettings) {
48171                    if (responsiveSettings.hasOwnProperty(breakpoint)) {
48172                        _.breakpoints.push(responsiveSettings[
48173                            breakpoint].breakpoint);
48174                        _.breakpointSettings[responsiveSettings[
48175                            breakpoint].breakpoint] =
48176                            responsiveSettings[breakpoint].settings;
48177                    }
48178                }
48179                _.breakpoints.sort(function(a, b) {
48180                    return b - a;
48181                });
48182            }
48183
48184            _.autoPlay = $.proxy(_.autoPlay, _);
48185            _.autoPlayClear = $.proxy(_.autoPlayClear, _);
48186            _.changeSlide = $.proxy(_.changeSlide, _);
48187            _.clickHandler = $.proxy(_.clickHandler, _);
48188            _.selectHandler = $.proxy(_.selectHandler, _);
48189            _.setPosition = $.proxy(_.setPosition, _);
48190            _.swipeHandler = $.proxy(_.swipeHandler, _);
48191            _.dragHandler = $.proxy(_.dragHandler, _);
48192            _.keyHandler = $.proxy(_.keyHandler, _);
48193            _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
48194
48195            _.instanceUid = instanceUid++;
48196
48197            // A simple way to check for HTML strings
48198            // Strict HTML recognition (must start with <)
48199            // Extracted from jQuery v1.11 source
48200            _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
48201
48202            _.init();
48203
48204            _.checkResponsive();
48205
48206        }
48207
48208        return Slick;
48209
48210    }());
48211
48212    Slick.prototype.addSlide = function(markup, index, addBefore) {
48213
48214        var _ = this;
48215
48216        if (typeof(index) === 'boolean') {
48217            addBefore = index;
48218            index = null;
48219        } else if (index < 0 || (index >= _.slideCount)) {
48220            return false;
48221        }
48222
48223        _.unload();
48224
48225        if (typeof(index) === 'number') {
48226            if (index === 0 && _.$slides.length === 0) {
48227                $(markup).appendTo(_.$slideTrack);
48228            } else if (addBefore) {
48229                $(markup).insertBefore(_.$slides.eq(index));
48230            } else {
48231                $(markup).insertAfter(_.$slides.eq(index));
48232            }
48233        } else {
48234            if (addBefore === true) {
48235                $(markup).prependTo(_.$slideTrack);
48236            } else {
48237                $(markup).appendTo(_.$slideTrack);
48238            }
48239        }
48240
48241        _.$slides = _.$slideTrack.children(this.options.slide);
48242
48243        _.$slideTrack.children(this.options.slide).detach();
48244
48245        _.$slideTrack.append(_.$slides);
48246
48247        _.$slides.each(function(index, element) {
48248            $(element).attr("index",index);
48249        });
48250
48251        _.$slidesCache = _.$slides;
48252
48253        _.reinit();
48254
48255    };
48256
48257    Slick.prototype.animateSlide = function(targetLeft, callback) {
48258
48259        var animProps = {}, _ = this;
48260
48261        if(_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
48262            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
48263            _.$list.animate({height: targetHeight},_.options.speed);
48264        }
48265
48266        if (_.options.rtl === true && _.options.vertical === false) {
48267            targetLeft = -targetLeft;
48268        }
48269        if (_.transformsEnabled === false) {
48270            if (_.options.vertical === false) {
48271                _.$slideTrack.animate({
48272                    left: targetLeft
48273                }, _.options.speed, _.options.easing, callback);
48274            } else {
48275                _.$slideTrack.animate({
48276                    top: targetLeft
48277                }, _.options.speed, _.options.easing, callback);
48278            }
48279
48280        } else {
48281
48282            if (_.cssTransitions === false) {
48283
48284                $({
48285                    animStart: _.currentLeft
48286                }).animate({
48287                    animStart: targetLeft
48288                }, {
48289                    duration: _.options.speed,
48290                    easing: _.options.easing,
48291                    step: function(now) {
48292                        if (_.options.vertical === false) {
48293                            animProps[_.animType] = 'translate(' +
48294                                now + 'px, 0px)';
48295                            _.$slideTrack.css(animProps);
48296                        } else {
48297                            animProps[_.animType] = 'translate(0px,' +
48298                                now + 'px)';
48299                            _.$slideTrack.css(animProps);
48300                        }
48301                    },
48302                    complete: function() {
48303                        if (callback) {
48304                            callback.call();
48305                        }
48306                    }
48307                });
48308
48309            } else {
48310
48311                _.applyTransition();
48312
48313                if (_.options.vertical === false) {
48314                    animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
48315                } else {
48316                    animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
48317                }
48318                _.$slideTrack.css(animProps);
48319
48320                if (callback) {
48321                    setTimeout(function() {
48322
48323                        _.disableTransition();
48324
48325                        callback.call();
48326                    }, _.options.speed);
48327                }
48328
48329            }
48330
48331        }
48332
48333    };
48334
48335    Slick.prototype.asNavFor = function(index) {
48336        var _ = this, asNavFor = _.options.asNavFor != null ? $(_.options.asNavFor).getSlick() : null;
48337        if(asNavFor != null) asNavFor.slideHandler(index, true);
48338    };
48339
48340    Slick.prototype.applyTransition = function(slide) {
48341
48342        var _ = this,
48343            transition = {};
48344
48345        if (_.options.fade === false) {
48346            transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
48347        } else {
48348            transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
48349        }
48350
48351        if (_.options.fade === false) {
48352            _.$slideTrack.css(transition);
48353        } else {
48354            _.$slides.eq(slide).css(transition);
48355        }
48356
48357    };
48358
48359    Slick.prototype.autoPlay = function() {
48360
48361        var _ = this;
48362
48363        if (_.autoPlayTimer) {
48364            clearInterval(_.autoPlayTimer);
48365        }
48366
48367        if (_.slideCount > _.options.slidesToShow && _.paused !== true) {
48368            _.autoPlayTimer = setInterval(_.autoPlayIterator,
48369                _.options.autoplaySpeed);
48370        }
48371
48372    };
48373
48374    Slick.prototype.autoPlayClear = function() {
48375
48376        var _ = this;
48377        if (_.autoPlayTimer) {
48378            clearInterval(_.autoPlayTimer);
48379        }
48380
48381    };
48382
48383    Slick.prototype.autoPlayIterator = function() {
48384
48385        var _ = this;
48386
48387        if (_.options.infinite === false) {
48388
48389            if (_.direction === 1) {
48390
48391                if ((_.currentSlide + 1) === _.slideCount -
48392                    1) {
48393                    _.direction = 0;
48394                }
48395
48396                _.slideHandler(_.currentSlide + _.options.slidesToScroll);
48397
48398            } else {
48399
48400                if ((_.currentSlide - 1 === 0)) {
48401
48402                    _.direction = 1;
48403
48404                }
48405
48406                _.slideHandler(_.currentSlide - _.options.slidesToScroll);
48407
48408            }
48409
48410        } else {
48411
48412            _.slideHandler(_.currentSlide + _.options.slidesToScroll);
48413
48414        }
48415
48416    };
48417
48418    Slick.prototype.buildArrows = function() {
48419
48420        var _ = this;
48421
48422        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
48423
48424            _.$prevArrow = $(_.options.prevArrow);
48425            _.$nextArrow = $(_.options.nextArrow);
48426
48427            if (_.htmlExpr.test(_.options.prevArrow)) {
48428                _.$prevArrow.appendTo(_.options.appendArrows);
48429            }
48430
48431            if (_.htmlExpr.test(_.options.nextArrow)) {
48432                _.$nextArrow.appendTo(_.options.appendArrows);
48433            }
48434
48435            if (_.options.infinite !== true) {
48436                _.$prevArrow.addClass('slick-disabled');
48437            }
48438
48439        }
48440
48441    };
48442
48443    Slick.prototype.buildDots = function() {
48444
48445        var _ = this,
48446            i, dotString;
48447
48448        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
48449
48450            dotString = '<ul class="' + _.options.dotsClass + '">';
48451
48452            for (i = 0; i <= _.getDotCount(); i += 1) {
48453                dotString += '<li>' + _.options.customPaging.call(this, _, i) + '</li>';
48454            }
48455
48456            dotString += '</ul>';
48457
48458            _.$dots = $(dotString).appendTo(
48459                _.options.appendDots);
48460
48461            _.$dots.find('li').first().addClass(
48462                'slick-active');
48463
48464        }
48465
48466    };
48467
48468    Slick.prototype.buildOut = function() {
48469
48470        var _ = this;
48471
48472        _.$slides = _.$slider.children(_.options.slide +
48473            ':not(.slick-cloned)').addClass(
48474            'slick-slide');
48475        _.slideCount = _.$slides.length;
48476
48477        _.$slides.each(function(index, element) {
48478            $(element).attr("index",index);
48479        });
48480
48481        _.$slidesCache = _.$slides;
48482
48483        _.$slider.addClass('slick-slider');
48484
48485        _.$slideTrack = (_.slideCount === 0) ?
48486            $('<div class="slick-track"/>').appendTo(_.$slider) :
48487            _.$slides.wrapAll('<div class="slick-track"/>').parent();
48488
48489        _.$list = _.$slideTrack.wrap(
48490            '<div class="slick-list"/>').parent();
48491        _.$slideTrack.css('opacity', 0);
48492
48493        if (_.options.centerMode === true) {
48494            _.options.slidesToScroll = 1;
48495        }
48496
48497        $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
48498
48499        _.setupInfinite();
48500
48501        _.buildArrows();
48502
48503        _.buildDots();
48504
48505        _.updateDots();
48506
48507        if (_.options.accessibility === true) {
48508            _.$list.prop('tabIndex', 0);
48509        }
48510
48511        _.setSlideClasses(typeof this.currentSlide === 'number' ? this.currentSlide : 0);
48512
48513        if (_.options.draggable === true) {
48514            _.$list.addClass('draggable');
48515        }
48516
48517    };
48518
48519    Slick.prototype.checkResponsive = function() {
48520
48521        var _ = this,
48522            breakpoint, targetBreakpoint, respondToWidth;
48523        var sliderWidth = _.$slider.width();
48524        var windowWidth = window.innerWidth || $(window).width();
48525        if (_.respondTo === "window") {
48526          respondToWidth = windowWidth;
48527        } else if (_.respondTo === "slider") {
48528          respondToWidth = sliderWidth;
48529        } else if (_.respondTo === "min") {
48530          respondToWidth = Math.min(windowWidth, sliderWidth);
48531        }
48532
48533        if (_.originalSettings.responsive && _.originalSettings
48534            .responsive.length > -1 && _.originalSettings.responsive !== null) {
48535
48536            targetBreakpoint = null;
48537
48538            for (breakpoint in _.breakpoints) {
48539                if (_.breakpoints.hasOwnProperty(breakpoint)) {
48540                    if (respondToWidth < _.breakpoints[breakpoint]) {
48541                        targetBreakpoint = _.breakpoints[breakpoint];
48542                    }
48543                }
48544            }
48545
48546            if (targetBreakpoint !== null) {
48547                if (_.activeBreakpoint !== null) {
48548                    if (targetBreakpoint !== _.activeBreakpoint) {
48549                        _.activeBreakpoint =
48550                            targetBreakpoint;
48551                        _.options = $.extend({}, _.originalSettings,
48552                            _.breakpointSettings[
48553                                targetBreakpoint]);
48554                        _.refresh();
48555                    }
48556                } else {
48557                    _.activeBreakpoint = targetBreakpoint;
48558                    _.options = $.extend({}, _.originalSettings,
48559                        _.breakpointSettings[
48560                            targetBreakpoint]);
48561                    _.refresh();
48562                }
48563            } else {
48564                if (_.activeBreakpoint !== null) {
48565                    _.activeBreakpoint = null;
48566                    _.options = _.originalSettings;
48567                    _.refresh();
48568                }
48569            }
48570
48571        }
48572
48573    };
48574
48575    Slick.prototype.changeSlide = function(event, dontAnimate) {
48576
48577        var _ = this,
48578            $target = $(event.target),
48579            indexOffset, slideOffset, unevenOffset,navigables, prevNavigable;
48580
48581        // If target is a link, prevent default action.
48582        $target.is('a') && event.preventDefault();
48583
48584        unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
48585        indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
48586
48587        switch (event.data.message) {
48588
48589            case 'previous':
48590                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
48591                if (_.slideCount > _.options.slidesToShow) {
48592                    _.slideHandler(_.currentSlide  - slideOffset, false, dontAnimate);
48593                }
48594                break;
48595
48596            case 'next':
48597                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
48598                if (_.slideCount > _.options.slidesToShow) {
48599                    _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
48600                }
48601                break;
48602
48603            case 'index':
48604                var index = event.data.index === 0 ? 0 :
48605                    event.data.index || $(event.target).parent().index() * _.options.slidesToScroll;
48606
48607                navigables = _.getNavigableIndexes();
48608                prevNavigable = 0;
48609                if(navigables[index] && navigables[index] === index) {
48610                    if(index > navigables[navigables.length -1]){
48611                        index = navigables[navigables.length -1];
48612                    } else {
48613                        for(var n in navigables) {
48614                            if(index < navigables[n]) {
48615                                index = prevNavigable;
48616                                break;
48617                            }
48618                            prevNavigable = navigables[n];
48619                        }
48620                    }
48621                }
48622                _.slideHandler(index, false, dontAnimate);
48623
48624            default:
48625                return;
48626        }
48627
48628    };
48629
48630    Slick.prototype.clickHandler = function(event) {
48631
48632        var _ = this;
48633
48634        if(_.shouldClick === false) {
48635            event.stopImmediatePropagation();
48636            event.stopPropagation();
48637            event.preventDefault();
48638        }
48639
48640    }
48641
48642    Slick.prototype.destroy = function() {
48643
48644        var _ = this;
48645
48646        _.autoPlayClear();
48647
48648        _.touchObject = {};
48649
48650        $('.slick-cloned', _.$slider).remove();
48651        if (_.$dots) {
48652            _.$dots.remove();
48653        }
48654        if (_.$prevArrow && (typeof _.options.prevArrow !== 'object')) {
48655            _.$prevArrow.remove();
48656        }
48657        if (_.$nextArrow && (typeof _.options.nextArrow !== 'object')) {
48658            _.$nextArrow.remove();
48659        }
48660        if (_.$slides.parent().hasClass('slick-track')) {
48661            _.$slides.unwrap().unwrap();
48662        }
48663
48664        _.$slides.removeClass(
48665            'slick-slide slick-active slick-center slick-visible')
48666            .removeAttr('index')
48667            .css({
48668                position: '',
48669                left: '',
48670                top: '',
48671                zIndex: '',
48672                opacity: '',
48673                width: ''
48674            });
48675
48676        _.$slider.removeClass('slick-slider');
48677        _.$slider.removeClass('slick-initialized');
48678
48679        _.$list.off('.slick');
48680        $(window).off('.slick-' + _.instanceUid);
48681        $(document).off('.slick-' + _.instanceUid);
48682
48683    };
48684
48685    Slick.prototype.disableTransition = function(slide) {
48686
48687        var _ = this,
48688            transition = {};
48689
48690        transition[_.transitionType] = "";
48691
48692        if (_.options.fade === false) {
48693            _.$slideTrack.css(transition);
48694        } else {
48695            _.$slides.eq(slide).css(transition);
48696        }
48697
48698    };
48699
48700    Slick.prototype.fadeSlide = function(oldSlide, slideIndex, callback) {
48701
48702        var _ = this;
48703
48704        if (_.cssTransitions === false) {
48705
48706            _.$slides.eq(slideIndex).css({
48707                zIndex: 1000
48708            });
48709
48710            _.$slides.eq(slideIndex).animate({
48711                opacity: 1
48712            }, _.options.speed, _.options.easing, callback);
48713
48714            _.$slides.eq(oldSlide).animate({
48715                opacity: 0
48716            }, _.options.speed, _.options.easing);
48717
48718        } else {
48719
48720            _.applyTransition(slideIndex);
48721            _.applyTransition(oldSlide);
48722
48723            _.$slides.eq(slideIndex).css({
48724                opacity: 1,
48725                zIndex: 1000
48726            });
48727
48728            _.$slides.eq(oldSlide).css({
48729                opacity: 0
48730            });
48731
48732            if (callback) {
48733                setTimeout(function() {
48734
48735                    _.disableTransition(slideIndex);
48736                    _.disableTransition(oldSlide);
48737
48738                    callback.call();
48739                }, _.options.speed);
48740            }
48741
48742        }
48743
48744    };
48745
48746    Slick.prototype.filterSlides = function(filter) {
48747
48748        var _ = this;
48749
48750        if (filter !== null) {
48751
48752            _.unload();
48753
48754            _.$slideTrack.children(this.options.slide).detach();
48755
48756            _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
48757
48758            _.reinit();
48759
48760        }
48761
48762    };
48763
48764    Slick.prototype.getCurrent = function() {
48765
48766        var _ = this;
48767
48768        return _.currentSlide;
48769
48770    };
48771
48772    Slick.prototype.getDotCount = function() {
48773
48774        var _ = this;
48775
48776        var breakPoint = 0;
48777        var counter = 0;
48778        var pagerQty = 0;
48779
48780        if(_.options.infinite === true) {
48781            pagerQty = Math.ceil(_.slideCount / _.options.slidesToScroll);
48782        } else {
48783            while (breakPoint < _.slideCount){
48784                ++pagerQty;
48785                breakPoint = counter + _.options.slidesToShow;
48786                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll  : _.options.slidesToShow;
48787            }
48788        }
48789
48790        return pagerQty - 1;
48791
48792    };
48793
48794    Slick.prototype.getLeft = function(slideIndex) {
48795
48796        var _ = this,
48797            targetLeft,
48798            verticalHeight,
48799            verticalOffset = 0,
48800            slideWidth,
48801            targetSlide;
48802
48803        _.slideOffset = 0;
48804        verticalHeight = _.$slides.first().outerHeight();
48805
48806        if (_.options.infinite === true) {
48807            if (_.slideCount > _.options.slidesToShow) {
48808                _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
48809                verticalOffset = (verticalHeight * _.options.slidesToShow) * -1;
48810            }
48811            if (_.slideCount % _.options.slidesToScroll !== 0) {
48812                if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
48813                    if(slideIndex > _.slideCount) {
48814                        _.slideOffset = ((_.options.slidesToShow - (sl
vendor: 1,543 bytes, lines 48814-48848
48814ideIndex - _.slideCount)) * _.slideWidth) * -1;
48815                        verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
48816                    } else {
48817                        _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
48818                        verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
48819                    }
48820                }
48821            }
48822        } else {
48823            if(slideIndex + _.options.slidesToShow > _.slideCount) {
48824                _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
48825                verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
48826            }
48827        }
48828
48829        if (_.slideCount <= _.options.slidesToShow){
48830            _.slideOffset = 0;
48831            verticalOffset = 0;
48832        }
48833
48834        if (_.options.centerMode === true && _.options.infinite === true) {
48835            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
48836        } else if (_.options.centerMode === true) {
48837            _.slideOffset = 0;
48838            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
48839        }
48840
48841        if (_.options.vertical === false) {
48842            targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
48843        } else {
48844            targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
48845        }
48846
48847        if (_.options.variableWidth === true) {
48848
48849            if(_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
48850                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
48851            } else {
48852                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
48853            }
48854            targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
48855            if (_.options.centerMode === true) {
48856                if(_.options.infinite === false) {
48857                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
48858                } else {
48859                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
48860                }
48861                targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
48862                targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
48863            }
48864        }
48865
48866         // 1680
48867
48868        return targetLeft;
48869
48870    };
48871
48872    Slick.prototype.getNavigableIndexes = function() {
48873
48874        var _ = this;
48875
48876        var breakPoint = 0;
48877        var counter = 0;
48878        var indexes = [];
48879
48880        while (breakPoint < _.slideCount){
48881            indexes.push(breakPoint);
48882            breakPoint = counter + _.options.slidesToScroll;
48883            counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll  : _.options.slidesToShow;
48884        }
48885
48886        return indexes;
48887
48888    };
48889
48890    Slick.prototype.getSlideCount = function() {
48891
48892        var _ = this, slidesTraversed;
48893
48894        if(_.options.swipeToSlide === true) {
48895            var swipedSlide = null;
48896            _.$slideTrack.find('.slick-slide').each(function(index, slide){
48897                if (slide.offsetLeft + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
48898                    swipedSlide = slide;
48899                    return false;
48900                }
48901            });
48902            slidesTraversed = Math.abs($(swipedSlide).attr('index') - _.currentSlide);
48903            return slidesTraversed;
48904        } else {
48905            return _.options.slidesToScroll;
48906        }
48907
48908    };
48909
48910    Slick.prototype.init = function() {
48911
48912        var _ = this;
48913
48914        if (!$(_.$slider).hasClass('slick-initialized')) {
48915
48916            $(_.$slider).addClass('slick-initialized');
48917            _.buildOut();
48918            _.setProps();
48919            _.startLoad();
48920            _.loadSlider();
48921            _.initializeEvents();
48922            _.updateArrows();
48923            _.updateDots();
48924        }
48925
48926        if (_.options.onInit !== null) {
48927            _.options.onInit.call(this, _);
48928        }
48929
48930    };
48931
48932    Slick.prototype.initArrowEvents = function() {
48933
48934        var _ = this;
48935
48936        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
48937            _.$prevArrow.on('click.slick', {
48938                message: 'previous'
48939            }, _.changeSlide);
48940            _.$nextArrow.on('click.slick', {
48941                message: 'next'
48942            }, _.changeSlide);
48943        }
48944
48945    };
48946
48947    Slick.prototype.initDotEvents = function() {
48948
48949        var _ = this;
48950
48951        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
48952            $('li', _.$dots).on('click.slick', {
48953                message: 'index'
48954            }, _.changeSlide);
48955        }
48956
48957        if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.options.autoplay === true) {
48958            $('li', _.$dots)
48959                .on('mouseenter.slick', function(){
48960                    _.paused = true;
48961                    _.autoPlayClear();
48962                })
48963                .on('mouseleave.slick', function(){
48964                    _.paused = false;
48965                    _.autoPlay();
48966                });
48967        }
48968
48969    };
48970
48971    Slick.prototype.initializeEvents = function() {
48972
48973        var _ = this;
48974
48975        _.initArrowEvents();
48976
48977        _.initDotEvents();
48978
48979        _.$list.on('touchstart.slick mousedown.slick', {
48980            action: 'start'
48981        }, _.swipeHandler);
48982        _.$list.on('touchmove.slick mousemove.slick', {
48983            action: 'move'
48984        }, _.swipeHandler);
48985        _.$list.on('touchend.slick mouseup.slick', {
48986            action: 'end'
48987        }, _.swipeHandler);
48988        _.$list.on('touchcancel.slick mouseleave.slick', {
48989            action: 'end'
48990        }, _.swipeHandler);
48991
48992        _.$list.on('click.slick', _.clickHandler);
48993
48994        if (_.options.pauseOnHover === true && _.options.autoplay === true) {
48995            _.$list.on('mouseenter.slick', function(){
48996                _.paused = true;
48997                _.autoPlayClear();
48998            });
48999            _.$list.on('mouseleave.slick', function(){
49000                _.paused = false;
49001                _.autoPlay();
49002            });
49003        }
49004
49005        if(_.options.accessibility === true) {
49006            _.$list.on('keydown.slick', _.keyHandler);
49007        }
49008
49009        if(_.options.focusOnSelect === true) {
49010            $(_.options.slide, _.$slideTrack).on('click.slick', _.selectHandler);
49011        }
49012
49013        $(window).on('orientationchange.slick.slick-' + _.instanceUid, function() {
49014            _.checkResponsive();
49015            _.setPosition();
49016        });
49017
49018        $(window).on('resize.slick.slick-' + _.instanceUid, function() {
49019            if ($(window).width() !== _.windowWidth) {
49020                clearTimeout(_.windowDelay);
49021                _.windowDelay = window.setTimeout(function() {
49022                    _.windowWidth = $(window).width();
49023                    _.checkResponsive();
49024                    _.setPosition();
49025                }, 50);
49026            }
49027        });
49028
49029        $('*[draggable!=true]', _.$slideTrack).on('dragstart', function(e){ e.preventDefault(); })
49030
49031        $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
49032        $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
49033
49034    };
49035
49036    Slick.prototype.initUI = function() {
49037
49038        var _ = this;
49039
49040        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
49041
49042            _.$prevArrow.show();
49043            _.$nextArrow.show();
49044
49045        }
49046
49047        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
49048
49049            _.$dots.show();
49050
49051        }
49052
49053        if (_.options.autoplay === true) {
49054
49055            _.autoPlay();
49056
49057        }
49058
49059    };
49060
49061    Slick.prototype.keyHandler = function(event) {
49062
49063        var _ = this;
49064
49065        if (event.keyCode === 37 && _.options.accessibility === true) {
49066            _.changeSlide({
49067                data: {
49068                    message: 'previous'
49069                }
49070            });
49071        } else if (event.keyCode === 39 && _.options.accessibility === true) {
49072            _.changeSlide({
49073                data: {
49074                    message: 'next'
49075                }
49076            });
49077        }
49078
49079    };
49080
49081    Slick.prototype.lazyLoad = function() {
49082
49083        var _ = this,
49084            loadRange, cloneRange, rangeStart, rangeEnd;
49085
49086        function loadImages(imagesScope) {
49087            $('img[data-lazy]', imagesScope).each(function() {
49088                var image = $(this),
49089                    imageSource = $(this).attr('data-lazy');
49090
49091                image
49092                  .load(function() { image.animate({ opacity: 1 }, 200); })
49093                  .css({ opacity: 0 })
49094                  .attr('src', imageSource)
49095                  .removeAttr('data-lazy')
49096                  .removeClass('slick-loading');
49097            });
49098        }
49099
49100        if (_.options.centerMode === true) {
49101            if (_.options.infinite === true) {
49102                rangeStart = _.currentSlide + (_.options.slidesToShow/2 + 1);
49103                rangeEnd = rangeStart + _.options.slidesToShow + 2;
49104            } else {
49105                rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow/2 + 1));
49106                rangeEnd = 2 + (_.options.slidesToShow/2 + 1) + _.currentSlide;
49107            }
49108        } else {
49109            rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
49110            rangeEnd = rangeStart + _.options.slidesToShow;
49111            if (_.options.fade === true ) {
49112                if(rangeStart > 0) rangeStart--;
49113                if(rangeEnd <= _.slideCount) rangeEnd++;
49114            }
49115        }
49116
49117        loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
49118        loadImages(loadRange);
49119
49120          if (_.slideCount <= _.options.slidesToShow){
49121              cloneRange = _.$slider.find('.slick-slide')
49122              loadImages(cloneRange)
49123          }else
49124        if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
49125            cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
49126            loadImages(cloneRange)
49127        } else if (_.currentSlide === 0) {
49128            cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
49129            loadImages(cloneRange);
49130        }
49131
49132    };
49133
49134    Slick.prototype.loadSlider = function() {
49135
49136        var _ = this;
49137
49138        _.setPosition();
49139
49140        _.$slideTrack.css({
49141            opacity: 1
49142        });
49143
49144        _.$slider.removeClass('slick-loading');
49145
49146        _.initUI();
49147
49148        if (_.options.lazyLoad === 'progressive') {
49149            _.progressiveLazyLoad();
49150        }
49151
49152    };
49153
49154    Slick.prototype.postSlide = function(index) {
49155
49156        var _ = this;
49157
49158        if (_.options.onAfterChange !== null) {
49159            _.options.onAfterChange.call(this, _, index);
49160        }
49161
49162        _.animating = false;
49163
49164        _.setPosition();
49165
49166        _.swipeLeft = null;
49167
49168        if (_.options.autoplay === true && _.paused === false) {
49169            _.autoPlay();
49170        }
49171
49172    };
49173
49174    Slick.prototype.progressiveLazyLoad = function() {
49175
49176        var _ = this,
49177            imgCount, targetImage;
49178
49179        imgCount = $('img[data-lazy]', _.$slider).length;
49180
49181        if (imgCount > 0) {
49182            targetImage = $('img[data-lazy]', _.$slider).first();
49183            targetImage.attr('src', targetImage.attr('data-lazy')).removeClass('slick-loading').load(function() {
49184                targetImage.removeAttr('data-lazy');
49185                _.progressiveLazyLoad();
49186            })
49187         .error(function () {
49188          targetImage.removeAttr('data-lazy');
49189          _.progressiveLazyLoad();
49190         });
49191        }
49192
49193    };
49194
49195    Slick.prototype.refresh = function() {
49196
49197        var _ = this,
49198            currentSlide = _.currentSlide;
49199
49200        _.destroy();
49201
49202        $.extend(_, _.initials);
49203
49204        _.init();
49205
49206        _.changeSlide({
49207            data: {
49208                message: 'index',
49209                index: currentSlide,
49210            }
49211        }, true);
49212
49213    };
49214
49215    Slick.prototype.reinit = function() {
49216
49217        var _ = this;
49218
49219        _.$slides = _.$slideTrack.children(_.options.slide).addClass(
49220            'slick-slide');
49221
49222        _.slideCount = _.$slides.length;
49223
49224        if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
49225            _.currentSlide = _.currentSlide - _.options.slidesToScroll;
49226        }
49227
49228        if (_.slideCount <= _.options.slidesToShow) {
49229            _.currentSlide = 0;
49230        }
49231
49232        _.setProps();
49233
49234        _.setupInfinite();
49235
49236        _.buildArrows();
49237
49238        _.updateArrows();
49239
49240        _.initArrowEvents();
49241
49242        _.buildDots();
49243
49244        _.updateDots();
49245
49246        _.initDotEvents();
49247
49248        if(_.options.focusOnSelect === true) {
49249            $(_.options.slide, _.$slideTrack).on('click.slick', _.selectHandler);
49250        }
49251
49252        _.setSlideClasses(0);
49253
49254        _.setPosition();
49255
49256        if (_.options.onReInit !== null) {
49257            _.options.onReInit.call(this, _);
49258        }
49259
49260    };
49261
49262    Slick.prototype.removeSlide = function(index, removeBefore, removeAll) {
49263
49264        var _ = this;
49265
49266        if (typeof(index) === 'boolean') {
49267            removeBefore = index;
49268            index = removeBefore === true ? 0 : _.slideCount - 1;
49269        } else {
49270            index = removeBefore === true ? --index : index;
49271        }
49272
49273        if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
49274            return false;
49275        }
49276
49277        _.unload();
49278
49279        if(removeAll === true) {
49280            _.$slideTrack.children().remove();
49281        } else {
49282            _.$slideTrack.children(this.options.slide).eq(index).remove();
49283        }
49284
49285        _.$slides = _.$slideTrack.children(this.options.slide);
49286
49287        _.$slideTrack.children(this.options.slide).detach();
49288
49289        _.$slideTrack.append(_.$slides);
49290
49291        _.$slidesCache = _.$slides;
49292
49293        _.reinit();
49294
49295    };
49296
49297    Slick.prototype.setCSS = function(position) {
49298
49299        var _ = this,
49300            positionProps = {}, x, y;
49301
49302        if (_.options.rtl === true) {
49303            position = -position;
49304        }
49305        x = _.positionProp == 'left' ? position + 'px' : '0px';
49306        y = _.positionProp == 'top' ? position + 'px' : '0px';
49307
49308        positionProps[_.positionProp] = position;
49309
49310        if (_.transformsEnabled === false) {
49311            _.$slideTrack.css(positionProps);
49312        } else {
49313            positionProps = {};
49314            if (_.cssTransitions === false) {
49315                positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
49316                _.$slideTrack.css(positionProps);
49317            } else {
49318                positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
49319                _.$slideTrack.css(positionProps);
49320            }
49321        }
49322
49323    };
49324
49325    Slick.prototype.setDimensions = function() {
49326
49327        var _ = this;
49328
49329        if (_.options.vertical === false) {
49330            if (_.options.centerMode === true) {
49331                _.$list.css({
49332                    padding: ('0px ' + _.options.centerPadding)
49333                });
49334            }
49335        } else {
49336            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
49337            if (_.options.centerMode === true) {
49338                _.$list.css({
49339                    padding: (_.options.centerPadding + ' 0px')
49340                });
49341            }
49342        }
49343
49344        _.listWidth = _.$list.width();
49345        _.listHeight = _.$list.height();
49346
49347
49348        if(_.options.vertical === false && _.options.variableWidth === false) {
49349            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
49350            _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
49351
49352        } else if (_.options.variableWidth === true) {
49353            var trackWidth = 0;
49354            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
49355            _.$slideTrack.children('.slick-slide').each(function(){
49356                trackWidth += Math.ceil($(this).outerWidth(true));
49357            });
49358            _.$slideTrack.width(Math.ceil(trackWidth) + 1);
49359        } else {
49360            _.slideWidth = Math.ceil(_.listWidth);
49361            _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
49362        }
49363
49364        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
49365        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
49366
49367    };
49368
49369    Slick.prototype.setFade = function() {
49370
49371        var _ = this,
49372            targetLeft;
49373
49374        _.$slides.each(function(index, element) {
49375            targetLeft = (_.slideWidth * index) * -1;
49376            if (_.options.rtl === true) {
49377                $(element).css({
49378                    position: 'relative',
49379                    right: targetLeft,
49380                    top: 0,
49381                    zIndex: 800,
49382                    opacity: 0
49383                });
49384            } else {
49385                $(element).css({
49386                    position: 'relative',
49387                    left: targetLeft,
49388                    top: 0,
49389                    zIndex: 800,
49390                    opacity: 0
49391                });
49392            }
49393        });
49394
49395        _.$slides.eq(_.currentSlide).css({
49396            zIndex: 900,
49397            opacity: 1
49398        });
49399
49400    };
49401
49402    Slick.prototype.setHeight = function() {
49403
49404        var _ = this;
49405
49406        if(_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
49407            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
49408            _.$list.css('height', targetHeight);
49409        }
49410
49411    };
49412
49413    Slick.prototype.setPosition = function() {
49414
49415        var _ = this;
49416
49417        _.setDimensions();
49418
49419        _.setHeight();
49420
49421        if (_.options.fade === false) {
49422            _.setCSS(_.getLeft(_.currentSlide));
49423        } else {
49424            _.setFade();
49425        }
49426
49427        if (_.options.onSetPosition !== null) {
vendor: 8,634 bytes, lines 49428-49665
49428            _.options.onSetPosition.call(this, _);
49429        }
49430
49431    };
49432
49433    Slick.prototype.setProps = function() {
49434
49435        var _ = this,
49436            bodyStyle = document.body.style;
49437
49438        _.positionProp = _.options.vertical === true ? 'top' : 'left';
49439
49440        if (_.positionProp === 'top') {
49441            _.$slider.addClass('slick-vertical');
49442        } else {
49443            _.$slider.removeClass('slick-vertical');
49444        }
49445
49446        if (bodyStyle.WebkitTransition !== undefined ||
49447            bodyStyle.MozTransition !== undefined ||
49448            bodyStyle.msTransition !== undefined) {
49449            if(_.options.useCSS === true) {
49450                _.cssTransitions = true;
49451            }
49452        }
49453
49454        if (bodyStyle.OTransform !== undefined) {
49455            _.animType = 'OTransform';
49456            _.transformType = "-o-transform";
49457            _.transitionType = 'OTransition';
49458            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
49459        }
49460        if (bodyStyle.MozTransform !== undefined) {
49461            _.animType = 'MozTransform';
49462            _.transformType = "-moz-transform";
49463            _.transitionType = 'MozTransition';
49464            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
49465        }
49466        if (bodyStyle.webkitTransform !== undefined) {
49467            _.animType = 'webkitTransform';
49468            _.transformType = "-webkit-transform";
49469            _.transitionType = 'webkitTransition';
49470            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
49471        }
49472        if (bodyStyle.msTransform !== undefined) {
49473            _.animType = 'msTransform';
49474            _.transformType = "-ms-transform";
49475            _.transitionType = 'msTransition';
49476            if (bodyStyle.msTransform === undefined) _.animType = false;
49477        }
49478        if (bodyStyle.transform !== undefined && _.animType !== false) {
49479            _.animType = 'transform';
49480            _.transformType = "transform";
49481            _.transitionType = 'transition';
49482        }
49483        _.transformsEnabled = (_.animType !== null && _.animType !== false);
49484
49485    };
49486
49487
49488    Slick.prototype.setSlideClasses = function(index) {
49489
49490        var _ = this,
49491            centerOffset, allSlides, indexOffset, remainder;
49492
49493        _.$slider.find('.slick-slide').removeClass('slick-active').removeClass('slick-center');
49494        allSlides = _.$slider.find('.slick-slide');
49495
49496        if (_.options.centerMode === true) {
49497
49498            centerOffset = Math.floor(_.options.slidesToShow / 2);
49499
49500            if(_.options.infinite === true) {
49501
49502                if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
49503                    _.$slides.slice(index - centerOffset, index + centerOffset + 1).addClass('slick-active');
49504                } else {
49505                    indexOffset = _.options.slidesToShow + index;
49506                    allSlides.slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2).addClass('slick-active');
49507                }
49508
49509                if (index === 0) {
49510                    allSlides.eq(allSlides.length - 1 - _.options.slidesToShow).addClass('slick-center');
49511                } else if (index === _.slideCount - 1) {
49512                    allSlides.eq(_.options.slidesToShow).addClass('slick-center');
49513                }
49514
49515            }
49516
49517            _.$slides.eq(index).addClass('slick-center');
49518
49519        } else {
49520
49521            if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
49522                _.$slides.slice(index, index + _.options.slidesToShow).addClass('slick-active');
49523            } else if ( allSlides.length <= _.options.slidesToShow ) {
49524                allSlides.addClass('slick-active');
49525            } else {
49526                remainder = _.slideCount%_.options.slidesToShow;
49527                indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
49528                if(_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
49529                    allSlides.slice(indexOffset-(_.options.slidesToShow-remainder), indexOffset + remainder).addClass('slick-active');
49530                } else {
49531                    allSlides.slice(indexOffset, indexOffset + _.options.slidesToShow).addClass('slick-active');
49532                }
49533            }
49534
49535        }
49536
49537        if (_.options.lazyLoad === 'ondemand') {
49538            _.lazyLoad();
49539        }
49540
49541    };
49542
49543    Slick.prototype.setupInfinite = function() {
49544
49545        var _ = this,
49546            i, slideIndex, infiniteCount;
49547
49548        if (_.options.fade === true) {
49549            _.options.centerMode = false;
49550        }
49551
49552        if (_.options.infinite === true && _.options.fade === false) {
49553
49554            slideIndex = null;
49555
49556            if (_.slideCount > _.options.slidesToShow) {
49557
49558                if (_.options.centerMode === true) {
49559                    infiniteCount = _.options.slidesToShow + 1;
49560                } else {
49561                    infiniteCount = _.options.slidesToShow;
49562                }
49563
49564                for (i = _.slideCount; i > (_.slideCount -
49565                    infiniteCount); i -= 1) {
49566                    slideIndex = i - 1;
49567                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
49568                        .attr('index', slideIndex-_.slideCount)
49569                        .prependTo(_.$slideTrack).addClass('slick-cloned');
49570                }
49571                for (i = 0; i < infiniteCount; i += 1) {
49572                    slideIndex = i;
49573                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
49574                        .attr('index', slideIndex+_.slideCount)
49575                        .appendTo(_.$slideTrack).addClass('slick-cloned');
49576                }
49577                _.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
49578                    $(this).attr('id', '');
49579                });
49580
49581            }
49582
49583        }
49584
49585    };
49586
49587    Slick.prototype.selectHandler = function(event) {
49588
49589        var _ = this;
49590        var index = parseInt($(event.target).parents('.slick-slide').attr("index"));
49591        if(!index) index = 0;
49592
49593        if(_.slideCount <= _.options.slidesToShow){
49594            _.$slider.find('.slick-slide').removeClass('slick-active');
49595            _.$slides.eq(index).addClass('slick-active');
49596            if(_.options.centerMode === true) {
49597                _.$slider.find('.slick-slide').removeClass('slick-center');
49598                _.$slides.eq(index).addClass('slick-center');
49599            }
49600            _.asNavFor(index);
49601            return;
49602        }
49603        _.slideHandler(index);
49604
49605    };
49606
49607    Slick.prototype.slideHandler = function(index,sync,dontAnimate) {
49608
49609        var targetSlide, animSlide, oldSlide, slideLeft, unevenOffset, targetLeft = null,
49610            _ = this;
49611
49612        sync = sync || false;
49613
49614        if (_.animating === true && _.options.waitForAnimate === true) {
49615            return;
49616        }
49617
49618        if (_.options.fade === true && _.currentSlide === index) {
49619            return;
49620        }
49621
49622        if (_.slideCount <= _.options.slidesToShow) {
49623            return;
49624        }
49625
49626        if (sync === false) {
49627            _.asNavFor(index);
49628        }
49629
49630        targetSlide = index;
49631        targetLeft = _.getLeft(targetSlide);
49632        slideLeft = _.getLeft(_.currentSlide);
49633
49634        _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
49635
49636        if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
49637            if(_.options.fade === false) {
49638                targetSlide = _.currentSlide;
49639                if(dontAnimate!==true) {
49640                    _.animateSlide(slideLeft, function() {
49641                        _.postSlide(targetSlide);
49642                    });
49643                } else {
49644                    _.postSlide(targetSlide);
49645                }
49646            }
49647            return;
49648        } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
49649            if(_.options.fade === false) {
49650                targetSlide = _.currentSlide;
49651                if(dontAnimate!==true) {
49652                    _.animateSlide(slideLeft, function() {
49653                        _.postSlide(targetSlide);
49654                    });
49655                } else {
49656                    _.postSlide(targetSlide);
49657                }
49658            }
49659            return;
49660        }
49661
49662        if (_.options.autoplay === true) {
49663            clearInterval(_.autoPlayTimer);
49664        }
49665
49666        if (targetSlide < 0) {
49667            if (_.slideCount % _.options.slidesToScroll !== 0) {
49668                animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
49669            } else {
49670                animSlide = _.slideCount + targetSlide;
49671            }
49672        } else if (targetSlide >= _.slideCount) {
49673            if (_.slideCount % _.options.slidesToScroll !== 0) {
49674                animSlide = 0;
49675            } else {
49676                animSlide = targetSlide - _.slideCount;
49677            }
49678        } else {
49679            animSlide = targetSlide;
49680        }
49681
49682        _.animating = true;
49683
49684        if (_.options.onBeforeChange !== null && index !== _.currentSlide) {
49685            _.options.onBeforeChange.call(this, _, _.currentSlide, animSlide);
49686        }
49687
49688        oldSlide = _.currentSlide;
49689        _.currentSlide = animSlide;
49690
49691        _.setSlideClasses(_.currentSlide);
49692
49693        _.updateDots();
49694        _.updateArrows();
49695
49696        if (_.options.fade === true) {
49697            if(dontAnimate!==true) {
49698                _.fadeSlide(oldSlide,animSlide, function() {
49699                    _.postSlide(animSlide);
49700                });
49701            } else {
49702                _.postSlide(animSlide);
49703            }
49704            return;
49705        }
49706
49707        if(dontAnimate!==true) {
49708            _.animateSlide(targetLeft, function() {
49709                _.postSlide(animSlide);
49710            });
49711        } else {
49712            _.postSlide(animSlide);
49713        }
49714
49715    };
49716
49717    Slick.prototype.startLoad = function() {
49718
49719        var _ = this;
49720
49721        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
49722
49723            _.$prevArrow.hide();
49724            _.$nextArrow.hide();
49725
49726        }
49727
49728        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
49729
49730            _.$dots.hide();
49731
49732        }
49733
49734        _.$slider.addClass('slick-loading');
49735
49736    };
49737
49738    Slick.prototype.swipeDirection = function() {
49739
49740        var xDist, yDist, r, swipeAngle, _ = this;
49741
49742        xDist = _.touchObject.startX - _.touchObject.curX;
49743        yDist = _.touchObject.startY - _.touchObject.curY;
49744        r = Math.atan2(yDist, xDist);
49745
49746        swipeAngle = Math.round(r * 180 / Math.PI);
49747        if (swipeAngle < 0) {
49748            swipeAngle = 360 - Math.abs(swipeAngle);
49749        }
49750
49751        if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
49752            return (_.options.rtl === false ? 'left' : 'right');
49753        }
49754        if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
49755            return (_.options.rtl === false ? 'left' : 'right');
49756        }
49757        if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
49758            return (_.options.rtl === false ? 'right' : 'left');
49759        }
49760
49761        return 'vertical';
49762
49763    };
49764
49765    Slick.prototype.swipeEnd = function(event) {
49766
49767        var _ = this, slideCount;
49768
49769        _.dragging = false;
49770
49771        _.shouldClick = (_.touchObject.swipeLength > 10) ? false : true;
49772
49773        if (_.touchObject.curX === undefined) {
49774            return false;
49775        }
49776
49777        if (_.touchObject.swipeLength >= _.touchObject.minSwipe) {
49778
49779            switch (_.swipeDirection()) {
49780                case 'left':
49781                    _.slideHandler(_.currentSlide + _.getSlideCount());
49782                    _.currentDirection = 0;
49783                    _.touchObject = {};
49784                    break;
49785
49786                case 'right':
49787                    _.slideHandler(_.currentSlide - _.getSlideCount());
49788                    _.currentDirection = 1;
49789                    _.touchObject = {};
49790                    break;
49791            }
49792        } else {
49793            if(_.touchObject.startX !== _.touchObject.curX) {
49794                _.slideHandler(_.currentSlide);
49795                _.touchObject = {};
49796            }
49797        }
49798
49799    };
49800
49801    Slick.prototype.swipeHandler = function(event) {
49802
49803        var _ = this;
49804
49805        if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
49806           return;
49807        } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
49808           return;
49809        }
49810
49811        _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
49812            event.originalEvent.touches.length : 1;
49813
49814        _.touchObject.minSwipe = _.listWidth / _.options
49815            .touchThreshold;
49816
49817        switch (event.data.action) {
49818
49819            case 'start':
49820                _.swipeStart(event);
49821                break;
49822
49823            case 'move':
49824                _.swipeMove(event);
49825                break;
49826
49827            case 'end':
49828                _.swipeEnd(event);
49829                break;
49830
49831        }
49832
49833    };
49834
49835    Slick.prototype.swipeMove = function(event) {
49836
49837        var _ = this,
49838            curLeft, swipeDirection, positionOffset, touches;
49839
49840        touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
49841
49842        if (!_.dragging || touches && touches.length !== 1) {
49843            return false;
49844        }
49845
49846        curLeft = _.getLeft(_.currentSlide);
49847
49848        _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
49849        _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
49850
49851        _.touchObject.swipeLength = Math.round(Math.sqrt(
49852            Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
49853
49854        swipeDirection = _.swipeDirection();
49855
49856        if (swipeDirection === 'vertical') {
49857            return;
49858        }
49859
49860        if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
49861            event.preventDefault();
49862        }
49863
49864        positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
49865
49866        if (_.options.vertical === false) {
49867            _.swipeLeft = curLeft + _.touchObject.swipeLength * positionOffset;
49868        } else {
49869            _.swipeLeft = curLeft + (_.touchObject
49870                .swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
49871        }
49872
49873        if (_.options.fade === true || _.options.touchMove === false) {
49874            return false;
49875        }
49876
49877        if (_.animating === true) {
49878            _.swipeLeft = null;
49879            return false;
49880        }
49881
49882        _.setCSS(_.swipeLeft);
49883
49884    };
49885
49886    Slick.prototype.swipeStart = function(event) {
49887
49888        var _ = this,
49889            touches;
49890
49891        if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
49892            _.touchObject = {};
49893            return false;
49894        }
49895
49896        if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
49897            touches = event.originalEvent.touches[0];
49898        }
49899
49900        _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
49901        _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
49902
49903        _.dragging = true;
49904
49905    };
49906
49907    Slick.prototype.unfilterSlides = function() {
49908
49909        var _ = this;
49910
49911        if (_.$slidesCache !== null) {
49912
49913            _.unload();
49914
49915            _.$slideTrack.children(this.options.slide).detach();
49916
49917            _.$slidesCache.appendTo(_.$slideTrack);
49918
49919            _.reinit();
49920
49921        }
49922
49923    };
49924
49925    Slick.prototype.unload = function() {
49926
49927        var _ = this;
49928
49929        $('.slick-cloned', _.$slider).remove();
49930        if (_.$dots) {
49931            _.$dots.remove();
49932        }
49933        if (_.$prevArrow && (typeof _.options.prevArrow !== 'object')) {
49934            _.$prevArrow.remove();
49935        }
49936        if (_.$nextArrow && (typeof _.options.nextArrow !== 'object')) {
49937            _.$nextArrow.remove();
49938        }
49939        _.$slides.removeClass(
49940            'slick-slide slick-active slick-visible').css('width', '');
49941
49942    };
49943
49944    Slick.prototype.updateArrows = function() {
49945
49946        var _ = this, centerOffset;
49947
49948        centerOffset = Math.floor(_.options.slidesToShow / 2)
49949
49950        if (_.options.arrows === true && _.options.infinite !==
49951            true && _.slideCount > _.options.slidesToShow) {
49952            _.$prevArrow.removeClass('slick-disabled');
49953            _.$nextArrow.removeClass('slick-disabled');
49954            if (_.currentSlide === 0) {
49955                _.$prevArrow.addClass('slick-disabled');
49956                _.$nextArrow.removeClass('slick-disabled');
49957            } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
49958                _.$nextArrow.addClass('slick-disabled');
49959                _.$prevArrow.removeClass('slick-disabled');
49960            } else if (_.currentSlide > _.slideCount - _.options.slidesToShow + centerOffset  && _.options.centerMode === true) {
49961                _.$nextArrow.addClass('slick-disabled');
49962                _.$prevArrow.removeClass('slick-disabled');
49963            }
49964        }
49965
49966    };
49967
49968    Slick.prototype.updateDots = function() {
49969
49970        var _ = this;
49971
49972        if (_.$dots !== null) {
49973
49974            _.$dots.find('li').removeClass('slick-active');
49975            _.$dots.find('li').eq(Math.floor(_.currentSlide / _.options.slidesToScroll)).addClass('slick-active');
49976
49977        }
49978
49979    };
49980
49981    $.fn.slick = function(options) {
49982        var _ = this;
49983        return _.each(function(index, element) {
49984
49985            element.slick = new Slick(element, options);
49986
49987        });
49988    };
49989
49990    $.fn.slickAdd = function(slide, slideIndex, addBefore) {
49991        var _ = this;
49992        return _.each(function(index, element) {
49993
49994            element.slick.addSlide(slide, slideIndex, addBefore);
49995
49996        });
49997    };
49998
49999    $.fn.slickCurrentSlide = function() {
50000        var _ = this;
50001        return _.get(0).slick.getCurrent();
50002    };
50003
50004    $.fn.slickFilter = function(filter) {
50005        var _ = this;
50006        return _.each(function(index, element) {
50007
50008            element.slick.filterSlides(filter);
50009
50010        });
50011    };
50012
50013    $.fn.slickGoTo = function(slide, dontAnimate) {
50014        var _ = this;
50015        return _.each(function(index, element) {
50016
50017            element.slick.changeSlide({
50018                data: {
50019                    message: 'index',
50020                    index: parseInt(slide)
50021                }
50022            }, dontAnimate);
50023
50024        });
50025    };
50026
50027    $.fn.slickNext = function() {
50028        var _ = this;
50029        return _.each(function(index, element) {
50030
50031            element.slick.changeSlide({
50032                data: {
50033                    message: 'next'
50034                }
50035            });
50036
50037        });
50038    };
50039
50040    $.fn.slickPause = function() {
50041        var _ = this;
50042        return _.each(function(index, element) {
50043
50044            element.slick.autoPlayClear();
50045            element.slick.paused = true;
50046
50047        });
50048    };
50049
50050    $.fn.slickPlay = function() {
50051        var _ = this;
50052        return _.each(function(index, element) {
50053
50054            element.slick.paused = false;
50055            element.slick.autoPlay();
50056
50057        });
50058    };
50059
50060    $.fn.slickPrev = function() {
50061        var _ = this;
50062        return _.each(function(index, element) {
50063
50064            element.slick.changeSlide({
50065                data: {
50066                    message: 'previous'
50067                }
50068            });
50069
50070        });
50071    };
50072
50073    $.fn.slickRemove = function(slideIndex, removeBefore) {
50074        var _ = this;
50075        return _.each(function(index, element) {
50076
50077            element.slick.removeSlide(slideIndex, removeBefore);
50078
50079        });
50080    };
50081
50082    $.fn.slickRemoveAll = function() {
50083        var _ = this;
50084        return _.each(function(index, element) {
50085
50086            element.slick.removeSlide(null, null, true);
50087
50088        });
50089    };
50090
50091    $.fn.slickGetOption = function(option) {
50092        var _ = this;
50093        return _.get(0).slick.options[option];
50094    };
50095
50096    $.fn.slickSetOption = function(option, value, refresh) {
50097        var _ = this;
50098        return _.each(function(index, element) {
50099
50100            element.slick.options[option] = value;
50101
50102            if (refresh === true) {
50103                element.slick.unload();
50104                element.slick.reinit();
50105            }
50106
50107        });
50108    };
50109
50110    $.fn.slickUnfilter = function() {
50111        var _ = this;
50112        return _.each(function(index, element) {
50113
50114            element.slick.unfilterSlides();
50115
50116        });
50117    };
50118
50119    $.fn.unslick = function() {
50120        var _ = this;
50121        return _.each(function(index, element) {
50122
50123          if (element.slick) {
50124            element.slick.destroy();
50125          }
50126
50127        });
50128    };
50129
50130    $.fn.getSlick = function() {
50131        var s = null;
50132        var _ = this;
50133        _.each(function(index, element) {
50134            s = element.slick;
50135        });
50136
50137        return s;
50138    };
50139
50140}));
50141// I18n.js
50142// =======
50143//
50144// This small library provides the Rails I18n API on the Javascript.
50145// You don't actually have to use Rails (or even Ruby) to use I18n.js.
50146// Just make sure you export all translations in an object like this:
50147//
50148//     I18n.translations.en = {
50149//       hello: "Hello World"
50150//     };
50151//
50152// See tests for specific formatting like numbers and dates.
50153//
50154
50155// Using UMD pattern from
50156// https://github.com/umdjs/umd#regular-module
50157// `returnExports.js` version
50158;(function (root, factory) {
50159  if (typeof define === 'function' && define.amd) {
50160    // AMD. Register as an anonymous module.
50161    define("i18n", function(){ return factory(root);});
50162  } else if (typeof module === 'object' && module.exports) {
50163    // Node. Does not work with strict CommonJS, but
50164    // only CommonJS-like environments that support module.exports,
50165    // like Node.
50166    module.exports = factory(root);
50167  } else {
50168    // Browser globals (root is window)
50169    root.I18n = factory(root);
50170  }
50171}(this, function(global) {
50172  "use strict";
50173
50174  // Use previously defined object if exists in current scope
50175  var I18n = global && global.I18n || {};
50176
50177  // Just cache the Array#slice function.
50178  var slice = Array.prototype.slice;
50179
50180  // Apply number padding.
50181  var padding = function(number) {
50182    return ("0" + number.toString()).substr(-2);
50183  };
50184
50185  // Improved toFixed number rounding function with support for unprecise floating points
50186  // JavaScript's standard toFixed function does not round certain numbers correctly (for example 0.105 with precision 2).
50187  var toFixed = function(number, precision) {
50188    return decimalAdjust('round', number, -precision).toFixed(precision);
50189  };
50190
50191  // Is a given variable an object?
50192  // Borrowed from Underscore.js
50193  var isObject = function(obj) {
50194    var type = typeof obj;
50195    return type === 'function' || type === 'object'
50196  };
50197
50198  var isFunction = function(func) {
50199    var type = typeof func;
50200    return type === 'function'
50201  };
50202
50203  // Check if value is different than undefined and null;
50204  var isSet = function(value) {
50205    return typeof(value) !== 'undefined' && value !== null;
50206  };
50207
50208  // Is a given value an array?
50209  // Borrowed from Underscore.js
50210  var isArray = function(val) {
50211    if (Array.isArray) {
50212      return Array.isArray(val);
50213    }
50214    return Object.prototype.toString.call(val) === '[object Array]';
50215  };
50216
50217  var isString = function(val) {
50218    return typeof val === 'string' || Object.prototype.toString.call(val) === '[object String]';
50219  };
50220
50221  var isNumber = function(val) {
50222    return typeof val === 'number' || Object.prototype.toString.call(val) === '[object Number]';
50223  };
50224
50225  var isBoolean = function(val) {
50226    return val === true || val === false;
50227  };
50228
50229  var isNull = function(val) {
50230    return val === null;
50231  };
50232
50233  var decimalAdjust = function(type, value, exp) {
50234    // If the exp is undefined or zero...
50235    if (typeof exp === 'undefined' || +exp === 0) {
50236      return Math[type](value);
50237    }
50238    value = +value;
50239    exp = +exp;
50240    // If the value is not a number or the exp is not an integer...
50241    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
50242      return NaN;
50243    }
50244    // Shift
50245    value = value.toString().split('e');
50246    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
50247    // Shift back
50248    value = value.toString().split('e');
50249    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
50250  };
50251
50252  var lazyEvaluate = function(message, scope) {
50253    if (isFunction(message)) {
50254      return message(scope);
50255    } else {
50256      return message;
50257    }
50258  };
50259
50260  var merge = function (dest, obj) {
50261    var key, value;
50262    for (key in obj) if (obj.hasOwnProperty(key)) {
50263      value = obj[key];
50264      if (isString(value) || isNumber(value) || isBoolean(value) || isArray(value) || isNull(value)) {
50265        dest[key] = value;
50266      } else {
50267        if (dest[key] == null) dest[key] = {};
50268        merge(dest[key], value);
50269      }
50270    }
50271    return dest;
50272  };
50273
50274  // Set default days/months translations.
50275  var DATE = {
50276      day_names: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
50277    , abbr_day_names: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
50278    , month_names: [null, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
50278November", "December"]
50279    , abbr_month_names: [null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
50280    , meridian: ["AM", "PM"]
50281  };
50282
50283  // Set default number format.
50284  var NUMBER_FORMAT = {
50285      precision: 3
50286    , separator: "."
50287    , delimiter: ","
50288    , strip_insignificant_zeros: false
50289  };
50290
50291  // Set default currency format.
50292  var CURRENCY_FORMAT = {
50293      unit: "$"
50294    , precision: 2
50295    , format: "%u%n"
50296    , sign_first: true
50297    , delimiter: ","
50298    , separator: "."
50299  };
50300
50301  // Set default percentage format.
50302  var PERCENTAGE_FORMAT = {
50303      unit: "%"
50304    , precision: 3
50305    , format: "%n%u"
50306    , separator: "."
50307    , delimiter: ""
50308  };
50309
50310  // Set default size units.
50311  var SIZE_UNITS = [null, "kb", "mb", "gb", "tb"];
50312
50313  // Other default options
50314  var DEFAULT_OPTIONS = {
50315    // Set default locale. This locale will be used when fallback is enabled and
50316    // the translation doesn't exist in a particular locale.
50317      defaultLocale: "en"
50318    // Set the current locale to `en`.
50319    , locale: "en"
50320    // Set the translation key separator.
50321    , defaultSeparator: "."
50322    // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
50323    , placeholder: /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm
50324    // Set if engine should fallback to the default locale when a translation
50325    // is missing.
50326    , fallbacks: false
50327    // Set the default translation object.
50328    , translations: {}
50329    // Set missing translation behavior. 'message' will display a message
50330    // that the translation is missing, 'guess' will try to guess the string
50331    , missingBehaviour: 'message'
50332    // if you use missingBehaviour with 'message', but want to know that the
50333    // string is actually missing for testing purposes, you can prefix the
50334    // guessed string by setting the value here. By default, no prefix!
50335    , missingTranslationPrefix: ''
50336  };
50337
50338  // Set default locale. This locale will be used when fallback is enabled and
50339  // the translation doesn't exist in a particular locale.
50340  I18n.reset = function() {
50341    var key;
50342    for (key in DEFAULT_OPTIONS) {
50343      this[key] = DEFAULT_OPTIONS[key];
50344    }
50345  };
50346
50347  // Much like `reset`, but only assign options if not already assigned
50348  I18n.initializeOptions = function() {
50349    var key;
50350    for (key in DEFAULT_OPTIONS) if (!isSet(this[key])) {
50351      this[key] = DEFAULT_OPTIONS[key];
50352    }
50353  };
50354  I18n.initializeOptions();
50355
50356  // Return a list of all locales that must be tried before returning the
50357  // missing translation message. By default, this will consider the inline option,
50358  // current locale and fallback locale.
50359  //
50360  //     I18n.locales.get("de-DE");
50361  //     // ["de-DE", "de", "en"]
50362  //
50363  // You can define custom rules for any locale. Just make sure you return a array
50364  // containing all locales.
50365  //
50366  //     // Default the Wookie locale to English.
50367  //     I18n.locales["wk"] = function(locale) {
50368  //       return ["en"];
50369  //     };
50370  //
50371  I18n.locales = {};
50372
50373  // Retrieve locales based on inline locale, current locale or default to
50374  // I18n's detection.
50375  I18n.locales.get = function(locale) {
50376    var result = this[locale] || this[I18n.locale] || this["default"];
50377
50378    if (isFunction(result)) {
50379      result = result(locale);
50380    }
50381
50382    if (isArray(result) === false) {
50383      result = [result];
50384    }
50385
50386    return result;
50387  };
50388
50389  // The default locale list.
50390  I18n.locales["default"] = function(locale) {
50391    var locales = []
50392      , list = []
50393    ;
50394
50395    // Handle the inline locale option that can be provided to
50396    // the `I18n.t` options.
50397    if (locale) {
50398      locales.push(locale);
50399    }
50400
50401    // Add the current locale to the list.
50402    if (!locale && I18n.locale) {
50403      locales.push(I18n.locale);
50404    }
50405
50406    // Add the default locale if fallback strategy is enabled.
50407    if (I18n.fallbacks && I18n.defaultLocale) {
50408      locales.push(I18n.defaultLocale);
50409    }
50410
50411    // Locale code format 1:
50412    // According to RFC4646 (http://www.ietf.org/rfc/rfc4646.txt)
50413    // language codes for Traditional Chinese should be `zh-Hant`
50414    //
50415    // But due to backward compatibility
50416    // We use older version of IETF language tag
50417    // @see http://www.w3.org/TR/html401/struct/dirlang.html
50418    // @see http://en.wikipedia.org/wiki/IETF_language_tag
50419    //
50420    // Format: `language-code = primary-code ( "-" subcode )*`
50421    //
50422    // primary-code uses ISO639-1
50423    // @see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
50424    // @see http://www.iso.org/iso/home/standards/language_codes.htm
50425    //
50426    // subcode uses ISO 3166-1 alpha-2
50427    // @see http://en.wikipedia.org/wiki/ISO_3166
50428    // @see http://www.iso.org/iso/country_codes.htm
50429    //
50430    // @note
50431    //   subcode can be in upper case or lower case
50432    //   defining it in upper case is a convention only
50433
50434
50435    // Locale code format 2:
50436    // Format: `code = primary-code ( "-" region-code )*`
50437    // primary-code uses ISO 639-1
50438    // script-code uses ISO 15924
50439    // region-code uses ISO 3166-1 alpha-2
50440    // Example: zh-Hant-TW, en-HK, zh-Hant-CN
50441    //
50442    // It is similar to RFC4646 (or actually the same),
50443    // but seems to be limited to language, script, region
50444
50445    // Compute each locale with its country code.
50446    // So this will return an array containing
50447    // `de-DE` and `de`
50448    // or
50449    // `zh-hans-tw`, `zh-hans`, `zh`
50450    // locales.
50451    locales.forEach(function(locale) {
50452      var localeParts = locale.split("-");
50453      var firstFallback = null;
50454      var secondFallback = null;
50455      if (localeParts.length === 3) {
50456        firstFallback = [
50457          localeParts[0],
50458          localeParts[1]
50459        ].join("-");
50460        secondFallback = localeParts[0];
50461      }
50462      else if (localeParts.length === 2) {
50463        firstFallback = localeParts[0];
50464      }
50465
50466      if (list.indexOf(locale) === -1) {
50467        list.push(locale);
50468      }
50469
50470      if (! I18n.fallbacks) {
50471        return;
50472      }
50473
50474      [
50475        firstFallback,
50476        secondFallback
50477      ].forEach(function(nullableFallbackLocale) {
50478        // We don't want null values
50479        if (typeof nullableFallbackLocale === "undefined") { return; }
50480        if (nullableFallbackLocale === null) { return; }
50481        // We don't want duplicate values
50482        //
50483        // Comparing with `locale` first is faster than
50484        // checking whether value's presence in the list
50485        if (nullableFallbackLocale === locale) { return; }
50486        if (list.indexOf(nullableFallbackLocale) !== -1) { return; }
50487
50488        list.push(nullableFallbackLocale);
50489      });
50490    });
50491
50492    // No locales set? English it is.
50493    if (!locales.length) {
50494      locales.push("en");
50495    }
50496
50497    return list;
50498  };
50499
50500  // Hold pluralization rules.
50501  I18n.pluralization = {};
50502
50503  // Return the pluralizer for a specific locale.
50504  // If no specify locale is found, then I18n's default will be used.
50505  I18n.pluralization.get = function(locale) {
50506    return this[locale] || this[I18n.locale] || this["default"];
50507  };
50508
50509  // The default pluralizer rule.
50510  // It detects the `zero`, `one`, and `other` scopes.
50511  I18n.pluralization["default"] = function(count) {
50512    switch (count) {
50513      case 0: return ["zero", "other"];
50514      case 1: return ["one"];
50515      default: return ["other"];
50516    }
50517  };
50518
50519  // Return current locale. If no locale has been set, then
50520  // the current locale will be the default locale.
50521  I18n.currentLocale = function() {
50522    return this.locale || this.defaultLocale;
50523  };
50524
50525  // Check if value is different than undefined and null;
50526  I18n.isSet = isSet;
50527
50528  // Find and process the translation using the provided scope and options.
50529  // This is used internally by some functions and should not be used as an
50530  // public API.
50531  I18n.lookup = function(scope, options) {
50532    options = options || {};
50533
50534    var locales = this.locales.get(options.locale).slice()
50535      , locale
50536      , scopes
50537      , fullScope
50538      , translations
50539    ;
50540
50541    fullScope = this.getFullScope(scope, options);
50542
50543    while (locales.length) {
50544      locale = locales.shift();
50545      scopes = fullScope.split(this.defaultSeparator);
50546      translations = this.translations[locale];
50547
50548      if (!translations) {
50549        continue;
50550      }
50551      while (scopes.length) {
50552        translations = translations[scopes.shift()];
50553
50554        if (translations === undefined || translations === null) {
50555          break;
50556        }
50557      }
50558
50559      if (translations !== undefined && translations !== null) {
50560        return translations;
50561      }
50562    }
50563
50564    if (isSet(options.defaultValue)) {
50565      return lazyEvaluate(options.defaultValue, scope);
50566    }
50567  };
50568
50569  // lookup pluralization rule key into translations
50570  I18n.pluralizationLookupWithoutFallback = function(count, locale, translations) {
50571    var pluralizer = this.pluralization.get(locale)
50572      , pluralizerKeys = pluralizer(count)
50573      , pluralizerKey
50574      , message;
50575
50576    if (isObject(translations)) {
50577      while (pluralizerKeys.length) {
50578        pluralizerKey = pluralizerKeys.shift();
50579        if (isSet(translations[pluralizerKey])) {
50580          message = translations[pluralizerKey];
50581          break;
50582        }
50583      }
50584    }
50585
50586    return message;
50587  };
50588
50589  // Lookup dedicated to pluralization
50590  I18n.pluralizationLookup = function(count, scope, options) {
50591    options = options || {};
50592    var locales = this.locales.get(options.locale).slice()
50593      , locale
50594      , scopes
50595      , translations
50596      , message
50597    ;
50598    scope = this.getFullScope(scope, options);
50599
50600    while (locales.length) {
50601      locale = locales.shift();
50602      scopes = scope.split(this.defaultSeparator);
50603      translations = this.translations[locale];
50604
50605      if (!translations) {
50606        continue;
50607      }
50608
50609      while (scopes.length) {
50610        translations = translations[scopes.shift()];
50611        if (!isObject(translations)) {
50612          break;
50613        }
50614        if (scopes.length === 0) {
50615          message = this.pluralizationLookupWithoutFallback(count, locale, translations);
50616        }
50617      }
50618      if (typeof message !== "undefined" && message !== null) {
50619        break;
50620      }
50621    }
50622
50623    if (typeof message === "undefined" || message === null) {
50624      if (isSet(options.defaultValue)) {
50625        if (isObject(options.defaultValue)) {
50626          message = this.pluralizationLookupWithoutFallback(count, options.locale, options.defaultValue);
50627        } else {
50628          message = options.defaultValue;
50629        }
50630        translations = options.defaultValue;
50631      }
50632    }
50633
50634    return { message: message, translations: translations };
50635  };
50636
50637  // Rails changed the way the meridian is stored.
50638  // It started with `date.meridian` returning an array,
50639  // then it switched to `time.am` and `time.pm`.
50640  // This function abstracts this difference and returns
50641  // the correct meridian or the default value when none is provided.
50642  I18n.meridian = function() {
50643    var time = this.lookup("time");
50644    var date = this.lookup("date");
50645
50646    if (time && time.am && time.pm) {
50647      return [time.am, time.pm];
50648    } else if (date && date.meridian) {
50649      return date.meridian;
50650    } else {
50651      return DATE.meridian;
50652    }
50653  };
50654
50655  // Merge serveral hash options, checking if value is set before
50656  // overwriting any value. The precedence is from left to right.
50657  //
50658  //     I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"});
50659  //     #=> {name: "John Doe", role: "user"}
50660  //
50661  I18n.prepareOptions = function() {
50662    var args = slice.call(arguments)
50663      , options = {}
50664      , subject
50665    ;
50666
50667    while (args.length) {
50668      subject = args.shift();
50669
50670      if (typeof(subject) != "object") {
50671        continue;
50672      }
50673
50674      for (var attr in subject) {
50675        if (!subject.hasOwnProperty(attr)) {
50676          continue;
50677        }
50678
50679        if (isSet(options[attr])) {
50680          continue;
50681        }
50682
50683        options[attr] = subject[attr];
50684      }
50685    }
50686
50687    return options;
50688  };
50689
50690  // Generate a list of translation options for default fallbacks.
50691  // `defaultValue` is also deleted from options as it is returned as part of
50692  // the translationOptions array.
50693  I18n.createTranslationOptions = function(scope, options) {
50694    var translationOptions = [{scope: scope}];
50695
50696    // Defaults should be an array of hashes containing either
50697    // fallback scopes or messages
50698    if (isSet(options.defaults)) {
50699      translationOptions = translationOptions.concat(options.defaults);
50700    }
50701
50702    // Maintain support for defaultValue. Since it is always a message
50703    // insert it in to the translation options as such.
50704    if (isSet(options.defaultValue)) {
50705      translationOptions.push({ message: options.defaultValue });
50706    }
50707
50708    return translationOptions;
50709  };
50710
50711  // Translate the given scope with the provided options.
50712  I18n.translate = function(scope, options) {
50713    options = options || {};
50714
50715    var translationOptions = this.createTranslationOptions(scope, options);
50716
50717    var translation;
50718    var usedScope = scope;
50719
50720    var optionsWithoutDefault = this.prepareOptions(options)
50721    delete optionsWithoutDefault.defaultValue
50722
50723    // Iterate through the translation options until a translation
50724    // or message is found.
50725    var translationFound =
50726      translationOptions.some(function(translationOption) {
50727        if (isSet(translationOption.scope)) {
50728          usedScope = translationOption.scope;
50729          translation = this.lookup(usedScope, optionsWithoutDefault);
50730        } else if (isSet(translationOption.message)) {
50731          translation = lazyEvaluate(translationOption.message, scope);
50732        }
50733
50734        if (translation !== undefined && translation !== null) {
50735          return true;
50736        }
50737      }, this);
50738
50739    if (!translationFound) {
50740      return this.missingTranslation(scope, options);
50741    }
50742
50743    if (typeof(translation) === "string") {
50744      translation = this.interpolate(translation, options);
50745    } else if (isArray(translation)) {
50746      translation = translation.map(function(t) {
50747        return (typeof(t) === "string" ? this.interpolate(t, options) : t);
50748      }, this);
50749    } else if (isObject(translation) && isSet(options.count)) {
50750      translation = this.pluralize(options.count, usedScope, options);
50751    }
50752
50753    return translation;
50754  };
50755
50756  // This function interpolates the all variables in the given message.
50757  I18n.interpolate = function(message, options) {
50758    if (message == null) {
50759      return message;
50760    }
50761
50762    options = options || {};
50763    var matches = message.match(this.placeholder)
50764      , placeholder
50765      , value
50766      , name
50767      , regex
50768    ;
50769
50770    if (!matches) {
50771      return message;
50772    }
50773
50774    while (matches.length) {
50775      placeholder = matches.shift();
50776      name = placeholder.replace(this.placeholder, "$1");
50777
50778      if (isSet(options[name])) {
50779        value = options[name].toString().replace(/\$/gm, "_#$#_");
50780      } else if (name in options) {
50781        value = this.nullPlaceholder(placeholder, message, options);
50782      } else {
50783        value = this.missingPlaceholder(placeholder, message, options);
50784      }
50785
50786      regex = new RegExp(placeholder.replace(/{/gm, "\\{").replace(/}/gm, "\\}"));
50787      message = message.replace(regex, value);
50788    }
50789
50790    return message.replace(/_#\$#_/g, "$");
50791  };
50792
50793  // Pluralize the given scope using the `count` value.
50794  // The pluralized translation may have other placeholders,
50795  // which will be retrieved from `options`.
50796  I18n.pluralize = function(count, scope, options) {
50797    options = this.prepareOptions({count: String(count)}, options)
50798    var pluralizer, result;
50799
50800    result = this.pluralizationLookup(count, scope, options);
50801    if (typeof result.translations === "undefined" || result.translations == null) {
50802      return this.missingTranslation(scope, options);
50803    }
50804
50805    if (typeof result.message !== "undefined" && result.message != null) {
50806      return this.interpolate(result.message, options);
50807    }
50808    else {
50809      pluralizer = this.pluralization.get(options.locale);
50810      return this.missingTranslation(scope + '.' + pluralizer(count)[0], options);
50811    }
50812  };
50813
50814  // Return a missing translation message for the given parameters.
50815  I18n.missingTranslation = function(scope, options) {
50816    //guess intended string
50817    if(this.missingBehaviour === 'guess'){
50818      //get only the last portion of the scope
50819      var s = scope.split('.').slice(-1)[0];
50820      //replace underscore with space && camelcase with space and lowercase letter
50821      return (this.missingTranslationPrefix.length > 0 ? this.missingTranslationPrefix : '') +
50822          s.replace('_',' ').replace(/([a-z])([A-Z])/g,
50823          function(match, p1, p2) {return p1 + ' ' + p2.toLowerCase()} );
50824    }
50825
50826    var localeForTranslation = (options != null && options.locale != null) ? options.locale : this.currentLocale();
50827    var fullScope           = this.getFullScope(scope, options);
50828    var fullScopeWithLocale = [localeForTranslation, fullScope].join(this.defaultSeparator);
50829
50830    return '[missing "' + fullScopeWithLocale + '" translation]';
50831  };
50832
50833  // Return a missing placeholder message for given parameters
50834  I18n.missingPlaceholder = function(placeholder, message, options) {
50835    return "[missing " + placeholder + " value]";
50836  };
50837
50838  I18n.nullPlaceholder = function() {
50839    return I18n.missingPlaceholder.apply(I18n, arguments);
50840  };
50841
50842  // Format number using localization rules.
50843  // The options will be retrieved from the `number.format` scope.
50844  // If this isn't present, then the following options will be used:
50845  //
50846  // - `precision`: `3`
50847  // - `separator`: `"."`
50848  // - `delimiter`: `","`
50849  // - `strip_insignificant_zeros`: `false`
50850  //
50851  // You can also override these options by providing the `options` argument.
50852  //
50853  I18n.toNumber = function(number, options) {
50854    options = this.prepareOptions(
50855        options
50856      , this.lookup("number.format")
50857      , NUMBER_FORMAT
50858    );
50859
50860    var negative = number < 0
50861      , string = toFixed(Math.abs(number), options.precision).toString()
50862      , parts = string.split(".")
50863      , precision
50864      , buffer = []
50865      , formattedNumber
50866      , format = options.format || "%n"
50867      , sign = negative ? "-" : ""
50868    ;
50869
50870    number = parts[0];
50871    precision = parts[1];
50872
50873    while (number.length > 0) {
50874      buffer.unshift(number.substr(Math.max(0, number.length - 3), 3));
50875      number = number.substr(0, number.length -3);
50876    }
50877
50878    formattedNumber = buffer.join(options.delimiter);
50879
50880    if (options.strip_insignificant_zeros && precision) {
50881      precision = precision.replace(/0+$/, "");
50882    }
50883
50884    if (options.precision > 0 && precision) {
50885      formattedNumber += options.separator + precision;
50886    }
50887
50888    if (options.sign_first) {
50889      format = "%s" + format;
50890    }
50891    else {
50892      format = format.replace("%n", "%s%n");
50893    }
50894
50895    formattedNumber = format
50896      .replace("%u", options.unit)
50897      .replace("%n", formattedNumber)
50898      .replace("%s", sign)
50899    ;
50900
50901    return formattedNumber;
50902  };
50903
50904  // Format currency with localization rules.
50905  // The options will be retrieved from the `number.currency.format` and
50906  // `number.format` scopes, in that order.
50907  //
50908  // Any missing option will be retrieved from the `I18n.toNumber` defaults and
50909  // the following options:
50910  //
50911  // - `unit`: `"$"`
50912  // - `precision`: `2`
50913  // - `format`: `"%u%n"`
50914  // - `delimiter`: `","`
50915  // - `separator`: `"."`
50916  //
50917  // You can also override these options by providing the `options` argument.
50918  //
50919  I18n.toCurrency = function(number, options) {
50920    options = this.prepareOptions(
50921        options
50922      , this.lookup("number.currency.format")
50923      , this.lookup("number.format")
50924      , CURRENCY_FORMAT
50925    );
50926
50927    return this.toNumber(number, options);
50928  };
50929
50930  // Localize several values.
50931  // You can provide the following scopes: `currency`, `number`, or `percentage`.
50932  // If you provide a scope that matches the `/^(date|time)/` regular expression
50933  // then the `value` will be converted by using the `I18n.toTime` function.
50934  //
50935  // It will default to the value's `toString` function.
50936  //
50937  I18n.localize = function(scope, value, options) {
50938    options || (options = {});
50939
50940    switch (scope) {
50941      case "currency":
50942        return this.toCurrency(value);
50943      case "number":
50944        scope = this.lookup("number.format");
50945        return this.toNumber(value, scope);
50946      case "percentage":
50947        return this.toPercentage(value);
50948      default:
50949        var localizedValue;
50950
50951        if (scope.match(/^(date|time)/)) {
50952          localizedValue = this.toTime(scope, value);
50953        } else {
50954          localizedValue = value.toString();
50955        }
50956
50957        return this.interpolate(localizedValue, options);
50958    }
50959  };
50960
50961  // Parse a given `date` string into a JavaScript Date object.
50962  // This function is time zone aware.
50963  //
50964  // The following string formats are recognized:
50965  //
50966  //    yyyy-mm-dd
50967  //    yyyy-mm-dd[ T]hh:mm::ss
50968  //    yyyy-mm-dd[ T]hh:mm::ss
50969  //    yyyy-mm-dd[ T]hh:mm::ssZ
50970  //    yyyy-mm-dd[ T]hh:mm::ss+0000
50971  //    yyyy-mm-dd[ T]hh:mm::ss+00:00
50972  //    yyyy-mm-dd[ T]hh:mm::ss.123Z
50973  //
50974  I18n.parseDate = function(date) {
50975    var matches, convertedDate, fraction;
50976    // A date input of `null` or `undefined` will be returned as-is
50977    if (date == null) {
50978      return date;
50979    }
50980    // we have a date, so just return it.
50981    if (typeof(date) === "object") {
50982      return date;
50983    }
50984
50985    matches = date.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2})([\.,]\d{1,3})?)?(Z|\+00:?00)?/);
50986
50987    if (matches) {
50988      for (var i = 1; i <= 6; i++) {
50989        matches[i] = parseInt(matches[i], 10) || 0;
50990      }
50991
50992      // month starts on 0
50993      matches[2] -= 1;
50994
50995      fraction = matches[7] ? 1000 * ("0" + matches[7]) : null;
50996
50997      if (matches[8]) {
50998        convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction));
50999      } else {
51000        convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction);
51001      }
51002    } else if (typeof(date) == "number") {
51003      // UNIX timestamp
51004      convertedDate = new Date();
51005      convertedDate.setTime(date);
51006    } else if (date.match(/([A-Z][a-z]{2}) ([A-Z][a-z]{2}) (\d+) (\d+:\d+:\d+) ([+-]\d+) (\d+)/)) {
51007      // This format `Wed Jul 20 13:03:39 +0000 2011` is parsed by
51008      // webkit/firefox, but not by IE, so we must parse it manually.
51009      convertedDate = new Date();
51010      convertedDate.setTime(Date.parse([
51011        RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$6, RegExp.$4, RegExp.$5
51012      ].join(" ")));
51013    } else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) {
51014      // a valid javascript format with timezone info
51015      convertedDate = new Date();
51016      convertedDate.setTime(Date.parse(date));
51017    } else {
51018      // an arbitrary javascript string
51019      convertedDate = new Date();
51020      convertedDate.setTime(Date.parse(date));
51021    }
51022
51023    return convertedDate;
51024  };
51025
51026  // Formats time according to the directives in the given format string.
51027  // The directives begins with a percent (%) character. Any text not listed as a
51028  // directive will be passed through to the output string.
51029  //
51030  // The accepted formats are:
51031  //
51032  //     %a     - The abbreviated weekday name (Sun)
51033  //     %A     - The full weekday name (Sunday)
51034  //     %b     - The abbreviated month name (Jan)
51035  //     %B     - The full month name (January)
51036  //     %c     - The preferred local date and time representation
51037  //     %d     - Day of the month (01..31)
51038  //     %-d    - Day of the month (1..31)
51039  //     %H     - Hour of the day, 24-hour clock (00..23)
51040  //     %-H/%k - Hour of the day, 24-hour clock (0..23)
51041  //     %I     - Hour of the day, 12-hour clock (01..12)
51042  //     %-I/%l - Hour of the day, 12-hour clock (1..12)
51043  //     %m     - Month of the year (01..12)
51044  //     %-m    - Month of the year (1..12)
51045  //     %M     - Minute of the hour (00..59)
51046  //     %-M    - Minute of the hour (0..59)
51047  //     %p     - Meridian indicator (AM  or  PM)
51048  //     %P     - Meridian indicator (am  or  pm)
51049  //     %S     - Second of the minute (00..60)
51050  //     %-S    - Second of the minute (0..60)
51051  //     %w     - Day of the week (Sunday is 0, 0..6)
51052  //     %y     - Year without a century (00..99)
51053  //     %-y    - Year without a century (0..99)
51054  //     %Y     - Year with century
51055  //     %z/%Z  - Timezone offset (+0545)
51056  //
51057  I18n.strftime = function(date, format) {
51058    var options = this.lookup("date")
51059      , meridianOptions = I18n.meridian()
51060    ;
51061
51062    if (!options) {
51063      options = {};
51064    }
51065
51066    options = this.prepareOptions(options, DATE);
51067
51068    if (isNaN(date.getTime())) {
51069      throw new Error('I18n.strftime() requires a valid date object, but received an invali
51069d date.');
51070    }
51071
51072    var weekDay = date.getDay()
51073      , day = date.getDate()
51074      , year = date.getFullYear()
51075      , month = date.getMonth() + 1
51076      , hour = date.getHours()
51077      , hour12 = hour
51078      , meridian = hour > 11 ? 1 : 0
51079      , secs = date.getSeconds()
51080      , mins = date.getMinutes()
51081      , offset = date.getTimezoneOffset()
51082      , absOffsetHours = Math.floor(Math.abs(offset / 60))
51083      , absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60)
51084      , timezoneoffset = (offset > 0 ? "-" : "+") +
51085          (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) +
51086          (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes)
51087    ;
51088
51089    if (hour12 > 12) {
51090      hour12 = hour12 - 12;
51091    } else if (hour12 === 0) {
51092      hour12 = 12;
51093    }
51094
51095    format = format.replace("%a", options.abbr_day_names[weekDay]);
51096    format = format.replace("%A", options.day_names[weekDay]);
51097    format = format.replace("%b", options.abbr_month_names[month]);
51098    format = format.replace("%B", options.month_names[month]);
51099    format = format.replace("%d", padding(day));
51100    format = format.replace("%e", day);
51101    format = format.replace("%-d", day);
51102    format = format.replace("%H", padding(hour));
51103    format = format.replace("%-H", hour);
51104    format = format.replace("%k", hour);
51105    format = format.replace("%I", padding(hour12));
51106    format = format.replace("%-I", hour12);
51107    format = format.replace("%l", hour12);
51108    format = format.replace("%m", padding(month));
51109    format = format.replace("%-m", month);
51110    format = format.replace("%M", padding(mins));
51111    format = format.replace("%-M", mins);
51112    format = format.replace("%p", meridianOptions[meridian]);
51113    format = format.replace("%P", meridianOptions[meridian].toLowerCase());
51114    format = format.replace("%S", padding(secs));
51115    format = format.replace("%-S", secs);
51116    format = format.replace("%w", weekDay);
51117    format = format.replace("%y", padding(year));
51118    format = format.replace("%-y", padding(year).replace(/^0+/, ""));
51119    format = format.replace("%Y", year);
51120    format = format.replace("%z", timezoneoffset);
51121    format = format.replace("%Z", timezoneoffset);
51122
51123    return format;
51124  };
51125
51126  // Convert the given dateString into a formatted date.
51127  I18n.toTime = function(scope, dateString) {
51128    var date = this.parseDate(dateString)
51129      , format = this.lookup(scope)
51130    ;
51131
51132    // A date input of `null` or `undefined` will be returned as-is
51133    if (date == null) {
51134      return date;
51135    }
51136
51137    var date_string = date.toString()
51138    if (date_string.match(/invalid/i)) {
51139      return date_string;
51140    }
51141
51142    if (!format) {
51143      return date_string;
51144    }
51145
51146    return this.strftime(date, format);
51147  };
51148
51149  // Convert a number into a formatted percentage value.
51150  I18n.toPercentage = function(number, options) {
51151    options = this.prepareOptions(
51152        options
51153      , this.lookup("number.percentage.format")
51154      , this.lookup("number.format")
51155      , PERCENTAGE_FORMAT
51156    );
51157
51158    return this.toNumber(number, options);
51159  };
51160
51161  // Convert a number into a readable size representation.
51162  I18n.toHumanSize = function(number, options) {
51163    var kb = 1024
51164      , size = number
51165      , iterations = 0
51166      , unit
51167      , precision
51168    ;
51169
51170    while (size >= kb && iterations < 4) {
51171      size = size / kb;
51172      iterations += 1;
51173    }
51174
51175    if (iterations === 0) {
51176      unit = this.t("number.human.storage_units.units.byte", {count: size});
51177      precision = 0;
51178    } else {
51179      unit = this.t("number.human.storage_units.units." + SIZE_UNITS[iterations]);
51180      precision = (size - Math.floor(size) === 0) ? 0 : 1;
51181    }
51182
51183    options = this.prepareOptions(
51184        options
51185      , {unit: unit, precision: precision, format: "%n%u", delimiter: ""}
51186    );
51187
51188    return this.toNumber(size, options);
51189  };
51190
51191  I18n.getFullScope = function(scope, options) {
51192    options = options || {};
51193
51194    // Deal with the scope as an array.
51195    if (isArray(scope)) {
51196      scope = scope.join(this.defaultSeparator);
51197    }
51198
51199    // Deal with the scope option provided through the second argument.
51200    //
51201    //    I18n.t('hello', {scope: 'greetings'});
51202    //
51203    if (options.scope) {
51204      scope = [options.scope, scope].join(this.defaultSeparator);
51205    }
51206
51207    return scope;
51208  };
51209  /**
51210   * Merge obj1 with obj2 (shallow merge), without modifying inputs
51211   * @param {Object} obj1
51212   * @param {Object} obj2
51213   * @returns {Object} Merged values of obj1 and obj2
51214   *
51215   * In order to support ES3, `Object.prototype.hasOwnProperty.call` is used
51216   * Idea is from:
51217   * https://stackoverflow.com/questions/8157700/object-has-no-hasownproperty-method-i-e-its-undefined-ie8
51218   */
51219  I18n.extend = function ( obj1, obj2 ) {
51220    if (typeof(obj1) === "undefined" && typeof(obj2) === "undefined") {
51221      return {};
51222    }
51223    return merge(obj1, obj2);
51224  };
51225
51226  // Set aliases, so we can save some typing.
51227  I18n.t = I18n.translate;
51228  I18n.l = I18n.localize;
51229  I18n.p = I18n.pluralize;
51230
51231  return I18n;
51232}));
51233// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
51234if (!Array.prototype.indexOf) {
51235    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
51236        "use strict";
51237        if (this == null) {
51238            throw new TypeError();
51239        }
51240        var t = Object(this);
51241        var len = t.length >>> 0;
51242        if (len === 0) {
51243            return -1;
51244        }
51245        var n = 0;
51246        if (arguments.length > 1) {
51247            n = Number(arguments[1]);
51248            if (n != n) { // shortcut for verifying if it's NaN
51249                n = 0;
51250            } else if (n != 0 && n != Infinity && n != -Infinity) {
51251                n = (n > 0 || -1) * Math.floor(Math.abs(n));
51252            }
51253        }
51254        if (n >= len) {
51255            return -1;
51256        }
51257        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
51258        for (; k < len; k++) {
51259            if (k in t && t[k] === searchElement) {
51260                return k;
51261            }
51262        }
51263        return -1;
51264    }
51265}
51266
51267// Production steps of ECMA-262, Edition 5, 15.4.4.18
51268// Reference: http://es5.github.com/#x15.4.4.18
51269// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
51270if ( !Array.prototype.forEach ) {
51271
51272  Array.prototype.forEach = function forEach( callback, thisArg ) {
51273
51274    var T, k;
51275
51276    if ( this == null ) {
51277      throw new TypeError( "this is null or not defined" );
51278    }
51279
51280    // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
51281    var O = Object(this);
51282
51283    // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
51284    // 3. Let len be ToUint32(lenValue).
51285    var len = O.length >>> 0; // Hack to convert O.length to a UInt32
51286
51287    // 4. If IsCallable(callback) is false, throw a TypeError exception.
51288    // See: http://es5.github.com/#x9.11
51289    if ( {}.toString.call(callback) !== "[object Function]" ) {
51290      throw new TypeError( callback + " is not a function" );
51291    }
51292
51293    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
51294    if ( thisArg ) {
51295      T = thisArg;
51296    }
51297
51298    // 6. Let k be 0
51299    k = 0;
51300
51301    // 7. Repeat, while k < len
51302    while( k < len ) {
51303
51304      var kValue;
51305
51306      // a. Let Pk be ToString(k).
51307      //   This is implicit for LHS operands of the in operator
51308      // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
51309      //   This step can be combined with c
51310      // c. If kPresent is true, then
51311      if ( Object.prototype.hasOwnProperty.call(O, k) ) {
51312
51313        // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
51314        kValue = O[ k ];
51315
51316        // ii. Call the Call internal method of callback with T as the this value and
51317        // argument list containing kValue, k, and O.
51318        callback.call( T, kValue, k, O );
51319      }
51320      // d. Increase k by 1.
51321      k++;
51322    }
51323    // 8. return undefined
51324  };
51325}
51326
51327// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
51328if (!Array.prototype.some)
51329{
51330  Array.prototype.some = function(fun /*, thisArg */)
51331  {
51332    'use strict';
51333
51334    if (this === void 0 || this === null)
51335      throw new TypeError();
51336
51337    var t = Object(this);
51338    var len = t.length >>> 0;
51339    if (typeof fun !== 'function')
51340      throw new TypeError();
51341
51342    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
51343    for (var i = 0; i < len; i++)
51344    {
51345      if (i in t && fun.call(thisArg, t[i], i, t))
51346        return true;
51347    }
51348
51349    return false;
51350  };
51351}
51352
51353// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
51354if (!Array.prototype.map) {
51355
51356  Array.prototype.map = function(callback/*, thisArg*/) {
51357
51358    var T, A, k;
51359
51360    if (this == null) {
51361      throw new TypeError('this is null or not defined');
51362    }
51363
51364    // 1. Let O be the result of calling ToObject passing the |this| 
51365    //    value as the argument.
51366    var O = Object(this);
51367
51368    // 2. Let lenValue be the result of calling the Get internal 
51369    //    method of O with the argument "length".
51370    // 3. Let len be ToUint32(lenValue).
51371    var len = O.length >>> 0;
51372
51373    // 4. If IsCallable(callback) is false, throw a TypeError exception.
51374    // See: http://es5.github.com/#x9.11
51375    if (typeof callback !== 'function') {
51376      throw new TypeError(callback + ' is not a function');
51377    }
51378
51379    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
51380    if (arguments.length > 1) {
51381      T = arguments[1];
51382    }
51383
51384    // 6. Let A be a new array created as if by the expression new Array(len) 
51385    //    where Array is the standard built-in constructor with that name and 
51386    //    len is the value of len.
51387    A = new Array(len);
51388
51389    // 7. Let k be 0
51390    k = 0;
51391
51392    // 8. Repeat, while k < len
51393    while (k < len) {
51394
51395      var kValue, mappedValue;
51396
51397      // a. Let Pk be ToString(k).
51398      //   This is implicit for LHS operands of the in operator
51399      // b. Let kPresent be the result of calling the HasProperty internal 
51400      //    method of O with argument Pk.
51401      //   This step can be combined with c
51402      // c. If kPresent is true, then
51403      if (k in O) {
51404
51405        // i. Let kValue be the result of calling the Get internal 
51406        //    method of O with argument Pk.
51407        kValue = O[k];
51408
51409        // ii. Let mappedValue be the result of calling the Call internal 
51410        //     method of callback with T as the this value and argument 
51411        //     list containing kValue, k, and O.
51412        mappedValue = callback.call(T, kValue, k, O);
51413
51414        // iii. Call the DefineOwnProperty internal method of A with arguments
51415        // Pk, Property Descriptor
51416        // { Value: mappedValue,
51417        //   Writable: true,
51418        //   Enumerable: true,
51419        //   Configurable: true },
51420        // and false.
51421
51422        // In browsers that support Object.defineProperty, use the following:
51423        // Object.defineProperty(A, k, {
51424        //   value: mappedValue,
51425        //   writable: true,
51426        //   enumerable: true,
51427        //   configurable: true
51428        // });
51429
51430        // For best browser support, use the following:
51431        A[k] = mappedValue;
51432      }
51433      // d. Increase k by 1.
51434      k++;
51435    }
51436
51437    // 9. return A
51438    return A;
51439  };
51440};
51441
51442// Using UMD pattern from
51443// https://github.com/umdjs/umd#regular-module
51444// `returnExports.js` version
51445;(function (root, factory) {
51446  if (typeof define === 'function' && define.amd) {
51447    // AMD. Register as an anonymous module.
51448    define(["i18n"], factory);
51449  } else if (typeof module === 'object' && module.exports) {
51450    // Node. Does not work with strict CommonJS, but
51451    // only CommonJS-like environments that support module.exports,
51452    // like Node.
51453    factory(require("i18n"));
51454  } else {
51455    // Browser globals (root is window)
51456    factory(root.I18n);
51457  }
51458}(this, function(I18n) {
51459  "use strict";
51460
51461  I18n.translations = {"en":{"javascript":{"bikes_search":{"abandoned":"Abandoned","absent":"Absent","color":"Color","hidden":"Hidden","impounded":"Impounded","location":"Location","registry":"Registry","registry_id":"Registry ID","search_external_registries":{"matches_found_html":"%{stolenness} bikes matching \"%{serial}\" found in external registries","no_matches_found_html":"No bikes matching \"%{serial}\" found in external registries","searching_html":"Searching external registries for bikes matching \"%{serial}\"..."},"search_serials_containing":{"matches_found_html":"%{stolenness} bikes with serial numbers containing \"%{serial}\"","no_matches_found_html":"No bikes with serial numbers containing \"%{serial}\" found","searching_html":"Searching for bikes with serial numbers containing \"%{serial}\"..."},"search_similar_serials":{"matches_found_html":"%{stolenness} bikes with serial numbers similar to \"%{serial}\"","no_matches_found_html":"No bikes with serial numbers similar to \"%{serial}\" found","searching_html":"Searching for bikes with serial numbers similar to \"%{serial}\"..."},"serial":"Serial","serial_search":"Serial number: %{serial}","stolen":"Stolen","unknown":"Unknown","unknown_brand":"Unknown Brand"},"payments":{"enter_the_minimum_amount":"Please enter an amount greater than 1","select_or_enter_amount":"Please select or enter an amount"}}},"es":{"javascript":{"bikes_search":{"abandoned":"Abandonado","absent":"Ausente","color":"Color","hidden":"Oculto","impounded":"Incautado","location":"Ubicación","registry":"Registro","registry_id":"ID de registro","search_external_registries":{"matches_found_html":"%{stolenness} Se encontraron bicicletas que coinciden con \"%{serial}\" en registros externos.","no_matches_found_html":"No se encontraron bicicletas que coincidieran con \"%{serial}\" en los registros externos.","searching_html":"Buscando en registros externos bicicletas que coincidan con \"%{serial}\"..."},"search_serials_containing":{"matches_found_html":"%{stolenness} bicicletas con números de serie que contienen \"%{serial}\"","no_matches_found_html":"No se encontraron bicicletas con números de serie que contuvieran \"%{serial}\".","searching_html":"Buscando bicicletas con números de serie que contengan \"%{serial}\"..."},"search_similar_serials":{"matches_found_html":"%{stolenness} bicicletas con números de serie similares a \"%{serial}\"","no_matches_found_html":"No se encontraron bicicletas con números de serie similares a \"%{serial}\".","searching_html":"Buscando bicicletas con números de serie similares a \"%{serial}\"..."},"serial":"De serie","serial_search":"Número de serie: %{serial}","stolen":"Robado","unknown":"Desconocido","unknown_brand":"Marca desconocida"},"payments":{"enter_the_minimum_amount":"Introduzca una cantidad mayor que 1.","select_or_enter_amount":"Seleccione o introduzca una cantidad."}}},"it":{"javascript":{"bikes_search":{"abandoned":"Abbandonato","absent":"Assente","color":"Colore","hidden":"Nascosto","impounded":"Sequestrato","location":"Luogo","registry":"Registro","registry_id":"ID di registrazione","search_external_registries":{"matches_found_html":"%{stolenness} biciclette corrispondenti a \"%{serial}\" trovate nei registri esterni","no_matches_found_html":"Nessuna bicicletta corrispondente a \"%{serial}\" trovata nei registri esterni","searching_html":"Ricerca in corso nei registri esterni di biciclette corrispondenti a \"%{serial}\"..."},"search_serials_containing":{"matches_found_html":"%{stolenness} biciclette con numeri di serie contenenti \"%{serial}\"","no_matches_found_html":"Non sono state trovate biciclette con numeri di serie contenenti \"%{serial}\".","searching_html":"Ricerca di biciclette con numeri di serie contenenti \"%{serial}\"..."},"search_similar_serials":{"matches_found_html":"%{stolenness} biciclette con numeri di serie simili a \"%{serial}\"","no_matches_found_html":"Non sono state trovate biciclette con numeri di serie simili a \"%{serial}\".","searching_html":"Ricerca di biciclette con numeri di serie simili a \"%{serial}\"..."},"serial":"Seriale","serial_search":"Numero di serie: %{serial}","stolen":"Rubata","unknown":"Sconosciuto","unknown_brand":"Marchio sconosciuto"},"payments":{"enter_the_minimum_amount":"Inserisci un importo maggiore di 1","select_or_enter_amount":"Seleziona o inserisci un importo"}}},"nb":{"javascript":{"bikes_search":{"abandoned":"Forlatt","absent":"Fraværende","color":"Farge","hidden":"Skjult","impounded":"Beslaglagt","location":"plassering","registry":"Register","registry_id":"Register-ID","search_external_registries":{"matches_found_html":"%{stolenness} sykler som samsvarer med \"%{serial}\" funnet i eksterne registre","no_matches_found_html":"Ingen sykler som samsvarer med \"%{serial}\" funnet i eksterne registre","searching_html":"Søker i eksterne registre etter sykler som samsvarer med \"%{serial}\"..."},"search_serials_containing":{"matches_found_html":"%{stolenness} sykler med serienumre som inneholder \"%{serial}\"","no_matches_found_html":"Ingen sykler med serienummer som inneholder \"%{serial}\" funnet","searching_html":"Søker etter sykler med serienumre som inneholder \"%{serial}\"..."},"search_similar_serials":{"matches_found_html":"%{stolenness} sykler med serienumre som ligner på \"%{serial}\"","no_matches_found_html":"Ingen sykler med serienummer som ligner på \"%{serial}\" funnet","searching_html":"Søker etter sykler med serienumre som ligner på \"%{serial}\"..."},"serial":"Serienummer","serial_search":"Serienummer: %{serial}","stolen":"Stjålet","unknown":"Ukjent","unknown_brand":"Ukjent merke"},"payments":{"enter_the_minimum_amount":"Vennligst skriv inn et beløp større enn 1","select_or_enter_amount":"Velg eller skriv inn et beløp"}}},"nl":{"javascript":{"bikes_search":{"abandoned":"Verlaten","absent":"Afwezig","color":"Kleur","hidden":"Verborgen","impounded":"In beslag genomen fietsen","location":"Plaats","registry":"Registry","registry_id":"Register-ID","search_external_registries":{"matches_found_html":"%{stolenness} fietsen die overeenkomen met %{serial} gevonden in externe registers","no_matches_found_html":"Geen overeenkomende fietsen %{serial} gevonden in externe registers","searching_html":"Zoeken naar externe registers voor overeenkomende fietsen %{serial} ..."},"search_serials_containing":{"matches_found_html":"%{stolenness} fietsen met serienummers die %{serial} bevatten","no_matches_found_html":"Geen fietsen met serienummers met %{serial} gevonden","searching_html":"Zoeken naar fietsen met serienummers die %{serial} bevatten ..."},"search_similar_serials":{"matches_found_html":"%{stolenness} fietsen met serienummers vergelijkbaar met %{serial}","no_matches_found_html":"Geen fietsen met serienummers vergelijkbaar met %{serial} gevonden","searching_html":"Zoeken naar fietsen met serienummers vergelijkbaar met %{serial} ..."},"serial":"Serie","serial_search":"Serienummer: %{serial}","stolen":"Gestolen","unknown":"Onbekend","unknown_brand":"Onbekend merk"},"payments":{"enter_the_minimum_amount":"Voer een bedrag groter dan 1 in","select_or_enter_amount":"Selecteer of voer een bedrag in"}}}};
51462}));
51463
51464
51465
51466!function(d,B,m,f){function v(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),e=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+e}function w(a,b,c,e){var k=a.length;e=e?"offset":"position";for(c=c||0;k--;){var g=a[k].el?a[k].el:d(a[k]),l=g[e]();l.left+=parseInt(g.css("margin-left"),10);l.top+=parseInt(g.css("margin-top"),10);
51466b[k]=[l.left-c,l.left+g.outerWidth()+c,l.top-c,l.top+g.outerHeight()+c]}}function p(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function x(a,b,c){b=[b.left,b.top];c=
51467c&&[c.left,c.top];for(var e,k=a.length,d=[];k--;)e=a[k],d[k]=[k,v(e,b),c&&v(e,c)];return d=d.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function q(a){this.options=d.extend({},n,a);this.containers=[];this.options.rootGroup||(this.scrollProxy=d.proxy(this.scroll,this),this.dragProxy=d.proxy(this.drag,this),this.dropProxy=d.proxy(this.drop,this),this.placeholder=d(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget=f))}function t(a,b){this.el=a;this.options=d.extend({},
51468z,b);this.group=q.get(this.options);this.rootGroup=this.options.rootGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;var c=this.rootGroup.options.itemPath;this.target=c?this.el.find(c):this.el;this.target.on(r.start,this.handle,d.proxy(this.dragInit,this));this.options.drop&&this.group.containers.push(this)}var r,z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},n={afterMove:function(a,b,c){},containerPath:"",containerSelector:"ol, ul",distance:0,
51469delay:0,handle:"",itemPath:"",itemSelector:"li",bodyClass:"dragging",draggedClass:"dragged",isValidTarget:function(a,b){return!0},onCancel:function(a,b,c,e){},onDrag:function(a,b,c,e){a.css(b)},onDragStart:function(a,b,c,e){a.css({height:a.outerHeight(),width:a.outerWidth()});a.addClass(b.group.options.draggedClass);d("body").addClass(b.group.options.bodyClass)},onDrop:function(a,b,c,e){a.removeClass(b.group.options.draggedClass).removeAttr("style");d("body").removeClass(b.group.options.bodyClass)},
51470onMousedown:function(a,b,c){if(!c.target.nodeName.match(/^(input|select|textarea)$/i))return c.preventDefault(),!0},placeholderClass:"placeholder",placeholder:'<li class="placeholder"></li>',pullPlaceholder:!0,serialize:function(a,b,c){a=d.extend({},a.data());if(c)return[b];b[0]&&(a.children=b);delete a.subContainers;delete a.sortable;return a},tolerance:0},s={},y=0,A={left:0,top:0,bottom:0,right:0};r={start:"touchstart.sortable mousedown.sortable",drop:"touchend.sortable touchcancel.sortable mouseup.sortable",
51471drag:"touchmove.sortable mousemove.sortable",scroll:"scroll.sortable"};q.get=function(a){s[a.group]||(a.group===f&&(a.group=y++),s[a.group]=new q(a));return s[a.group]};q.prototype={dragInit:function(a,b){this.$document=d(b.el[0].ownerDocument);var c=d(a.target).closest(this.options.itemSelector);c.length&&(this.item=c,this.itemContainer=b,!this.item.is(this.options.exclude)&&this.options.onMousedown(this.item,n.onMousedown,a)&&(this.setPointer(a),this.toggleListeners("on"),this.setupDelayTimer(),
51472this.dragInitDone=!0))},drag:function(a){if(!this.dragging){if(!this.distanceMet(a)||!this.delayMet)return;this.options.onDragStart(this.item,this.itemContainer,n.onDragStart,a);this.item.before(this.placeholder);this.dragging=!0}this.setPointer(a);this.options.onDrag(this.item,p(this.pointer,this.item.offsetParent()),n.onDrag,a);a=this.getPointer(a);var b=this.sameResultBox,c=this.options.tolerance;(!b||b.top-c>a.top||b.bottom+c<a.top||b.left-c>a.left||b.right+c<a.left)&&!this.searchValidTarget()&&
51473(this.placeholder.detach(),this.lastAppendedItem=f)},drop:function(a){this.toggleListeners("off");this.dragInitDone=!1;if(this.dragging){if(this.placeholder.closest("html")[0])this.placeholder.before(this.item).detach();else this.options.onCancel(this.item,this.itemContainer,n.onCancel,a);this.options.onDrop(this.item,this.getContainer(this.item),n.onDrop,a);this.clearDimensions();this.clearOffsetParent();this.lastAppendedItem=this.sameResultBox=f;this.dragging=!1}},searchValidTarget:function(a,b){a||
51474(a=this.relativePointer||this.pointer,b=this.lastRelativePointer||this.lastPointer);for(var c=x(this.getContainerDimensions(),a,b),e=c.length;e--;){var d=c[e][0];if(!c[e][1]||this.options.pullPlaceholder)if(d=this.containers[d],!d.disabled){if(!this.$getOffsetParent()){var g=d.getItemOffsetParent();a=p(a,g);b=p(b,g)}if(d.searchValidTarget(a,b))return!0}}this.sameResultBox&&(this.sameResultBox=f)},movePlaceholder:function(a,b,c,e){var d=this.lastAppendedItem;if(e||!d||d[0]!==b[0])b[c](this.placeholder),
51475this.lastAppendedItem=b,this.sameResultBox=e,this.options.afterMove(this.placeholder,a,b)},getContainerDimensions:function(){this.containerDimensions||w(this.containers,this.containerDimensions=[],this.options.tolerance,!this.$getOffsetParent());return this.containerDimensions},getContainer:function(a){return a.closest(this.options.containerSelector).data(m)},$getOffsetParent:function(){if(this.offsetParent===f){var a=this.containers.length-1,b=this.containers[a].getItemOffsetParent();if(!this.options.rootGroup)for(;a--;)if(b[0]!=
51476this.containers[a].getItemOffsetParent()[0]){b=!1;break}this.offsetParent=b}return this.offsetParent}
51476,setPointer:function(a){a=this.getPointer(a);if(this.$getOffsetParent()){var b=p(a,this.$getOffsetParent());this.lastRelativePointer=this.relativePointer;this.relativePointer=b}this.lastPointer=this.pointer;this.pointer=a},distanceMet:function(a){a=this.getPointer(a);return Math.max(Math.abs(this.pointer.left-a.left),Math.abs(this.pointer.top-a.top))>=this.options.distance},getPointer:function(a){var b=
51477a.originalEvent||a.originalEvent.touches&&a.originalEvent.touches[0];return{left:a.pageX||b.pageX,top:a.pageY||b.pageY}},setupDelayTimer:function(){var a=this;this.delayMet=!this.options.delay;this.delayMet||(clearTimeout(this._mouseDelayTimer),this._mouseDelayTimer=setTimeout(function(){a.delayMet=!0},this.options.delay))},scroll:function(a){this.clearDimensions();this.clearOffsetParent()},toggleListeners:function(a){var b=this;d.each(["drag","drop","scroll"],function(c,e){b.$document[a](r[e],b[e+
51478"Proxy"])})},clearOffsetParent:function(){this.offsetParent=f},clearDimensions:function(){this.traverse(function(a){a._clearDimensions()})},traverse:function(a){a(this);for(var b=this.containers.length;b--;)this.containers[b].traverse(a)},_clearDimensions:function(){this.containerDimensions=f},_destroy:function(){s[this.options.group]=f}};t.prototype={dragInit:function(a){var b=this.rootGroup;!this.disabled&&!b.dragInitDone&&this.options.drag&&this.isValidDrag(a)&&b.dragInit(a,this)},isValidDrag:function(a){return 1==
51479a.which||"touchstart"==a.type&&1==a.originalEvent.touches.length},searchValidTarget:function(a,b){var c=x(this.getItemDimensions(),a,b),e=c.length,d=this.rootGroup,g=!d.options.isValidTarget||d.options.isValidTarget(d.item,this);if(!e&&g)return d.movePlaceholder(this,this.target,"append"),!0;for(;e--;)if(d=c[e][0],!c[e][1]&&this.hasChildGroup(d)){if(this.getContainerGroup(d).searchValidTarget(a,b))return!0}else if(g)return this.movePlaceholder(d,a),!0},movePlaceholder:function(a,b){var c=d(this.items[a]),
51480e=this.itemDimensions[a],k="after",g=c.outerWidth(),f=c.outerHeight(),h=c.offset(),h={left:h.left,right:h.left+g,top:h.top,bottom:h.top+f};this.options.vertical?b.top<=(e[2]+e[3])/2?(k="before",h.bottom-=f/2):h.top+=f/2:b.left<=(e[0]+e[1])/2?(k="before",h.right-=g/2):h.left+=g/2;this.hasChildGroup(a)&&(h=A);this.rootGroup.movePlaceholder(this,c,k,h)},getItemDimensions:function(){this.itemDimensions||(this.items=this.$getChildren(this.el,"item").filter(":not(."+this.group.options.placeholderClass+
51481", ."+this.group.options.draggedClass+")").get(),w(this.items,this.itemDimensions=[],this.options.tolerance));return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return"relative"===a.css("position")||"absolute"===a.css("position")||"fixed"===a.css("position")?a:a.offsetParent()},hasChildGroup:function(a){return this.options.nested&&this.getContainerGroup(a)},getContainerGroup:function(a){var b=d.data(this.items[a],"subContainers");if(b===f){var c=this.$getChildren(this.items[a],
51482"container"),b=!1;c[0]&&(b=d.extend({},this.options,{rootGroup:this.rootGroup,group:y++}),b=c[m](b).data(m).group);d.data(this.items[a],"subContainers",b)}return b},$getChildren:function(a,b){var c=this.rootGroup.options,e=c[b+"Path"],c=c[b+"Selector"];a=d(a);e&&(a=a.find(e));return a.children(c)},_serialize:function(a,b){var c=this,e=this.$getChildren(a,b?"item":"container").not(this.options.exclude).map(function(){return c._serialize(d(this),!b)}).get();return this.rootGroup.options.serialize(a,
51483e,b)},traverse:function(a){d.each(this.items||[],function(b){(b=d.data(this,"subContainers"))&&b.traverse(a)});a(this)},_clearDimensions:function(){this.itemDimensions=f},_destroy:function(){var a=this;this.target.off(r.start,this.handle);this.el.removeData(m);this.options.drop&&(this.group.containers=d.grep(this.group.containers,function(b){return b!=a}));d.each(this.items||[],function(){d.removeData(this,"subContainers")})}};var u={enable:function(){this.traverse(function(a){a.disabled=!1})},disable:function(){this.traverse(function(a){a.disabled=
51484!0})},serialize:function(){return this._serialize(this.el,!0)},refresh:function(){this.traverse(function(a){a._clearDimensions()})},destroy:function(){this.traverse(function(a){a._destroy()})}};d.extend(t.prototype,u);d.fn[m]=function(a){var b=Array.prototype.slice.call(arguments,1
51484);return this.map(function(){var c=d(this),e=c.data(m);if(e&&u[a])return u[a].apply(e,b)||this;e||a!==f&&"object"!==typeof a||c.data(m,new t(c,a));return this})}}(jQuery,window,"sortable");
51485/*
51486 * jQuery UI Widget 1.10.1+amd
51487 * https://github.com/blueimp/jQuery-File-Upload
51488 *
51489 * Copyright 2013 jQuery Foundation and other contributors
51490 * Released under the MIT license.
51491 * http://jquery.org/license
51492 *
51493 * http://api.jqueryui.com/jQuery.widget/
51494 */
51495
51496(function (factory) {
51497    if (typeof define === "function" && define.amd) {
51498        // Register as an anonymous AMD module:
51499        define(["jquery"], factory);
51500    } else {
51501        // Browser globals:
51502        factory(jQuery);
51503    }
51504}(function( $, undefined ) {
51505
51506var uuid = 0,
51507  slice = Array.prototype.slice,
51508  _cleanData = $.cleanData;
51509$.cleanData = function( elems ) {
51510  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
51511    try {
51512      $( elem ).triggerHandler( "remove" );
51513    // http://bugs.jquery.com/ticket/8235
51514    } catch( e ) {}
51515  }
51516  _cleanData( elems );
51517};
51518
51519$.widget = function( name, base, prototype ) {
51520  var fullName, existingConstructor, constructor, basePrototype,
51521    // proxiedPrototype allows the provided prototype to remain unmodified
51522    // so that it can be used as a mixin for multiple widgets (#8876)
51523    proxiedPrototype = {},
51524    namespace = name.split( "." )[ 0 ];
51525
51526  name = name.split( "." )[ 1 ];
51527  fullName = namespace + "-" + name;
51528
51529  if ( !prototype ) {
51530    prototype = base;
51531    base = $.Widget;
51532  }
51533
51534  // create selector for plugin
51535  $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
51536    return !!$.data( elem, fullName );
51537  };
51538
51539  $[ namespace ] = $[ namespace ] || {};
51540  existingConstructor = $[ namespace ][ name ];
51541  constructor = $[ namespace ][ name ] = function( options, element ) {
51542    // allow instantiation without "new" keyword
51543    if ( !this._createWidget ) {
51544      return new constructor( options, element );
51545    }
51546
51547    // allow instantiation without initializing for simple inheritance
51548    // must use "new" keyword (the code above always passes args)
51549    if ( arguments.length ) {
51550      this._createWidget( options, element );
51551    }
51552  };
51553  // extend with the existing constructor to carry over any static properties
51554  $.extend( constructor, existingConstructor, {
51555    version: prototype.version,
51556    // copy the object used to create the prototype in case we need to
51557    // redefine the widget later
51558    _proto: $.extend( {}, prototype ),
51559    // track widgets that inherit from this widget in case this widget is
51560    // redefined after a widget inherits from it
51561    _childConstructors: []
51562  });
51563
51564  basePrototype = new base();
51565  // we need to make the options hash a property directly on the new instance
51566  // otherwise we'll modify the options hash on the prototype that we're
51567  // inheriting from
51568  basePrototype.options = $.widget.extend( {}, basePrototype.options );
51569  $.each( prototype, function( prop, value ) {
51570    if ( !$.isFunction( value ) ) {
51571      proxiedPrototype[ prop ] = value;
51572      return;
51573    }
51574    proxiedPrototype[ prop ] = (function() {
51575      var _super = function() {
51576          return base.prototype[ prop ].apply( this, arguments );
51577        },
51578        _superApply = function( args ) {
51579          return base.prototype[ prop ].apply( this, args );
51580        };
51581      return function() {
51582        var __super = this._super,
51583          __superApply = this._superApply,
51584          returnValue;
51585
51586        this._super = _super;
51587        this._superApply = _superApply;
51588
51589        returnValue = value.apply( this, arguments );
51590
51591        this._super = __super;
51592        this._superApply = __superApply;
51593
51594        return returnValue;
51595      };
51596    })();
51597  });
51598  constructor.prototype = $.widget.extend( basePrototype, {
51599    // TODO: remove support for widgetEventPrefix
51600    // always use the name + a colon as the prefix, e.g., draggable:start
51601    // don't prefix for widgets that aren't DOM-based
51602    widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
51603  }, proxiedPrototype, {
51604    constructor: constructor,
51605    namespace: namespace,
51606    widgetName: name,
51607    widgetFullName: fullName
51608  });
51609
51610  // If this widget is being redefined then we need to find all widgets that
51611  // are inheriting from it and redefine all of them so that they inherit from
51612  // the new version of this widget. We're essentially trying to replace one
51613  // level in the prototype chain.
vendor: 11,974 bytes, lines 51614-52000
51614  if ( existingConstructor ) {
51615    $.each( existingConstructor._childConstructors, function( i, child ) {
51616      var childPrototype = child.prototype;
51617
51618      // redefine the child widget using the same prototype that was
51619      // originally used, but inherit from the new version of the base
51620      $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
51621    });
51622    // remove the list of existing child constructors from the old constructor
51623    // so the old child constructors can be garbage collected
51624    delete existingConstructor._childConstructors;
51625  } else {
51626    base._childConstructors.push( constructor );
51627  }
51628
51629  $.widget.bridge( name, constructor );
51630};
51631
51632$.widget.extend = function( target ) {
51633  var input = slice.call( arguments, 1 ),
51634    inputIndex = 0,
51635    inputLength = input.length,
51636    key,
51637    value;
51638  for ( ; inputIndex < inputLength; inputIndex++ ) {
51639    for ( key in input[ inputIndex ] ) {
51640      value = input[ inputIndex ][ key ];
51641      if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
51642        // Clone objects
51643        if ( $.isPlainObject( value ) ) {
51644          target[ key ] = $.isPlainObject( target[ key ] ) ?
51645            $.widget.extend( {}, target[ key ], value ) :
51646            // Don't extend strings, arrays, etc. with objects
51647            $.widget.extend( {}, value );
51648        // Copy everything else by reference
51649        } else {
51650          target[ key ] = value;
51651        }
51652      }
51653    }
51654  }
51655  return target;
51656};
51657
51658$.widget.bridge = function( name, object ) {
51659  var fullName = object.prototype.widgetFullName || name;
51660  $.fn[ name ] = function( options ) {
51661    var isMethodCall = typeof options === "string",
51662      args = slice.call( arguments, 1 ),
51663      returnValue = this;
51664
51665    // allow multiple hashes to be passed on init
51666    options = !isMethodCall && args.length ?
51667      $.widget.extend.apply( null, [ options ].concat(args) ) :
51668      options;
51669
51670    if ( isMethodCall ) {
51671      this.each(function() {
51672        var methodValue,
51673          instance = $.data( this, fullName );
51674        if ( !instance ) {
51675          return $.error( "cannot call methods on " + name + " prior to initialization; " +
51676            "attempted to call method '" + options + "'" );
51677        }
51678        if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
51679          return $.error( "no such method '" + options + "' for " + name + " widget instance" );
51680        }
51681        methodValue = instance[ options ].apply( instance, args );
51682        if ( methodValue !== instance && methodValue !== undefined ) {
51683          returnValue = methodValue && methodValue.jquery ?
51684            returnValue.pushStack( methodValue.get() ) :
51685            methodValue;
51686          return false;
51687        }
51688      });
51689    } else {
51690      this.each(function() {
51691        var instance = $.data( this, fullName );
51692        if ( instance ) {
51693          instance.option( options || {} )._init();
51694        } else {
51695          $.data( this, fullName, new object( options, this ) );
51696        }
51697      });
51698    }
51699
51700    return returnValue;
51701  };
51702};
51703
51704$.Widget = function( /* options, element */ ) {};
51705$.Widget._childConstructors = [];
51706
51707$.Widget.prototype = {
51708  widgetName: "widget",
51709  widgetEventPrefix: "",
51710  defaultElement: "<div>",
51711  options: {
51712    disabled: false,
51713
51714    // callbacks
51715    create: null
51716  },
51717  _createWidget: function( options, element ) {
51718    element = $( element || this.defaultElement || this )[ 0 ];
51719    this.element = $( element );
51720    this.uuid = uuid++;
51721    this.eventNamespace = "." + this.widgetName + this.uuid;
51722    this.options = $.widget.extend( {},
51723      this.options,
51724      this._getCreateOptions(),
51725      options );
51726
51727    this.bindings = $();
51728    this.hoverable = $();
51729    this.focusable = $();
51730
51731    if ( element !== this ) {
51732      $.data( element, this.widgetFullName, this );
51733      this._on( true, this.element, {
51734        remove: function( event ) {
51735          if ( event.target === element ) {
51736            this.destroy();
51737          }
51738        }
51739      });
51740      this.document = $( element.style ?
51741        // element within the document
51742        element.ownerDocument :
51743        // element is window or document
51744        element.document || element );
51745      this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
51746    }
51747
51748    this._create();
51749    this._trigger( "create", null, this._getCreateEventData() );
51750    this._init();
51751  },
51752  _getCreateOptions: $.noop,
51753  _getCreateEventData: $.noop,
51754  _create: $.noop,
51755  _init: $.noop,
51756
51757  destroy: function() {
51758    this._destroy();
51759    // we can probably remove the unbind calls in 2.0
51760    // all event bindings should go through this._on()
51761    this.element
51762      .unbind( this.eventNamespace )
51763      // 1.9 BC for #7810
51764      // TODO remove dual storage
51765      .removeData( this.widgetName )
51766      .removeData( this.widgetFullName )
51767      // support: jquery <1.6.3
51768      // http://bugs.jquery.com/ticket/9413
51769      .removeData( $.camelCase( this.widgetFullName ) );
51770    this.widget()
51771      .unbind( this.eventNamespace )
51772      .removeAttr( "aria-disabled" )
51773      .removeClass(
51774        this.widgetFullName + "-disabled " +
51775        "ui-state-disabled" );
51776
51777    // clean up events and states
51778    this.bindings.unbind( this.eventNamespace );
51779    this.hoverable.removeClass( "ui-state-hover" );
51780    this.focusable.removeClass( "ui-state-focus" );
51781  },
51782  _destroy: $.noop,
51783
51784  widget: function() {
51785    return this.element;
51786  },
51787
51788  option: function( key, value ) {
51789    var options = key,
51790      parts,
51791      curOption,
51792      i;
51793
51794    if ( arguments.length === 0 ) {
51795      // don't return a reference to the internal hash
51796      return $.widget.extend( {}, this.options );
51797    }
51798
51799    if ( typeof key === "string" ) {
51800      // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
51801      options = {};
51802      parts = key.split( "." );
51803      key = parts.shift();
51804      if ( parts.length ) {
51805        curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
51806        for ( i = 0; i < parts.length - 1; i++ ) {
51807          curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
51808          curOption = curOption[ parts[ i ] ];
51809        }
51810        key = parts.pop();
51811        if ( value === undefined ) {
51812          return curOption[ key ] === undefined ? null : curOption[ key ];
51813        }
51814        curOption[ key ] = value;
51815      } else {
51816        if ( value === undefined ) {
51817          return this.options[ key ] === undefined ? null : this.options[ key ];
51818        }
51819        options[ key ] = value;
51820      }
51821    }
51822
51823    this._setOptions( options );
51824
51825    return this;
51826  },
51827  _setOptions: function( options ) {
51828    var key;
51829
51830    for ( key in options ) {
51831      this._setOption( key, options[ key ] );
51832    }
51833
51834    return this;
51835  },
51836  _setOption: function( key, value ) {
51837    this.options[ key ] = value;
51838
51839    if ( key === "disabled" ) {
51840      this.widget()
51841        .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
51842        .attr( "aria-disabled", value );
51843      this.hoverable.removeClass( "ui-state-hover" );
51844      this.focusable.removeClass( "ui-state-focus" );
51845    }
51846
51847    return this;
51848  },
51849
51850  enable: function() {
51851    return this._setOption( "disabled", false );
51852  },
51853  disable: function() {
51854    return this._setOption( "disabled", true );
51855  },
51856
51857  _on: function( suppressDisabledCheck, element, handlers ) {
51858    var delegateElement,
51859      instance = this;
51860
51861    // no suppressDisabledCheck flag, shuffle arguments
51862    if ( typeof suppressDisabledCheck !== "boolean" ) {
51863      handlers = element;
51864      element = suppressDisabledCheck;
51865      suppressDisabledCheck = false;
51866    }
51867
51868    // no element argument, shuffle and use this.element
51869    if ( !handlers ) {
51870      handlers = element;
51871      element = this.element;
51872      delegateElement = this.widget();
51873    } else {
51874      // accept selectors, DOM elements
51875      element = delegateElement = $( element );
51876      this.bindings = this.bindings.add( element );
51877    }
51878
51879    $.each( handlers, function( event, handler ) {
51880      function handlerProxy() {
51881        // allow widgets to customize the disabled handling
51882        // - disabled as an array instead of boolean
51883        // - disabled class as method for disabling individual parts
51884        if ( !suppressDisabledCheck &&
51885            ( instance.options.disabled === true ||
51886              $( this ).hasClass( "ui-state-disabled" ) ) ) {
51887          return;
51888        }
51889        return ( typeof handler === "string" ? instance[ handler ] : handler )
51890          .apply( instance, arguments );
51891      }
51892
51893      // copy the guid so direct unbinding works
51894      if ( typeof handler !== "string" ) {
51895        handlerProxy.guid = handler.guid =
51896          handler.guid || handlerProxy.guid || $.guid++;
51897      }
51898
51899      var match = event.match( /^(\w+)\s*(.*)$/ ),
51900        eventName = match[1] + instance.eventNamespace,
51901        selector = match[2];
51902      if ( selector ) {
51903        delegateElement.delegate( selector, eventName, handlerProxy );
51904      } else {
51905        element.bind( eventName, handlerProxy );
51906      }
51907    });
51908  },
51909
51910  _off: function( element, eventName ) {
51911    eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
51912    element.unbind( eventName ).undelegate( eventName );
51913  },
51914
51915  _delay: function( handler, delay ) {
51916    function handlerProxy() {
51917      return ( typeof handler === "string" ? instance[ handler ] : handler )
51918        .apply( instance, arguments );
51919    }
51920    var instance = this;
51921    return setTimeout( handlerProxy, delay || 0 );
51922  },
51923
51924  _hoverable: function( element ) {
51925    this.hoverable = this.hoverable.add( element );
51926    this._on( element, {
51927      mouseenter: function( event ) {
51928        $( event.currentTarget ).addClass( "ui-state-hover" );
51929      },
51930      mouseleave: function( event ) {
51931        $( event.currentTarget ).removeClass( "ui-state-hover" );
51932      }
51933    });
51934  },
51935
51936  _focusable: function( element ) {
51937    this.focusable = this.focusable.add( element );
51938    this._on( element, {
51939      focusin: function( event ) {
51940        $( event.currentTarget ).addClass( "ui-state-focus" );
51941      },
51942      focusout: function( event ) {
51943        $( event.currentTarget ).removeClass( "ui-state-focus" );
51944      }
51945    });
51946  },
51947
51948  _trigger: function( type, event, data ) {
51949    var prop, orig,
51950      callback = this.options[ type ];
51951
51952    data = data || {};
51953    event = $.Event( event );
51954    event.type = ( type === this.widgetEventPrefix ?
51955      type :
51956      this.widgetEventPrefix + type ).toLowerCase();
51957    // the original event may come from any element
51958    // so we need to reset the target on the new event
51959    event.target = this.element[ 0 ];
51960
51961    // copy original event properties over to the new event
51962    orig = event.originalEvent;
51963    if ( orig ) {
51964      for ( prop in orig ) {
51965        if ( !( prop in event ) ) {
51966          event[ prop ] = orig[ prop ];
51967        }
51968      }
51969    }
51970
51971    this.element.trigger( event, data );
51972    return !( $.isFunction( callback ) &&
51973      callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
51974      event.isDefaultPrevented() );
51975  }
51976};
51977
51978$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
51979  $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
51980    if ( typeof options === "string" ) {
51981      options = { effect: options };
51982    }
51983    var hasOptions,
51984      effectName = !options ?
51985        method :
51986        options === true || typeof options === "number" ?
51987          defaultEffect :
51988          options.effect || defaultEffect;
51989    options = options || {};
51990    if ( typeof options === "number" ) {
51991      options = { duration: options };
51992    }
51993    hasOptions = !$.isEmptyObject( options );
51994    options.complete = callback;
51995    if ( options.delay ) {
51996      element.delay( options.delay );
51997    }
51998    if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
51999      element[ method ]( options );
52000    } else if ( effectName !== method && element[ effectName ] ) {
52001      element[ effectName ]( options.duration, options.easing, callback );
52002    } else {
52003      element.queue(function( next ) {
52004        $( this )[ method ]();
52005        if ( callback ) {
52006          callback.call( element[ 0 ] );
52007        }
52008        next();
52009      });
52010    }
52011  };
52012});
52013
52014}));
52015/*
52016 * jQuery Iframe Transport Plugin 1.6.1
52017 * https://github.com/blueimp/jQuery-File-Upload
52018 *
52019 * Copyright 2011, Sebastian Tschan
52020 * https://blueimp.net
52021 *
52022 * Licensed under the MIT license:
52023 * http://www.opensource.org/licenses/MIT
52024 */
52025
52026/*jslint unparam: true, nomen: true */
52027/*global define, window, document */
52028
52029(function (factory) {
52030    'use strict';
52031    if (typeof define === 'function' && define.amd) {
52032        // Register as an anonymous AMD module:
52033        define(['jquery'], factory);
52034    } else {
52035        // Browser globals:
52036        factory(window.jQuery);
52037    }
52038}(function ($) {
52039    'use strict';
52040
52041    // Helper variable to create unique names for the transport iframes:
52042    var counter = 0;
52043
52044    // The iframe transport accepts three additional options:
52045    // options.fileInput: a jQuery collection of file input fields
52046    // options.paramName: the parameter name for the file form data,
52047    //  overrides the name property of the file input field(s),
52048    //  can be a string or an array of strings.
52049    // options.formData: an array of objects with name and value properties,
52050    //  equivalent to the return data of .serializeArray(), e.g.:
52051    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
52052    $.ajaxTransport('iframe', function (options) {
52053        if (options.async) {
52054            var form,
52055                iframe,
52056                addParamChar;
52057            return {
52058                send: function (_, completeCallback) {
52059                    form = $('<form style="display:none;"></form>');
52060                    form.attr('accept-charset', options.formAcceptCharset);
52061                    addParamChar = /\?/.test(options.url) ? '&' : '?';
52062                    // XDomainRequest only supports GET and POST:
52063                    if (options.type === 'DELETE') {
52064                        options.url = options.url + addParamChar + '_method=DELETE';
52065                        options.type = 'POST';
52066                    } else if (options.type === 'PUT') {
52067                        options.url = options.url + addParamChar + '_method=PUT';
52068                        options.type = 'POST';
52069                    } else if (options.type === 'PATCH') {
52070                        options.url = options.url + addParamChar + '_method=PATCH';
52071                        options.type = 'POST';
52072                    }
52073                    // javascript:false as initial iframe src
52074                    // prevents warning popups on HTTPS in IE6.
52075                    // IE versions below IE8 cannot set the name property of
52076                    // elements that have already been added to the DOM,
52077                    // so we set the name along with the iframe HTML markup:
52078                    iframe = $(
52079                        '<iframe src="javascript:false;" name="iframe-transport-' +
52080                            (counter += 1) + '"></iframe>'
52081                    ).bind('load', function () {
52082                        var fileInputClones,
52083                            paramNames = $.isArray(options.paramName) ?
52084                                    options.paramName : [options.paramName];
52085                        iframe
52086                            .unbind('load')
52087                            .bind('load', function () {
52088                                var response;
52089                                // Wrap in a try/catch block to catch exceptions thrown
52090                                // when trying to access cross-domain iframe contents:
52091                                try {
52092                                    response = iframe.contents();
52093                                    // Google Chrome and Firefox do not throw an
52094                                    // exception when calling iframe.contents() on
52095                                    // cross-domain requests, so we unify the response:
52096                                    if (!response.length || !response[0].firstChild) {
52097                                        throw new Error();
52098                                    }
52099                                } catch (e) {
52100                                    response = undefined;
52101                                }
52102                                // The complete callback returns the
52103                                // iframe content document as response object:
52104                                completeCallback(
52105                                    200,
52106                                    'success',
52107                                    {'iframe': response}
52108                                );
52109                                // Fix for IE endless progress bar activity bug
52110                                // (happens on form submits to iframe targets):
52111                                $('<iframe src="javascript:false;"></iframe>')
52112                                    .appendTo(form);
52113                                form.remove();
52114                            });
52115                        form
52116                            .prop('target', iframe.prop('name'))
52117                            .prop('action', options.url)
52118                            .prop('method', options.type);
52119                        if (options.formData) {
52120                            $.each(options.formData, function (index, field) {
52121                                $('<input type="hidden"/>')
52122                                    .prop('name', field.name)
52123                                    .val(field.value)
52124                                    .appendTo(form);
52125                            });
52126                        }
52127                        if (options.fileInput && options.fileInput.length &&
52128                                options.type === 'POST') {
52129                            fileInputClones = options.fileInput.clone();
52130                            // Insert a clone for each file input field:
52131                            options.fileInput.after(function (index) {
52132                                return fileInputClones[index];
52133                            });
52134                            if (options.paramName) {
52135                                options.fileInput.each(function (index) {
52136                                    $(this).prop(
52137                                        'name',
52138                                        paramNames[index] || options.paramName
52139                                    );
52140                                });
52141                            }
52142                            // Appending the file input fields to the hidden form
52143                            // removes them from their original location:
52144                            form
52145                                .append(options.fileInput)
52146                                .prop('enctype', 'multipart/form-data')
52147                                // enctype must be set as encoding for IE:
52148                                .prop('encoding', 'multipart/form-data');
52149                        }
52150                        form.submit();
52151                        // Insert the file input fields at their original location
52152                        // by replacing the clones with the originals:
52153                        if (fileInputClones && fileInputClones.length) {
52154                            options.fileInput.each(function (index, input) {
52155                                var clone = $(fileInputClones[index]);
52156                                $(input).prop('name', clone.prop('name'));
52157                                clone.replaceWith(input);
52158                            });
52159                        }
52160                    });
52161                    form.append(iframe).appendTo(document.body);
52162                },
52163                abort: function () {
52164                    if (iframe) {
52165                        // javascript:false as iframe src aborts the request
52166                        // and prevents warning popups on HTTPS in IE6.
52167                        // concat is used to avoid the "Script URL" JSLint error:
52168                        iframe
52169                            .unbind('load')
52170                            .prop('src', 'javascript'.concat(':false;'));
52171                    }
52172                    if (form) {
52173                        form.remove();
52174                    }
52175                }
52176            };
52177        }
52178    });
52179
52180    // The iframe transport returns the iframe content document as response.
52181    // The following adds converters from iframe to text, json, html, and script:
52182    $.ajaxSetup({
52183        converters: {
52184            'iframe text': function (iframe) {
52185                return iframe && $(iframe[0].body).text();
52186            },
52187            'iframe json': function (iframe) {
52188                return iframe && $.parseJSON($(iframe[0].body).text());
52189            },
52190            'iframe html': function (iframe) {
52191                return iframe && $(iframe[0].body).html();
52192            },
52193            'iframe script': function (iframe) {
52194                return iframe && $.globalEval($(iframe[0].body).text());
52195            }
52196        }
52197    });
52198
52199}));
52200/*
52201 * jQuery File Upload Plugin 5.42.3
52202 * https://github.com/blueimp/jQuery-File-Upload
52203 *
52204 * Copyright 2010, Sebastian Tschan
52205 * https://blueimp.net
52206 *
52207 * Licensed under the MIT license:
52208 * http://www.opensource.org/licenses/MIT
52209 */
52210
52211/* jshint nomen:false */
52212/* global define, require, window, document, location, Blob, FormData */
52213
52214(function (factory) {
52215    'use strict';
52216    if (typeof define === 'function' && define.amd) {
52217        // Register as an anonymous AMD module:
52218        define([
52219            'jquery',
52220            'jquery.ui.widget'
52221        ], factory);
52222    } else if (typeof exports === 'object') {
52223        // Node/CommonJS:
52224        factory(
52225            require('jquery'),
52226            require('./vendor/jquery.ui.widget')
52227        );
52228    } else {
52229        // Browser globals:
52230        factory(window.jQuery);
52231    }
52232}(function ($) {
52233    'use strict';
52234
52235    // Detect file input support, based on
52236    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
52237    $.support.fileInput = !(new RegExp(
52238        // Handle devices which give false positives for the feature detection:
52239        '(Android (1\\.[0156]|2\\.[01]))' +
52240            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
52241            '|(w(eb)?OSBrowser)|(webOS)' +
52242            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
52243    ).test(window.navigator.userAgent) ||
52244        // Feature detection for all other devices:
52245        $('<input type="file">').prop('disabled'));
52246
52247    // The FileReader API is not actually used, but works as feature detection,
52248    // as some Safari versions (5?) support XHR file uploads via the FormData API,
52249    // but not non-multipart XHR file uploads.
52250    // window.XMLHttpRequestUpload is not available on IE10, so we check for
52251    // window.ProgressEvent instead to detect XHR2 file upload capability:
52252    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
52253    $.support.xhrFormDataFileUpload = !!window.FormData;
52254
52255    // Detect support for Blob slicing (required for chunked uploads):
52256    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
52257        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
52258
52259    // Helper function to create drag handlers for dragover/dragenter/dragleave:
52260    function getDragHandler(type) {
52261        var isDragOver = type === 'dragover';
52262        return function (e) {
52263            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
52264            var dataTransfer = e.dataTransfer;
52265            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
52266                    this._trigger(
52267                        type,
52268                        $.Event(type, {delegatedEvent: e})
52269                    ) !== false) {
52270                e.preventDefault();
52271                if (isDragOver) {
52272                    dataTransfer.dropEffect = 'copy';
52273                }
52274            }
52275        };
52276    }
52277
52278    // The fileupload widget listens for change events on file input fields defined
52279    // via fileInput setting and paste or drop events of the given dropZone.
52280    // In addition to the default jQuery Widget methods, the fileupload widget
52281    // exposes the "add" and "send" methods, to add or directly send files using
52282    // the fileupload API.
52283    // By default, files added via file input selection, paste, drag & drop or
52284    // "add" method are uploaded immediately, but it is possible to override
52285    // the "add" callback option to queue file uploads.
52286    $.widget('blueimp.fileupload', {
52287
52288        options: {
52289            // The drop target element(s), by the default the complete document.
52290            // Set to null to disable drag & drop support:
52291            dropZone: $(document),
52292            // The paste target element(s), by the default undefined.
52293            // Set to a DOM node or jQuery object to enable file pasting:
52294            pasteZone: undefined,
52295            // The file input field(s), that are listened to for change events.
52296            // If undefined, it is set to the file input fields inside
52297            // of the widget element on plugin initialization.
52298            // Set to null to disable the change listener.
52299            fileInput: undefined,
52300            // By default, the file input field is replaced with a clone after
52301            // each input field change event. This is required for iframe transport
52302            // queues and allows change events to be fired for the same file
52303            // selection, but can be disabled by setting the following option to false:
52304            replaceFileInput: true,
52305            // The parameter name for the file form data (the request argument name).
52306            // If undefined or empty, the name property of the file input field is
52307            // used, or "files[]" if the file input name property is also empty,
52308            // can be a string or an array of strings:
52309            paramName: undefined,
52310            // By default, each file of a selection is uploaded using an individual
52311            // request for XHR type uploads. Set to false to upload file
52312            // selections in one request each:
52313            singleFileUploads: true,
52314            // To limit the number of files uploaded with one XHR request,
52315            // set the following option to an integer greater than 0:
52316            limitMultiFileUploads: undefined,
52317            // The following option limits the number of files uploaded with one
52318            // XHR request to keep the request size under or equal to the defined
52319            // limit in bytes:
52320            limitMultiFileUploadSize: undefined,
52321            // Multipart file uploads add a number of bytes to each uploaded file,
52322            // therefore the following option adds an overhead for each file used
52323            // in the limitMultiFileUploadSize configuration:
52324            limitMultiFileUploadSizeOverhead: 512,
52325            // Set the following option to true to issue all file upload requests
52326            // in a sequential order:
52327            sequentialUploads: false,
52328            // To limit the number of concurrent uploads,
52329            // set the following option to an integer greater than 0:
52330            limitConcurrentUploads: undefined,
52331            // Set the following option to true to force iframe transport uploads:
52332            forceIframeTransport: false,
52333            // Set the following option to the location of a redirect url on the
52334            // origin server, for cross-domain iframe transport uploads:
52335            redirect: undefined,
52336            // The parameter name for the redirect url, sent as part of the form
52337            // data and set to 'redirect' if this option is empty:
52338            redirectParamName: undefined,
52339            // Set the following option to the location of a postMessage window,
52340            // to enable postMessage transport uploads:
52341            postMessage: undefined,
52342            // By default, XHR file uploads are sent as multipart/form-data.
52343            // The iframe transport is always using multipart/form-data.
52344            // Set to false to enable non-multipart XHR uploads:
52345            multipart: true,
52346            // To upload large files in smaller chunks, set the following option
52347            // to a preferred maximum chunk size. If set to 0, null or undefined,
52348            // or the browser does not support the required Blob API, files will
52349            // be uploaded as a whole.
52350            maxChunkSize: undefined,
52351            // When a non-multipart upload or a chunked multipart upload has been
52352            // aborted, this option can be used to resume the upload by setting
52353            // it to the size of the already uploaded bytes. This option is most
52354            // useful when modifying the options object inside of the "add" or
52355            // "send" callbacks, as the options are cloned for each file upload.
52356            uploadedBytes: undefined,
52357            // By default, failed (abort or error) file uploads are removed from the
52358            // global progress calculation. Set the following option to fal
52358se to
52359            // prevent recalculating the global progress data:
52360            recalculateProgress: true,
52361            // Interval in milliseconds to calculate and trigger progress events:
52362            progressInterval: 100,
52363            // Interval in milliseconds to calculate progress bitrate:
52364            bitrateInterval: 500,
52365            // By default, uploads are started automatically when adding files:
52366            autoUpload: true,
52367
52368            // Error and info messages:
52369            messages: {
52370                uploadedBytes: 'Uploaded bytes exceed file size'
52371            },
52372
52373            // Translation function, gets the message key to be translated
52374            // and an object with context specific data as arguments:
52375            i18n: function (message, context) {
52376                message = this.messages[message] || message.toString();
52377                if (context) {
52378                    $.each(context, function (key, value) {
52379                        message = message.replace('{' + key + '}', value);
52380                    });
52381                }
52382                return message;
52383            },
52384
52385            // Additional form data to be sent along with the file uploads can be set
52386            // using this option, which accepts an array of objects with name and
52387            // value properties, a function returning such an array, a FormData
52388            // object (for XHR file uploads), or a simple object.
52389            // The form of the first fileInput is given as parameter to the function:
52390            formData: function (form) {
52391                return form.serializeArray();
52392            },
52393
52394            // The add callback is invoked as soon as files are added to the fileupload
52395            // widget (via file input selection, drag & drop, paste or add API call).
52396            // If the singleFileUploads option is enabled, this callback will be
52397            // called once for each file in the selection for XHR file uploads, else
52398            // once for each file selection.
52399            //
52400            // The upload starts when the submit method is invoked on the data parameter.
52401            // The data object contains a files property holding the added files
52402            // and allows you to override plugin options as well as define ajax settings.
52403            //
52404            // Listeners for this callback can also be bound the following way:
52405            // .bind('fileuploadadd', func);
52406            //
52407            // data.submit() returns a Promise object and allows to attach additional
52408            // handlers using jQuery's Deferred callbacks:
52409            // data.submit().done(func).fail(func).always(func);
52410            add: function (e, data) {
52411                if (e.isDefaultPrevented()) {
52412                    return false;
52413                }
52414                if (data.autoUpload || (data.autoUpload !== false &&
52415                        $(this).fileupload('option', 'autoUpload'))) {
52416                    data.process().done(function () {
52417                        data.submit();
52418                    });
52419                }
52420            },
52421
52422            // Other callbacks:
52423
52424            // Callback for the submit event of each file upload:
52425            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
52426
52427            // Callback for the start of each file upload request:
52428            // send: function (e, data) {}, // .bind('fileuploadsend', func);
52429
52430            // Callback for successful uploads:
52431            // done: function (e, data) {}, // .bind('fileuploaddone', func);
52432
52433            // Callback for failed (abort or error) uploads:
52434            // fail: function (e, data) {}, // .bind('fileuploadfail', func);
52435
52436            // Callback for completed (success, abort or error) requests:
52437            // always: function (e, data) {}, // .bind('fileuploadalways', func);
52438
52439            // Callback for upload progress events:
52440            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
52441
52442            // Callback for global upload progress events:
52443            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
52444
52445            // Callback for uploads start, equivalent to the global ajaxStart event:
52446            // start: function (e) {}, // .bind('fileuploadstart', func);
52447
52448            // Callback for uploads stop, equivalent to the global ajaxStop event:
52449            // stop: function (e) {}, // .bind('fileuploadstop', func);
52450
52451            // Callback for change events of the fileInput(s):
52452            // change: function (e, data) {}, // .bind('fileuploadchange', func);
52453
52454            // Callback for paste events to the pasteZone(s):
52455            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
52456
52457            // Callback for drop events of the dropZone(s):
52458            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
52459
52460            // Callback for dragover events of the dropZone(s):
52461            // dragover: function (e) {}, // .bind('fileuploaddragover', func);
52462
52463            // Callback for the start of each chunk upload request:
52464            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
52465
52466            // Callback for successful chunk uploads:
52467            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
52468
52469            // Callback for failed (abort or error) chunk uploads:
52470            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
52471
52472            // Callback for completed (success, abort or error) chunk upload requests:
52473            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
52474
52475            // The plugin options are used as settings object for the ajax calls.
52476            // The following are jQuery ajax settings required for the file uploads:
52477            processData: false,
52478            contentType: false,
52479            cache: false,
52480            timeout: 0
52481        },
52482
52483        // A list of options that require reinitializing event listeners and/or
52484        // special initialization code:
52485        _specialOptions: [
52486            'fileInput',
52487            'dropZone',
52488            'pasteZone',
52489            'multipart',
52490            'forceIframeTransport'
52491        ],
52492
52493        _blobSlice: $.support.blobSlice && function () {
52494            var slice = this.slice || this.webkitSlice || this.mozSlice;
52495            return slice.apply(this, arguments);
52496        },
52497
52498        _BitrateTimer: function () {
52499            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
52500            this.loaded = 0;
52501            this.bitrate = 0;
52502            this.getBitrate = function (now, loaded, interval) {
52503                var timeDiff = now - this.timestamp;
52504                if (!this.bitrate || !interval || timeDiff > interval) {
52505                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
52506                    this.loaded = loaded;
52507                    this.timestamp = now;
52508                }
52509                return this.bitrate;
52510            };
52511        },
52512
52513        _isXHRUpload: function (options) {
52514            return !options.forceIframeTransport &&
52515                ((!options.multipart && $.support.xhrFileUpload) ||
52516                $.support.xhrFormDataFileUpload);
52517        },
52518
52519        _getFormData: function (options) {
52520            var formData;
52521            if ($.type(options.formData) === 'function') {
52522                return options.formData(options.form);
52523            }
52524            if ($.isArray(options.formData)) {
52525                return options.formData;
52526            }
52527            if ($.type(options.formData) === 'object') {
52528                formData = [];
52529                $.each(options.formData, function (name, value) {
52530                    formData.push({name: name, value: value});
52531                });
52532                return formData;
52533            }
52534            return [];
52535        },
52536
52537        _getTotal: function (files) {
52538            var total = 0;
52539            $.each(files, function (index, file) {
52540                total += file.size || 1;
52541            });
52542            return total;
52543        },
52544
52545        _initProgressObject: function (obj) {
52546            var progress = {
52547                loaded: 0,
52548                total: 0,
52549                bitrate: 0
52550            };
52551            if (obj._progress) {
52552                $.extend(obj._progress, progress);
52553            } else {
52554                obj._progress = progress;
52555            }
52556        },
52557
52558        _initResponseObject: function (obj) {
52559            var prop;
52560            if (obj._response) {
52561                for (prop in obj._response) {
52562                    if (obj._response.hasOwnProperty(prop)) {
52563                        delete obj._response[prop];
52564                    }
52565                }
52566            } else {
52567                obj._response = {};
52568            }
52569        },
52570
52571        _onProgress: function (e, data) {
52572            if (e.lengthComputable) {
52573                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
52574                    loaded;
52575                if (data._time && data.progressInterval &&
52576                        (now - data._time < data.progressInterval) &&
52577                        e.loaded !== e.total) {
52578                    return;
52579                }
52580                data._time = now;
52581                loaded = Math.floor(
52582                    e.loaded / e.total * (data.chunkSize || data._progress.total)
52583                ) + (data.uploadedBytes || 0);
52584                // Add the difference from the previously loaded state
52585                // to the global loaded counter:
52586                this._progress.loaded += (loaded - data._progress.loaded);
52587                this._progress.bitrate = this._bitrateTimer.getBitrate(
52588                    now,
52589                    this._progress.loaded,
52590                    data.bitrateInterval
52591                );
52592                data._progress.loaded = data.loaded = loaded;
52593                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
52594                    now,
52595                    loaded,
52596                    data.bitrateInterval
52597                );
52598                // Trigger a custom progress event with a total data property set
52599                // to the file size(s) of the current upload and a loaded data
52600                // property calculated accordingly:
52601                this._trigger(
52602                    'progress',
52603                    $.Event('progress', {delegatedEvent: e}),
52604                    data
52605                );
52606                // Trigger a global progress event for all current file uploads,
52607                // including ajax calls queued for sequential file uploads:
52608                this._trigger(
52609                    'progressall',
52610                    $.Event('progressall', {delegatedEvent: e}),
52611                    this._progress
52612                );
52613            }
52614        },
52615
52616        _initProgressListener: function (options) {
52617            var that = this,
52618                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
52619            // Accesss to the native XHR object is required to add event listeners
52620            // for the upload progress event:
52621            if (xhr.upload) {
52622                $(xhr.upload).bind('progress', function (e) {
52623                    var oe = e.originalEvent;
52624                    // Make sure the progress event properties get copied over:
52625                    e.lengthComputable = oe.lengthComputable;
52626                    e.loaded = oe.loaded;
52627                    e.total = oe.total;
52628                    that._onProgress(e, options);
52629                });
52630                options.xhr = function () {
52631                    return xhr;
52632                };
52633            }
52634        },
52635
52636        _isInstanceOf: function (type, obj) {
52637            // Cross-frame instanceof check
52638            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
52639        },
52640
52641        _initXHRData: function (options) {
52642            var that = this,
52643                formData,
52644                file = options.files[0],
52645                // Ignore non-multipart setting if not supported:
52646                multipart = options.multipart || !$.support.xhrFileUpload,
52647                paramName = $.type(options.paramName) === 'array' ?
52648                    options.paramName[0] : options.paramName;
52649            options.headers = $.extend({}, options.headers);
52650            if (options.contentRange) {
52651                options.headers['Content-Range'] = options.contentRange;
52652            }
52653            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
52654                options.headers['Content-Disposition'] = 'attachment; filename="' +
52655                    encodeURI(file.name) + '"';
52656            }
52657            if (!multipart) {
52658                options.contentType = file.type || 'application/octet-stream';
52659                options.data = options.blob || file;
52660            } else if ($.support.xhrFormDataFileUpload) {
52661                if (options.postMessage) {
52662                    // window.postMessage does not allow sending FormData
52663                    // objects, so we just add the File/Blob objects to
52664                    // the formData array and let the postMessage window
52665                    // create the FormData object out of this array:
52666                    formData = this._getFormData(options);
52667                    if (options.blob) {
52668                        formData.push({
52669                            name: paramName,
52670                            value: options.blob
52671                        });
52672                    } else {
52673                        $.each(options.files, function (index, file) {
52674                            formData.push({
52675                                name: ($.type(options.paramName) === 'array' &&
52676                                    options.paramName[index]) || paramName,
52677                                value: file
52678                            });
52679                        });
52680                    }
52681                } else {
52682                    if (that._isInstanceOf('FormData', options.formData)) {
52683                        formData = options.formData;
52684                    } else {
52685                        formData = new FormData();
52686                        $.each(this._getFormData(options), function (index, field) {
52687                            formData.append(field.name, field.value);
52688                        });
52689                    }
52690                    if (options.blob) {
52691                        formData.append(paramName, options.blob, file.name);
52692                    } else {
52693                        $.each(options.files, function (index, file) {
52694                            // This check allows the tests to run with
52695                            // dummy objects:
52696                            if (that._isInstanceOf('File', file) ||
52697                                    that._isInstanceOf('Blob', file)) {
52698                                formData.append(
52699                                    ($.type(options.paramName) === 'array' &&
52700                                        options.paramName[index]) || paramName,
52701                                    file,
52702                                    file.uploadName || file.name
52703                                );
52704                            }
52705                        });
52706                    }
52707                }
52708                options.data = formData;
52709            }
52710            // Blob reference is not needed anymore, free memory:
52711            options.blob = null;
52712        },
52713
52714        _initIframeSettings: function (options) {
52715            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
52716            // Setting the dataType to iframe enables the iframe transport:
52717            options.dataType = 'iframe ' + (options.dataType || '');
52718            // The iframe transport accepts a serialized array as form data:
52719            options.formData = this._getFormData(options);
52720            // Add redirect url to form data on cross-domain uploads:
52721            if (options.redirect && targetHost && targetHost !== location.host) {
52722                options.formData.push({
52723                    name: options.redirectParamName || 'redirect',
52724                    value: options.redirect
52725                });
52726            }
52727        },
52728
52729        _initDataSettings: function (options) {
52730            if (this._isXHRUpload(options)) {
52731                if (!this._chunkedUpload(options, true)) {
52732                    if (!options.data) {
52733                        this._initXHRData(options);
52734                    }
52735                    this._initProgressListener(options);
52736                }
52737                if (options.postMessage) {
52738                    // Setting the dataType to postmessage enables the
52739                    // postMessage transport:
52740                    options.dataType = 'postmessage ' + (options.dataType || '');
52741                }
52742            } else {
52743                this._initIframeSettings(options);
52744            }
52745        },
52746
52747        _getParamName: function (options) {
52748            var fileInput = $(options.fileInput),
52749                paramName = options.paramName;
52750            if (!paramName) {
52751                paramName = [];
52752                fileInput.each(function () {
52753                    var input = $(this),
52754                        name = input.prop('name') || 'files[]',
52755                        i = (input.prop('files') || [1]).length;
52756                    while (i) {
52757                        paramName.push(name);
52758                        i -= 1;
52759                    }
52760                });
52761                if (!paramName.length) {
52762                    paramName = [fileInput.prop('name') || 'files[]'];
52763                }
52764            } else if (!$.isArray(paramName)) {
52765                paramName = [paramName];
52766            }
52767            return paramName;
52768        },
52769
52770        _initFormSettings: function (options) {
52771            // Retrieve missing options from the input field and the
52772            // associated form, if available:
52773            if (!options.form || !options.form.length) {
52774                options.form = $(options.fileInput.prop('form'));
52775                // If the given file input doesn't have an associated form,
52776                // use the default widget file input's form:
52777                if (!options.form.length) {
52778                    options.form = $(this.options.fileInput.prop('form'));
52779                }
52780            }
52781            options.paramName = this._getParamName(options);
52782            if (!options.url) {
52783                options.url = options.form.prop('action') || location.href;
52784            }
52785            // The HTTP request method must be "POST" or "PUT":
52786            options.type = (options.type ||
52787                ($.type(options.form.prop('method')) === 'string' &&
52788                    options.form.prop('method')) || ''
52789                ).toUpperCase();
52790            if (options.type !== 'POST' && options.type !== 'PUT' &&
52791                    options.type !== 'PATCH') {
52792                options.type = 'POST';
52793            }
52794            if (!options.formAcceptCharset) {
52795                options.formAcceptCharset = options.form.attr('accept-charset');
52796            }
52797        },
52798
52799        _getAJAXSettings: function (data) {
52800            var options = $.extend({}, this.options, data);
52801            this._initFormSettings(options);
52802            this._initDataSettings(options);
52803            return options;
52804        },
52805
52806        // jQuery 1.6 doesn't provide .state(),
52807        // while jQuery 1.8+ removed .isRejected() and .isResolved():
52808        _getDeferredState: function (deferred) {
52809            if (deferred.state) {
52810                return deferred.state();
52811            }
52812            if (deferred.isResolved()) {
52813                return 'resolved';
52814            }
52815            if (deferred.isRejected()) {
52816                return 'rejected';
52817            }
52818            return 'pending';
52819        },
52820
52821        // Maps jqXHR callbacks to the equivalent
52822        // methods of the given Promise object:
52823        _enhancePromise: function (promise) {
52824            promise.success = promise.done;
52825            promise.error = promise.fail;
52826            promise.complete = promise.always;
52827            return promise;
52828        },
52829
52830        // Creates and returns a Promise object enhanced with
52831        // the jqXHR methods abort, success, error and complete:
52832        _getXHRPromise: function (resolveOrReject, context, args
52832) {
52833            var dfd = $.Deferred(),
52834                promise = dfd.promise();
52835            context = context || this.options.context || promise;
52836            if (resolveOrReject === true) {
52837                dfd.resolveWith(context, args);
52838            } else if (resolveOrReject === false) {
52839                dfd.rejectWith(context, args);
52840            }
52841            promise.abort = dfd.promise;
52842            return this._enhancePromise(promise);
52843        },
52844
52845        // Adds convenience methods to the data callback argument:
52846        _addConvenienceMethods: function (e, data) {
52847            var that = this,
52848                getPromise = function (args) {
52849                    return $.Deferred().resolveWith(that, args).promise();
52850                };
52851            data.process = function (resolveFunc, rejectFunc) {
52852                if (resolveFunc || rejectFunc) {
52853                    data._processQueue = this._processQueue =
52854                        (this._processQueue || getPromise([this])).pipe(
52855                            function () {
52856                                if (data.errorThrown) {
52857                                    return $.Deferred()
52858                                        .rejectWith(that, [data]).promise();
52859                                }
52860                                return getPromise(arguments);
52861                            }
52862                        ).pipe(resolveFunc, rejectFunc);
52863                }
52864                return this._processQueue || getPromise([this]);
52865            };
52866            data.submit = function () {
52867                if (this.state() !== 'pending') {
52868                    data.jqXHR = this.jqXHR =
52869                        (that._trigger(
52870                            'submit',
52871                            $.Event('submit', {delegatedEvent: e}),
52872                            this
52873                        ) !== false) && that._onSend(e, this);
52874                }
52875                return this.jqXHR || that._getXHRPromise();
52876            };
52877            data.abort = function () {
52878                if (this.jqXHR) {
52879                    return this.jqXHR.abort();
52880                }
52881                this.errorThrown = 'abort';
52882                that._trigger('fail', null, this);
52883                return that._getXHRPromise(false);
52884            };
52885            data.state = function () {
52886                if (this.jqXHR) {
52887                    return that._getDeferredState(this.jqXHR);
52888                }
52889                if (this._processQueue) {
52890                    return that._getDeferredState(this._processQueue);
52891                }
52892            };
52893            data.processing = function () {
52894                return !this.jqXHR && this._processQueue && that
52895                    ._getDeferredState(this._processQueue) === 'pending';
52896            };
52897            data.progress = function () {
52898                return this._progress;
52899            };
52900            data.response = function () {
52901                return this._response;
52902            };
52903        },
52904
52905        // Parses the Range header from the server response
52906        // and returns the uploaded bytes:
52907        _getUploadedBytes: function (jqXHR) {
52908            var range = jqXHR.getResponseHeader('Range'),
52909                parts = range && range.split('-'),
52910                upperBytesPos = parts && parts.length > 1 &&
52911                    parseInt(parts[1], 10);
52912            return upperBytesPos && upperBytesPos + 1;
52913        },
52914
52915        // Uploads a file in multiple, sequential requests
52916        // by splitting the file up in multiple blob chunks.
52917        // If the second parameter is true, only tests if the file
52918        // should be uploaded in chunks, but does not invoke any
52919        // upload requests:
52920        _chunkedUpload: function (options, testOnly) {
52921            options.uploadedBytes = options.uploadedBytes || 0;
52922            var that = this,
52923                file = options.files[0],
52924                fs = file.size,
52925                ub = options.uploadedBytes,
52926                mcs = options.maxChunkSize || fs,
52927                slice = this._blobSlice,
52928                dfd = $.Deferred(),
52929                promise = dfd.promise(),
52930                jqXHR,
52931                upload;
52932            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
52933                    options.data) {
52934                return false;
52935            }
52936            if (testOnly) {
52937                return true;
52938            }
52939            if (ub >= fs) {
52940                file.error = options.i18n('uploadedBytes');
52941                return this._getXHRPromise(
52942                    false,
52943                    options.context,
52944                    [null, 'error', file.error]
52945                );
52946            }
52947            // The chunk upload method:
52948            upload = function () {
52949                // Clone the options object for each chunk upload:
52950                var o = $.extend({}, options),
52951                    currentLoaded = o._progress.loaded;
52952                o.blob = slice.call(
52953                    file,
52954                    ub,
52955                    ub + mcs,
52956                    file.type
52957                );
52958                // Store the current chunk size, as the blob itself
52959                // will be dereferenced after data processing:
52960                o.chunkSize = o.blob.size;
52961                // Expose the chunk bytes position range:
52962                o.contentRange = 'bytes ' + ub + '-' +
52963                    (ub + o.chunkSize - 1) + '/' + fs;
52964                // Process the upload data (the blob and potential form data):
52965                that._initXHRData(o);
52966                // Add progress listeners for this chunk upload:
52967                that._initProgressListener(o);
52968                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
52969                        that._getXHRPromise(false, o.context))
52970                    .done(function (result, textStatus, jqXHR) {
52971                        ub = that._getUploadedBytes(jqXHR) ||
52972                            (ub + o.chunkSize);
52973                        // Create a progress event if no final progress event
52974                        // with loaded equaling total has been triggered
52975                        // for this chunk:
52976                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
52977                            that._onProgress($.Event('progress', {
52978                                lengthComputable: true,
52979                                loaded: ub - o.uploadedBytes,
52980                                total: ub - o.uploadedBytes
52981                            }), o);
52982                        }
52983                        options.uploadedBytes = o.uploadedBytes = ub;
52984                        o.result = result;
52985                        o.textStatus = textStatus;
52986                        o.jqXHR = jqXHR;
52987                        that._trigger('chunkdone', null, o);
52988                        that._trigger('chunkalways', null, o);
52989                        if (ub < fs) {
52990                            // File upload not yet complete,
52991                            // continue with the next chunk:
52992                            upload();
52993                        } else {
52994                            dfd.resolveWith(
52995                                o.context,
52996                                [result, textStatus, jqXHR]
52997                            );
52998                        }
52999                    })
53000                    .fail(function (jqXHR, textStatus, errorThrown) {
53001                        o.jqXHR = jqXHR;
53002                        o.textStatus = textStatus;
53003                        o.errorThrown = errorThrown;
53004                        that._trigger('chunkfail', null, o);
53005                        that._trigger('chunkalways', null, o);
53006                        dfd.rejectWith(
53007                            o.context,
53008                            [jqXHR, textStatus, errorThrown]
53009                        );
53010                    });
53011            };
53012            this._enhancePromise(promise);
53013            promise.abort = function () {
53014                return jqXHR.abort();
53015            };
53016            upload();
53017            return promise;
53018        },
53019
53020        _beforeSend: function (e, data) {
53021            if (this._active === 0) {
53022                // the start callback is triggered when an upload starts
53023                // and no other uploads are currently running,
53024                // equivalent to the global ajaxStart event:
53025                this._trigger('start');
53026                // Set timer for global bitrate progress calculation:
53027                this._bitrateTimer = new this._BitrateTimer();
53028                // Reset the global progress values:
53029                this._progress.loaded = this._progress.total = 0;
53030                this._progress.bitrate = 0;
53031            }
53032            // Make sure the container objects for the .response() and
53033            // .progress() methods on the data object are available
53034            // and reset to their initial state:
53035            this._initResponseObject(data);
53036            this._initProgressObject(data);
53037            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
53038            data._progress.total = data.total = this._getTotal(data.files) || 1;
53039            data._progress.bitrate = data.bitrate = 0;
53040            this._active += 1;
53041            // Initialize the global progress values:
53042            this._progress.loaded += data.loaded;
53043            this._progress.total += data.total;
53044        },
53045
53046        _onDone: function (result, textStatus, jqXHR, options) {
53047            var total = options._progress.total,
53048                response = options._response;
53049            if (options._progress.loaded < total) {
53050                // Create a progress event if no final progress event
53051                // with loaded equaling total has been triggered:
53052                this._onProgress($.Event('progress', {
53053                    lengthComputable: true,
53054                    loaded: total,
53055                    total: total
53056                }), options);
53057            }
53058            response.result = options.result = result;
53059            response.textStatus = options.textStatus = textStatus;
53060            response.jqXHR = options.jqXHR = jqXHR;
53061            this._trigger('done', null, options);
53062        },
53063
53064        _onFail: function (jqXHR, textStatus, errorThrown, options) {
53065            var response = options._response;
53066            if (options.recalculateProgress) {
53067                // Remove the failed (error or abort) file upload from
53068                // the global progress calculation:
53069                this._progress.loaded -= options._progress.loaded;
53070                this._progress.total -= options._progress.total;
53071            }
53072            response.jqXHR = options.jqXHR = jqXHR;
53073            response.textStatus = options.textStatus = textStatus;
53074            response.errorThrown = options.errorThrown = errorThrown;
53075            this._trigger('fail', null, options);
53076        },
53077
53078        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
53079            // jqXHRorResult, textStatus and jqXHRorError are added to the
53080            // options object via done and fail callbacks
53081            this._trigger('always', null, options);
53082        },
53083
53084        _onSend: function (e, data) {
53085            if (!data.submit) {
53086                this._addConvenienceMethods(e, data);
53087            }
53088            var that = this,
53089                jqXHR,
53090                aborted,
53091                slot,
53092                pipe,
53093                options = that._getAJAXSettings(data),
53094                send = function () {
53095                    that._sending += 1;
53096                    // Set timer for bitrate progress calculation:
53097                    options._bitrateTimer = new that._BitrateTimer();
53098                    jqXHR = jqXHR || (
53099                        ((aborted || that._trigger(
53100                            'send',
53101                            $.Event('send', {delegatedEvent: e}),
53102                            options
53103                        ) === false) &&
53104                        that._getXHRPromise(false, options.context, aborted)) ||
53105                        that._chunkedUpload(options) || $.ajax(options)
53106                    ).done(function (result, textStatus, jqXHR) {
53107                        that._onDone(result, textStatus, jqXHR, options);
53108                    }).fail(function (jqXHR, textStatus, errorThrown) {
53109                        that._onFail(jqXHR, textStatus, errorThrown, options);
53110                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
53111                        that._onAlways(
53112                            jqXHRorResult,
53113                            textStatus,
53114                            jqXHRorError,
53115                            options
53116                        );
53117                        that._sending -= 1;
53118                        that._active -= 1;
53119                        if (options.limitConcurrentUploads &&
53120                                options.limitConcurrentUploads > that._sending) {
53121                            // Start the next queued upload,
53122                            // that has not been aborted:
53123                            var nextSlot = that._slots.shift();
53124                            while (nextSlot) {
53125                                if (that._getDeferredState(nextSlot) === 'pending') {
53126                                    nextSlot.resolve();
53127                                    break;
53128                                }
53129                                nextSlot = that._slots.shift();
53130                            }
53131                        }
53132                        if (that._active === 0) {
53133                            // The stop callback is triggered when all uploads have
53134                            // been completed, equivalent to the global ajaxStop event:
53135                            that._trigger('stop');
53136                        }
53137                    });
53138                    return jqXHR;
53139                };
53140            this._beforeSend(e, options);
53141            if (this.options.sequentialUploads ||
53142                    (this.options.limitConcurrentUploads &&
53143                    this.options.limitConcurrentUploads <= this._sending)) {
53144                if (this.options.limitConcurrentUploads > 1) {
53145                    slot = $.Deferred();
53146                    this._slots.push(slot);
53147                    pipe = slot.pipe(send);
53148                } else {
53149                    this._sequence = this._sequence.pipe(send, send);
53150                    pipe = this._sequence;
53151                }
53152                // Return the piped Promise object, enhanced with an abort method,
53153                // which is delegated to the jqXHR object of the current upload,
53154                // and jqXHR callbacks mapped to the equivalent Promise methods:
53155                pipe.abort = function () {
53156                    aborted = [undefined, 'abort', 'abort'];
53157                    if (!jqXHR) {
53158                        if (slot) {
53159                            slot.rejectWith(options.context, aborted);
53160                        }
53161                        return send();
53162                    }
53163                    return jqXHR.abort();
53164                };
53165                return this._enhancePromise(pipe);
53166            }
53167            return send();
53168        },
53169
53170        _onAdd: function (e, data) {
53171            var that = this,
53172                result = true,
53173                options = $.extend({}, this.options, data),
53174                files = data.files,
53175                filesLength = files.length,
53176                limit = options.limitMultiFileUploads,
53177                limitSize = options.limitMultiFileUploadSize,
53178                overhead = options.limitMultiFileUploadSizeOverhead,
53179                batchSize = 0,
53180                paramName = this._getParamName(options),
53181                paramNameSet,
53182                paramNameSlice,
53183                fileSet,
53184                i,
53185                j = 0;
53186            if (!filesLength) {
53187                return false;
53188            }
53189            if (limitSize && files[0].size === undefined) {
53190                limitSize = undefined;
53191            }
53192            if (!(options.singleFileUploads || limit || limitSize) ||
53193                    !this._isXHRUpload(options)) {
53194                fileSet = [files];
53195                paramNameSet = [paramName];
53196            } else if (!(options.singleFileUploads || limitSize) && limit) {
53197                fileSet = [];
53198                paramNameSet = [];
53199                for (i = 0; i < filesLength; i += limit) {
53200                    fileSet.push(files.slice(i, i + limit));
53201                    paramNameSlice = paramName.slice(i, i + limit);
53202                    if (!paramNameSlice.length) {
53203                        paramNameSlice = paramName;
53204                    }
53205                    paramNameSet.push(paramNameSlice);
53206                }
53207            } else if (!options.singleFileUploads && limitSize) {
53208                fileSet = [];
53209                paramNameSet = [];
53210                for (i = 0; i < filesLength; i = i + 1) {
53211                    batchSize += files[i].size + overhead;
53212                    if (i + 1 === filesLength ||
53213                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
53214                            (limit && i + 1 - j >= limit)) {
53215                        fileSet.push(files.slice(j, i + 1));
53216                        paramNameSlice = paramName.slice(j, i + 1);
53217                        if (!paramNameSlice.length) {
53218                            paramNameSlice = paramName;
53219                        }
53220                        paramNameSet.push(paramNameSlice);
53221                        j = i + 1;
53222                        batchSize = 0;
53223                    }
53224                }
53225            } else {
53226                paramNameSet = paramName;
53227            }
53228            data.originalFiles = files;
53229            $.each(fileSet || files, function (index, element) {
53230                var newData = $.extend({}, data);
53231                newData.files = fileSet ? element : [element];
53232                newData.paramName = paramNameSet[index];
53233                that._initResponseObject(newData);
53234                that._initProgressObject(newData);
53235                that._addConvenienceMethods(e, newData);
53236                result = that._trigger(
53237                    'add',
53238                    $.Event('add', {delegatedEvent: e}),
53239                    newData
53240                );
53241                return result;
53242            });
53243            return result;
53244        },
53245
53246        _replaceFileInput: function (data) {
53247            var input = data.fileInput,
53248                inputClone = input.clone(true);
53249            // Add a reference for the new cloned file input to the data argument:
53250            data.fileInputClone = inputClone;
53251            $('<form></form>').append(inputClone)[0].reset();
53252            // Detaching allows to insert the fileInput on another form
53253            // without loosing the file input value:
53254            input.after(inputClone).detach();
53255            // Avoid memory leaks with the detached file input:
53256            $.cleanData(input.unbind('remove'));
53257            // Replace the original file input element in the fileInput
53258            // elements set with the clone, which has been copied including
53259            // event handlers:
53260            this.options.fileInput = this.options.fileInput.map(function (i, el) {
53261                if (el === input[0]) {
53262                    return inputClone[0];
53263                }
53264                return el;
53265            });
53266            // If the widget has been initialized on the file input itself,
53267            // override this.element with the file input clone:
53268            if (input[0] === this.element[0]) {
53269                this.element = inputClone;
53270            }
53271        },
53272
53273        _handleFileTreeEntry: function (entry, path) {
53274            var that = this,
53275                dfd = $.Deferred(),
53276                errorHandler = function (e) {
53277                    if (e && !e.entry) {
53278                        e.entry = entry;
53279                    }
53280                    // Since $.when returns immediately if one
53281                    // Deferred is rejected, we use resolve instead.
53282                    // This allows valid files and invalid items
53283                    // to be returned together in one set:
53284                    dfd.resolve([e]);
53285                },
53286                successHandler = function (entries) {
53287                    that._handleFileTreeEntries(
53288                        entries,
53289                        path + entry.name + '/'
53290                    ).done(function (files) {
53291                        dfd.resolve(files);
53292                    }).fail(errorHandler);
53293                },
53294                readEntries = function () {
53295                    dirReader.readEntries(function (results) {
53296                        if (!results.length) {
53297                            successHandler(entries);
53298                        } else {
53299                            entries = entries.concat(results);
53300                            readEntries();
53301                        }
53302                    }, errorHandler);
53303                },
53304                dirReader, entries = [];
53305            path = path || '';
53306            if (entry.isFile) {
53307                if (entry._file) {
53308                    // Workaround for Chrome bug #149735
53309                    entry._file.relativePath = path;
53310                    dfd.resolve(entry._file);
53311                } else {
53312                    entry.file(function (file) {
53313                        file.relativePath = path;
53314                        dfd.resolve(file);
53315                    }, errorHandler);
53316                }
53317            } else if (entry.isDirectory) {
53318                dirReader = entry.createReader();
53319                readEntries();
53320            } else {
53321                // Return an empy list for file system items
53322                // other than files or directories:
53323                dfd.resolve([]);
53324            }
53325            return dfd.promise();
53326        },
53327
53328        _handleFileTreeEntries: function (entries, path) {
53329            var that = this;
53330            return $.when.apply(
53331                $,
53332                $.map(entries, function (entry) {
53333                    return that._handleFileTreeEntry(entry, path);
53334                })
53335            ).pipe(function () {
53336                return Array.prototype.concat.apply(
53337                    [],
53338                    arguments
53339                );
53340            });
53341        },
53342
53343        _getDroppedFiles: function (dataTransfer) {
53344            dataTransfer = dataTransfer || {};
53345            var items = dataTransfer.items;
53346            if (items && items.length && (items[0].webkitGetAsEntry ||
53347                    items[0].getAsEntry)) {
53348                return this._handleFileTreeEntries(
53349                    $.map(items, function (item) {
53350                        var entry;
53351                        if (item.webkitGetAsEntry) {
53352                            entry = item.webkitGetAsEntry();
53353                            if (entry) {
53354                                // Workaround for Chrome bug #149735:
53355                                entry._file = item.getAsFile();
53356                            }
53357                            return entry;
53358                        }
53359                        return item.getAsEntry();
53360                    })
53361                );
53362            }
53363            return $.Deferred().resolve(
53364                $.makeArray(dataTransfer.files)
53365            ).promise();
53366        },
53367
53368        _getSingleFileInputFiles: function (fileInput) {
53369            fileInput = $(fileInput);
53370            var entries = fileInput.prop('webkitEntries') ||
53371                    fileInput.prop('entries'),
53372                files,
53373                value;
53374            if (entries && entries.length) {
53375                return this._handleFileTreeEntries(entries);
53376            }
53377            files = $.makeArray(fileInput.prop('files'));
53378            if (!files.length) {
53379                value = fileInput.prop('value');
53380                if (!value) {
53381                    return $.Deferred().resolve([]).promise();
53382                }
53383                // If the files property is not available, the browser does not
53384                // support the File API and we add a pseudo File object with
53385                // the input value as name with path information removed:
53386                files = [{name: value.replace(/^.*\\/, '')}];
53387            } else if (files[0].name === undefined && files[0].fileName) {
53388                // File normalization for Safari 4 and Firefox 3:
53389                $.each(files, function (index, file) {
53390                    file.name = file.fileName;
53391                    file.size = file.fileSize;
53392                });
53393            }
53394            return $.Deferred().resolve(files).promise();
53395        },
53396
53397        _getFileInputFiles: function (fileInput) {
53398            if (!(fileInput instanceof $) || fileInput.length === 1) {
53399                return this._getSingleFileInputFiles(fileInput);
53400            }
53401            return $.when.apply(
53402                $,
53403                $.map(fileInput, this._getSingleFileInputFiles)
53404            ).pipe(function () {
53405                return Array.prototype.concat.apply(
53406                    [],
53407                    arguments
53408                );
53409            });
53410        },
53411
53412        _onChange: function (e) {
53413            var that = this,
53414                data = {
53415                    fileInput: $(e.target),
53416                    form: $(e.target.form)
53417                };
53418            this._getFileInputFiles(data.fileInput).always(function (files) {
53419                data.files = files;
53420                if (that.options.replaceFileInput) {
53421                    that._replaceFileInput(data);
53422                }
53423                if (that._trigger(
53424                        'change',
53425                        $.Event('change', {delegatedEvent: e}),
53426                        data
53427                    ) !== false) {
53428                    that._onAdd(e, data);
53429                }
53430            });
53431        },
53432
53433        _onPaste: function (e) {
53434            var items = e.originalEvent && e.originalEvent.clipboardData &&
53435                    e.originalEvent.clipboardData.items,
53436                data = {files: []};
53437            if (items && items.length) {
53438                $.each(items, function (index, item) {
53439                    var file = item.getAsFile && item.getAsFile();
53440                    if (file) {
53441                        data.files.push(file);
53442                    }
53443                });
53444                if (this._trigger(
53445                        'paste',
53446                        $.Event('paste', {delegatedEvent: e}),
53447                        data
53448                    ) !== false) {
53449                    this._onAdd(e, data);
53450                }
53451            }
53452        },
53453
53454        _onDrop: function (e) {
53455            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
53456            var that = this,
53457                dataTransfer = e.dataTransfer,
53458                data = {};
53459            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
53460                e.preventDefault();
53461                this._getDroppedFiles(dataTransfer).always(function (files) {
53462                    data.files = files;
53463                    if (that._trigger(
53464                            'drop',
53465                            $.Event('drop', {delegatedEvent: e}),
53466                            data
53467                        ) !== false) {
53468                        that._onAdd(e, data);
53469                    }
53470                });
53471            }
53472        },
53473
53474        _onDragOver: getDragHandler('dragover'),
53475
53476        _onDragEnter: getDragHandler('dragenter'),
53477
53478        _onDragLeave: getDragHandler('dragleave'),
53479
53480        _initEventHandlers: function () {
53481            if (this._isXHRUpload(this.options)) {
53482                this._on(this.options.dropZone, {
53483                    dragover: this._onDragOver,
53484                    drop: this._onDrop,
53485                    // event.preventDefault() on dragenter is required for IE10+:
53486                    dragenter: this._onDragEnter,
53487                    // dragleave is not required, but added for c
53487ompleteness:
53488                    dragleave: this._onDragLeave
53489                });
53490                this._on(this.options.pasteZone, {
53491                    paste: this._onPaste
53492                });
53493            }
53494            if ($.support.fileInput) {
53495                this._on(this.options.fileInput, {
53496                    change: this._onChange
53497                });
53498            }
53499        },
53500
53501        _destroyEventHandlers: function () {
53502            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
53503            this._off(this.options.pasteZone, 'paste');
53504            this._off(this.options.fileInput, 'change');
53505        },
53506
53507        _setOption: function (key, value) {
53508            var reinit = $.inArray(key, this._specialOptions) !== -1;
53509            if (reinit) {
53510                this._destroyEventHandlers();
53511            }
53512            this._super(key, value);
53513            if (reinit) {
53514                this._initSpecialOptions();
53515                this._initEventHandlers();
53516            }
53517        },
53518
53519        _initSpecialOptions: function () {
53520            var options = this.options;
53521            if (options.fileInput === undefined) {
53522                options.fileInput = this.element.is('input[type="file"]') ?
53523                        this.element : this.element.find('input[type="file"]');
53524            } else if (!(options.fileInput instanceof $)) {
53525                options.fileInput = $(options.fileInput);
53526            }
53527            if (!(options.dropZone instanceof $)) {
53528                options.dropZone = $(options.dropZone);
53529            }
53530            if (!(options.pasteZone instanceof $)) {
53531                options.pasteZone = $(options.pasteZone);
53532            }
53533        },
53534
53535        _getRegExp: function (str) {
53536            var parts = str.split('/'),
53537                modifiers = parts.pop();
53538            parts.shift();
53539            return new RegExp(parts.join('/'), modifiers);
53540        },
53541
53542        _isRegExpOption: function (key, value) {
53543            return key !== 'url' && $.type(value) === 'string' &&
53544                /^\/.*\/[igm]{0,3}$/.test(value);
53545        },
53546
53547        _initDataAttributes: function () {
53548            var that = this,
53549                options = this.options,
53550                data = this.element.data();
53551            // Initialize options set via HTML5 data-attributes:
53552            $.each(
53553                this.element[0].attributes,
53554                function (index, attr) {
53555                    var key = attr.name.toLowerCase(),
53556                        value;
53557                    if (/^data-/.test(key)) {
53558                        // Convert hyphen-ated key to camelCase:
53559                        key = key.slice(5).replace(/-[a-z]/g, function (str) {
53560                            return str.charAt(1).toUpperCase();
53561                        });
53562                        value = data[key];
53563                        if (that._isRegExpOption(key, value)) {
53564                            value = that._getRegExp(value);
53565                        }
53566                        options[key] = value;
53567                    }
53568                }
53569            );
53570        },
53571
53572        _create: function () {
53573            this._initDataAttributes();
53574            this._initSpecialOptions();
53575            this._slots = [];
53576            this._sequence = this._getXHRPromise(true);
53577            this._sending = this._active = 0;
53578            this._initProgressObject(this);
53579            this._initEventHandlers();
53580        },
53581
53582        // This method is exposed to the widget API and allows to query
53583        // the number of active uploads:
53584        active: function () {
53585            return this._active;
53586        },
53587
53588        // This method is exposed to the widget API and allows to query
53589        // the widget upload progress.
53590        // It returns an object with loaded, total and bitrate properties
53591        // for the running uploads:
53592        progress: function () {
53593            return this._progress;
53594        },
53595
53596        // This method is exposed to the widget API and allows adding files
53597        // using the fileupload API. The data parameter accepts an object which
53598        // must have a files property and can contain additional options:
53599        // .fileupload('add', {files: filesList});
53600        add: function (data) {
53601            var that = this;
53602            if (!data || this.options.disabled) {
53603                return;
53604            }
53605            if (data.fileInput && !data.files) {
53606                this._getFileInputFiles(data.fileInput).always(function (files) {
53607                    data.files = files;
53608                    that._onAdd(null, data);
53609                });
53610            } else {
53611                data.files = $.makeArray(data.files);
53612                this._onAdd(null, data);
53613            }
53614        },
53615
53616        // This method is exposed to the widget API and allows sending files
53617        // using the fileupload API. The data parameter accepts an object which
53618        // must have a files or fileInput property and can contain additional options:
53619        // .fileupload('send', {files: filesList});
53620        // The method returns a Promise object for the file upload call.
53621        send: function (data) {
53622            if (data && !this.options.disabled) {
53623                if (data.fileInput && !data.files) {
53624                    var that = this,
53625                        dfd = $.Deferred(),
53626                        promise = dfd.promise(),
53627                        jqXHR,
53628                        aborted;
53629                    promise.abort = function () {
53630                        aborted = true;
53631                        if (jqXHR) {
53632                            return jqXHR.abort();
53633                        }
53634                        dfd.reject(null, 'abort', 'abort');
53635                        return promise;
53636                    };
53637                    this._getFileInputFiles(data.fileInput).always(
53638                        function (files) {
53639                            if (aborted) {
53640                                return;
53641                            }
53642                            if (!files.length) {
53643                                dfd.reject();
53644                                return;
53645                            }
53646                            data.files = files;
53647                            jqXHR = that._onSend(null, data);
53648                            jqXHR.then(
53649                                function (result, textStatus, jqXHR) {
53650                                    dfd.resolve(result, textStatus, jqXHR);
53651                                },
53652                                function (jqXHR, textStatus, errorThrown) {
53653                                    dfd.reject(jqXHR, textStatus, errorThrown);
53654                                }
53655                            );
53656                        }
53657                    );
53658                    return this._enhancePromise(promise);
53659                }
53660                data.files = $.makeArray(data.files);
53661                if (data.files.length) {
53662                    return this._onSend(null, data);
53663                }
53664            }
53665            return this._getXHRPromise(false, data && data.context);
53666        }
53667
53668    });
53669
53670}));
53671// This COPIES app/javascript/scripts/utils/time_parser.js
53672// ... with a two modifications:
53673//
53674// - It relies on rails-assets-moment-timezone (not package.js)
53675// - It doesn't use 'export default' (not supported by sprockets)
53676//
53677//
53678// To re-import time_parser.js:
53679//
53680// 1. Copy the contents of that file below
53681// 2. Delete everything before "class TimeParser" and rename to "class TimeParserLegacy"
53682//    (specifically "import ..." and "export default")
53683//
53684
53685class TimeParserLegacy {
53686  constructor() {
53687    if (!window.localTimezone) {
53688      window.localTimezone = moment.tz.guess();
53689    }
53690    this.singleFormat = !!window.timeParserSingleFormat;
53691    this.localTimezone = window.localTimezone;
53692    moment.tz.setDefault(this.localTimezone);
53693    this.yesterdayStart = moment().subtract(1, "day").startOf("day");
53694    this.todayStart = moment().startOf("day");
53695    this.todayEnd = moment().endOf("day");
53696    this.tomorrowEnd = moment().add(1, "day").endOf("day");
53697    this.todayYear = moment().year();
53698  }
53699
53700  // Directly render localized time elements. Returns an HTML string
53701  localizedTimeHtml(
53702    timeString,
53703    { singleFormat, preciseTime, includeSeconds, withPreposition }
53704  ) {
53705    const time = this.parse(String(timeString).trim());
53706
53707    if (time === null) {
53708      return `<span></span>`;
53709    }
53710    // If singleFormat was passed as true, override with that, otherwise default to window format
53711    let variableFormat = singleFormat ? false : !this.singleFormat;
53712
53713    return `<span title="${this.preciseTimeSeconds(
53714      time
53715    )}">${this.localizedDateText(
53716      time,
53717      !variableFormat,
53718      preciseTime,
53719      includeSeconds,
53720      withPreposition
53721    )}</span>`;
53722  }
53723
53724  // Update all the times (and timezones) on the page
53725  // Removes the classes that trigger localization, so it doesn't reupdate the times
53726  localize() {
53727    // Write times
53728    Array.from(document.getElementsByClassName("convertTime")).forEach((el) =>
53729      this.writeTime(el)
53730    );
53731
53732    // Write timezones
53733    Array.from(
53734      document.getElementsByClassName("convertTimezone")
53735    ).forEach((el) => this.writeTimezone(el));
53736
53737    // Write hidden timezone fields - so if we're submitting a form, it includes the current timezone
53738    Array.from(
53739      document.getElementsByClassName("hiddenFieldTimezone")
53740    ).forEach((el) => this.setHiddenTimezoneFields(el));
53741
53742    // Write local time in fields
53743    Array.from(
53744      document.getElementsByClassName("dateInputUpdateZone")
53745    ).forEach((el) => this.setDateInputField(el));
53746  }
53747
53748  // ---------
53749  // Methods below here are internal methods
53750  // ---------
53751
53752  // Update an element with the current time.
53753  // Requires the element have parseable text of a time, pulls properties from the element classes
53754  writeTime(el) {
53755    const text = el.textContent.trim();
53756    const time = this.parse(text);
53757    // So running this again doesn't reapply to this element
53758    el.classList.remove("convertTime");
53759    // So we know which were updated (for styling, future updates, etc)
53760    el.classList.add("convertedTime");
53761
53762    // If we couldn't parse the time, exit
53763    if (!(text.length > 0) || time === null) {
53764      return;
53765    }
53766    el.innerHTML = this.localizedDateText(
53767      time,
53768      // If the window has singleFormat, then it should be single format - unless the element has variableFormat class
53769      this.singleFormat ? !el.classList.contains("variableFormat") : false,
53770      el.classList.contains("preciseTime"),
53771      el.classList.contains("preciseTimeSeconds"),
53772      el.classList.contains("withPreposition")
53773    );
53774    el.setAttribute("title", this.preciseTimeSeconds(time));
53775  }
53776
53777  // If we're display time with the hour, we have different formats based on whether we include seconds
53778  // this manages that functionality
53779  hourFormat(time, baseTimeFormat, includeSeconds, withPreposition) {
53780    const prefix = withPreposition ? " at " : "";
53781    if (includeSeconds) {
53782      return `${prefix}${time.format(baseTimeFormat)}:<small>${time.format(
53783        "ss"
53784      )}</small> ${time.format("a")}`;
53785    } else {
53786      return prefix + time.format(`${baseTimeFormat}a`);
53787    }
53788  }
53789
53790  localizedDateText(
53791    time,
53792    singleFormat,
53793    preciseTime,
53794    includeSeconds,
53795    withPreposition
53796  ) {
53797    let prefix = "";
53798    // If we're doing inconsistent formatting, add a prefix if we're dealing with yesterday or today (not the future)
53799    if (
53800      !singleFormat &&
53801      time < this.tomorrowEnd &&
53802      time > this.yesterdayStart
53803    ) {
53804      // If we're dealing with yesterday or tomorrow, we prepend that
53805      if (time < this.todayStart) {
53806        prefix = "Yesterday ";
53807      } else if (time > this.todayEnd) {
53808        prefix = "Tomorrow ";
53809      }
53810      return (
53811        prefix + this.hourFormat(time, "h:mm", includeSeconds, withPreposition)
53812      );
53813    }
53814    if (withPreposition) {
53815      prefix = "on ";
53816    }
53817
53818    // If it's preciseTime (or preciseTimeSeconds), always show the hours and mins
53819    if (preciseTime || includeSeconds) {
53820      // Make the time less-strong, otherwise it's hard to separate from the date
53821      let hourEl = `<span class="less-strong">${this.hourFormat(
53822        time,
53823        "h:mm",
53824        includeSeconds,
53825        withPreposition
53826      )}</span>`;
53827      // Only show the year if it isn't this year
53828      if (singleFormat || time.year() - this.todayYear !== 0) {
53829        return prefix + time.format("YYYY-MM-DD ") + hourEl;
53830      } else {
53831        return prefix + time.format("MMM Do ") + hourEl;
53832      }
53833    }
53834    // Otherwise, format in basic format
53835    if (singleFormat || time.year() - this.todayYear !== 0) {
53836      return prefix + time.format("YYYY-MM-DD");
53837    } else {
53838      if (withPreposition) {
53839        return prefix + time.format("MMM Do");
53840      } else {
53841        return prefix + time.format("MMM Do");
53842      }
53843    }
53844  }
53845
53846  preciseTimeSeconds(time) {
53847    return time.format("YYYY-MM-DD h:mm:ss a");
53848  }
53849
53850  setHiddenTimezoneFields(el) {
53851    el.value = this.localTimezone;
53852  }
53853
53854  setDateInputField(el) {
53855    const text = el.getAttribute("data-initialtime")
53856    if (text.length > 0) {
53857      // Format that at least Chrome expects for field
53858      el.value = moment(text, moment.ISO_8601).format("YYYY-MM-DDTHH:mm")
53859    }
53860  }
53861
53862  parse(text) {
53863    // If time is only a number, parse as a timestamp
53864    // Otherwise, parse as ISO_8601 which is the default time string
53865    if (/^\d+$/.test(text)) {
53866      return moment.unix(text);
53867    } else if (text !== null) {
53868      return moment(text, moment.ISO_8601);
53869    }
53870    if (text === null || !time.isValid()) {
53871      return null;
53872    }
53873  }
53874
53875  writeTimezone(el) {
53876    el.textContent = moment().format("z");
53877    el.classList.remove("convertTimezone");
53878  }
53879};
53880(function() {
53881  var BikeIndexInitClass, bikeIndexInit, enableEscapeForModals, initializeBikeIndex, lastInitializedPageId, renderDonationModal, warnIfUnsupportedBrowser,
53882    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
53883    hasProp = {}.hasOwnProperty;
53884
53885  if (!String.prototype.trim) {
53886    String.prototype.trim = function() {
53887      return this.replace(/^\s+|\s+$/g, "");
53888    };
53889  }
53890
53891  window.BikeIndex = (function() {
53892    function BikeIndex() {}
53893
53894    BikeIndex.prototype.loadFancySelects = function() {
53895      if (!$.fn.selectize) {
53896        return;
53897      }
53898      $(".unfancy.fancy-select.no-restore-on-backspace select").selectize({
53899        create: false,
53900        selectOnTab: true,
53901        plugins: []
53902      });
53903      $('.unfancy.fancy-select select').selectize({
53904        create: false,
53905        selectOnTab: true,
53906        plugins: ['restore_on_backspace']
53907      });
53908      $('.unfancy.fancy-select-placeholder select').selectize({
53909        create: false,
53910        selectOnTab: true,
53911        plugins: ['restore_on_backspace', 'selectable_placeholder']
53912      });
53913      return $('.unfancy.fancy-select, .unfancy.fancy-select-placeholder').removeClass('unfancy');
53914    };
53915
53916    return BikeIndex;
53917
53918  })();
53919
53920  BikeIndex.Init = (function(superClass) {
53921    extend(Init, superClass);
53922
53923    function Init() {
53924      this.loadFancySelects();
53925      this.initializeNoTabLinks();
53926      this.initializeScrollToRef();
53927      window.BikeIndexAlerts = new window.Alerts;
53928      this.loadPageScript(document.getElementsByTagName('body')[0].id);
53929      if ($('.organized-body').length > 0) {
53930        new BikeIndex.Organized;
53931      }
53932      this.localizeTimes();
53933      this.enableFullscreenOverflow();
53934    }
53935
53936    Init.prototype.loadPageScript = function(body_id) {
53937      var pageClasses;
53938      if (body_id.match('landing_pages_')) {
53939        return window.pageScript = new BikeIndex.LandingPage;
53940      }
53941      if (body_id.match('bikes_theft_alerts')) {
53942        return window.pageScript = new BikeIndex.BikesEdit;
53943      }
53944      body_id = body_id.replace(/_create$/g, '_new').replace(/_update$/g, '_edit');
53945      pageClasses = {
53946        welcome_index: BikeIndex.WelcomeIndex,
53947        news_show: BikeIndex.WelcomeIndex,
53948        welcome_recovery_stories: BikeIndex.WelcomeRecoveryStories,
53949        info_where: BikeIndex.InfoWhere,
53950        info_donate: BikeIndex.Payments,
53951        payments_new: BikeIndex.Payments,
53952        bikes_new: BikeIndex.BikesNew,
53953        bikes_edits_show: BikeIndex.BikesEdit,
53954        bikes_edit: BikeIndex.BikesEdit,
53955        bike_versions_edits_show: BikeIndex.BikesEdit,
53956        bike_versions_edit: BikeIndex.BikesEdit,
53957        bikes_show: BikeIndex.BikesShow,
53958        bike_versions_show: BikeIndex.BikesShow,
53959        bikes_index: BikeIndex.BikesIndex,
53960        bike_versions_index: BikeIndex.BikesIndex,
53961        orgpublic_impounded_bikes_index: BikeIndex.BikesIndex,
53962        organized_graduated_notifications_index: BikeIndex.BikesIndex,
53963        my_accounts_edit: BikeIndex.UsersEdit,
53964        my_account_show: BikeIndex.UserHome,
53965        welcome_choose_registration: BikeIndex.ChooseRegistration,
53966        organized_manage_locations: BikeIndex.OrganizedManageLocations,
53967        organizations_new: BikeIndex.OrganizedManageLocations,
53968        organized_manage_show: BikeIndex.OrganizedManageLocations,
53969        locks_new: BikeIndex.LocksForm,
53970        locks_edit: BikeIndex.LocksForm,
53971        stolen_bike_listings_index: BikeIndex.StolenBikeListing
53972      };
53973      if (Object.keys(pageClasses).includes(body_id)) {
53974        return window.pageScript = new pageClasses[body_id];
53975      }
53976    };
53977
53978    Init.prototype.initializeNoTabLinks = function() {
53979      return $('.no-tab').click(function(e) {
53980        var $target, local;
53981        e.preventDefault();
53982        $target = $(e.target);
53983        local = $target.attr('data-target');
53984        if ($target.hasClass('same-window')) {
53985          return window.location = local;
53986        } else {
53987          return window.open(local, '_blank');
53988        }
53989      });
53990    };
53991
53992    Init.prototype.initializeScrollToRef = function() {
53993      return $('.scroll-to-ref').click(function(e) {
53994        var $target, offset;
53995        e.preventDefault();
53996        $target = $(event.target);
53997        offset = $target.attr('data-offset');
53998        if (offset != null) {
53999          offset = parseInt(offset, 10);
54000        }
54001        offset || (offset = -80);
54002        $('body, html').animate({
54003          scrollTop: $($target.attr('href')).offset().top + offset
54004        }, 'fast');
54005        return history.replaceState({}, "", "" + location.pathname + ($target.attr('href')));
54006      });
54007    };
54008
54009    Init.prototype.displayLocalDate = function(time, preciseTime, withPreposition) {
54010      var str;
54011      if (time < window.tomorrow) {
54012        if (time > window.today) {
54013          if (withPreposition) {
54014            return "at " + (time.format("h:mma"));
54015          } else {
54016            return time.format("h:mma");
54017          }
54018        } else if (time > window.yesterday) {
54019          return "Yesterday " + (time.format('h:mma'));
54020        }
54021      }
54022      if (time.year() === moment().year()) {
54023        str = preciseTime ? time.format("MMM Do[,] h:mma") : time.format("MMM Do[,] ha");
54024      } else {
54025        str = preciseTime ? time.format("YYYY-MM-DD h:mma") : time.format("YYYY-MM-DD");
54026      }
54027      if (withPreposition) {
54028        return "on " + str;
54029      } else {
54030        return str;
54031      }
54032    };
54033
54034    Init.prototype.localizeTimes = function() {
54035      window.timeParser || (window.timeParser = new TimeParserLegacy());
54036      return window.timeParser.localize();
54037    };
54038
54039    Init.prototype.enableFullscreenOverflow = function() {
54040      var pageWidth;
54041      pageWidth = $(window).width();
54042      return $('.full-screen-table table').each(function(index) {
54043        var $this;
54044        $this = $(this);
54045        if ($this.outerWidth() > pageWidth) {
54046          return $this.parents('.full-screen-table').addClass('full-screen-table-overflown');
54047        }
54048      });
54049    };
54050
54051    return Init;
54052
54053  })(BikeIndex);
54054
54055  warnIfUnsupportedBrowser = function() {
54056    var d, header;
54057    d = document.documentElement.style;
54058    if (!('flexWrap' in d || 'WebkitFlexWrap' in d || 'msFlexWrap' in d)) {
54059      if ($('#old-browser-warning').length < 1) {
54060        if (navigator.appName === 'Microsoft Internet Explorer' || !!(navigator.userAgent.match(/Trident/) || navigator.userAgent.match(/rv 11/)) || $.browser && $.browser.msie === 1) {
54061          header = 'Your browser (Internet Explorer) is is not supported';
54062        } else {
54063          header = 'Your browser is out of date!';
54064        }
54065        return $('body').prepend("<div id='old-browser-warning'><h4>" + header + "</h4><p>As a result, Bike Index will not function correctly. <a href=\"http://whatbrowser.com\">Learn more here</a>.</p></div>");
54066      }
54067    }
54068  };
54069
54070  enableEscapeForModals = function() {
54071    $('.modal').on('show.bs.modal', function() {
54072      $(window).on('keyup', function(e) {
54073        if (e.keyCode === 27) {
54074          return $('.modal').modal('hide');
54075        }
54076      });
54077      $(".modal .close").on("click", function(e) {
54078        return $(e.target).parents(".modal").modal("hide");
54079      });
54080      return true;
54081    });
54082    return $('.modal').on('hide.bs.modal', function() {
54083      $(window).off('keyup');
54084      return $(".modal .close").off;
54085    });
54086  };
54087
54088  renderDonationModal = function() {
54089    var email, hideModal, ref;
54090    hideModal = localStorage.getItem("hideDonationModal");
54091    if (hideModal !== "true") {
54092      email = (ref = $("#navUserSettingLink")) != null ? ref.attr("data-email") : void 0;
54093      if (email) {
54094        $("#new-payment-form #payment_email").val(email);
54095      }
54096      $("#donationModal").modal("show");
54097      new BikeIndex.Payments;
54098      return $("#donationModal").on('hide.bs.modal', function() {
54099        return localStorage.setItem("hideDonationModal", "true");
54100      });
54101    }
54102  };
54103
54104  BikeIndexInitClass = BikeIndex.Init;
54105
54106  bikeIndexInit = null;
54107
54108  lastInitializedPageId = null;
54109
54110  initializeBikeIndex = function() {
54111    var pageId;
54112    pageId = document.body.id;
54113    if (pageId === lastInitializedPageId) {
54114      return;
54115    }
54116    if (bikeIndexInit != null) {
54117      bikeIndexInit.loadPageScript(pageId);
54118    } else {
54119      enableEscapeForModals();
54120      bikeIndexInit = new BikeIndexInitClass;
54121      window.BikeIndex.Init = bikeIndexInit;
54122      if (document.getElementById('binx_registration_widget')) {
54123        new window.ManufacturersSelect('#binx_registration_widget #b_param_manufacturer_id');
54124      }
54125      warnIfUnsupportedBrowser();
54126      if ($("#donationModal").length) {
54127        renderDonationModal();
54128      }
54129    }
54130    return lastInitializedPageId = pageId;
54131  };
54132
54133  $(document).ready(initializeBikeIndex);
54134
54135  $(document).on("turbo:load", initializeBikeIndex);
54136
54137}).call(this);
54138(function() {
54139  this.AdDisplayer = (function() {
54140    var ad_types, internalAds, ottalaus_url;
54141
54142    ad_types = [
54143      {
54144        kind: "skyscraper",
54145        klass: "ad300x600"
54146      }, {
54147        kind: "sm_rectangle",
54148        klass: "ad468x60"
54149      }
54150    ];
54151
54152    ottalaus_url = "https://ottalausinc.ca/";
54153
54154    internalAds = [
54155      {
54156        name: "ottalaus_300",
54157        kind: "skyscraper",
54158        href: ottalaus_url,
54159        body: "<img src=\"/ads/ottalaus-300.png\" alt=\"Ottalaus\">"
54160      }, {
54161        name: "ottalaus_468",
54162        kind: "sm_rectangle",
54163        href: ottalaus_url,
54164        body: "<img src=\"/ads/ottalaus-468.png\" alt=\"Ottalaus\">"
54165      }
54166    ];
54167
54168    AdDisplayer.prototype.shuffle = function(a) {
54169      var b;
54170      b = a.sort(function() {
54171        return 0.5 - Math.random();
54172      });
54173      return b.sort(function() {
54174        return 0.5 - Math.random();
54175      });
54176    };
54177
54178    function AdDisplayer() {
54179      var ad_type, adname, adsToRender, available, el, i, index, j, k, len, len1, len2, ref, ref1;
54180      this.renderedAds = [];
54181      adsToRender = this.shuffle(internalAds);
54182      for (i = 0, len = ad_types.length; i < len; i++) {
54183        ad_type = ad_types[i];
54184        available = adsToRender.filter(function(x) {
54185          return x.kind === ad_type.kind;
54186        });
54187        ref = document.querySelectorAll(".ad-binx." + ad_type.klass);
54188        for (index = j = 0, len1 = ref.length; j < len1; index = ++j) {
54189          el = ref[index];
54190          this.renderedAds.push(this.renderAdElement(el, available[index]));
54191        }
54192      }
54193      this.renderedAds = this.renderedAds.filter(function(x) {
54194        return x !== void 0;
54195      });
54196      if (window.ga) {
54197        ref1 = this.renderedAds;
54198        for (k = 0, len2 = ref1.length; k < len2; k++) {
54199          adname = ref1[k];
54200          window.ga("send", {
54201            hitType: "event",
54202            eventCategory: "advertisement",
54203            eventAction: "ad-load",
54204            eventLabel: "" + adname
54205          });
54206          $("#binxad-" + adname).click(function(e) {
54207            return window.ga("send", {
54208              hitType: "event",
54209              eventCategory: "advertisement",
54210              eventAction: "ad-click",
54211              eventLabel: "" + adname
54212            });
54213          });
54214        }
54215      }
54216    }
54217
54218    AdDisplayer.prototype.renderAdElement = function(el, ad) {
54219      if (!(el.offsetWidth > 0 && el.offsetHeight > 0 && ad)) {
54220        return;
54221      }
54222      el.classList.add("rendered-ad");
54223      el.innerHTML = "<a href=\"" + ad.href + "\" id=\"binxad-" + ad.name + "\">" + ad.body + "</a>";
54224      return ad.name;
54225    };
54226
54227    return AdDisplayer;
54228
54229  })();
54230
54231}).call(this);
54232(function() {
54233  this.Alerts = (function() {
54234    function Alerts() {
54235      this.fadeOutAlerts();
54236      this.displayStoredAlerts();
54237    }
54238
54239    Alerts.prototype.add = function(alert_type, alert_body, callback) {
54240      if (alert_type == null) {
54241        alert_type = 'error';
54242      }
54243      if (alert_body == null) {
54244        alert_body = '';
54245      }
54246      if (callback == null) {
54247        callback = false;
54248      }
54249      if (callback) {
54250        return this.storeAlert(alert_type, alert_body, callback);
54251      } else {
54252        return this.displayAlert(alert_type, alert_body);
54253      }
54254    };
54255
54256    Alerts.prototype.alertWrapperClass = function() {
54257      if ($(".modal.fade.in").length) {
54258        if (!$(".modal.fade.in .alert-wrapper").length) {
54259          $(".modal.fade.in .modal-content").append("<div class='modal-alert-wrapper'></div>");
54260        }
54261        return ".modal.fade.in .modal-alert-wrapper";
54262      } else {
54263        return ".primary-alert-block";
54264      }
54265    };
54266
54267    Alerts.prototype.displayAlert = function(alert_type, alert_body, seconds) {
54268      var alert_wrapper_class, attrs, template;
54269      if (seconds == null) {
54270        seconds = 7;
54271      }
54272      alert_wrapper_class = this.alertWrapperClass();
54273      $(alert_wrapper_class).removeClass('faded');
54274      template = $('#alert-template').html();
54275      attrs = {
54276        alert_type: alert_type,
54277        alert_body: alert_body,
54278        seconds: seconds
54279      };
54280      $(alert_wrapper_class).append(Mustache.render(template, attrs));
54281      return this.fadeOutAlerts();
54282    };
54283
54284    Alerts.prototype.fadeOutAlerts = function() {
54285      var $alert, alert, alert_wrapper_class, i, len, ref, results;
54286      alert_wrapper_class = this.alertWrapperClass();
54287      if ($(alert_wrapper_class + " .alert").length > 0) {
54288        ref = $(alert_wrapper_class + " .in");
54289        results = [];
54290        for (i = 0, len = ref.length; i < len; i++) {
54291          alert = ref[i];
54292          $alert = $(alert);
54293          if ($alert.data('seconds') > 0) {
54294            $alert.removeClass('in');
54295            results.push(this.fadeAlert($alert, $alert.attr('data-seconds')));
54296          } else if ($alert.hasClass('alert-success')) {
54297            $alert.removeClass('in');
54298            results.push(this.fadeAlert($alert, 10));
54299          } else {
54300            results.push(void 0);
54301          }
54302        }
54303        return results;
54304      } else {
54305        return $(alert_wrapper_class).addClass('faded');
54306      }
54307    };
54308
54309    Alerts.prototype.fadeAlert = function($alert, seconds) {
54310      var alert_wrapper_class;
54311      alert_wrapper_class = this.alertWrapperClass();
54312      return setTimeout((function() {
54313        return $alert.fadeOut('slow', function() {
54314          return $alert.slideUp('fast', function() {
54315            $alert.remove();
54316            if (!($(alert_wrapper_class + " .alert").length > 0)) {
54317              return $(alert_wrapper_class).addClass('faded');
54318            }
54319          });
54320        });
54321      }), seconds * 1000);
54322    };
54323
54324    Alerts.prototype.storeAlert = function(alert_type, alert_body, callback) {
54325      var stored_alert;
54326      stored_alert = {
54327        alert_type: alert_type,
54328        alert_body: alert_body
54329      };
54330      try {
54331        localStorage.setItem('stored_alert', JSON.stringify(stored_alert));
54332      } catch (error) {}
54333      return callback();
54334    };
54335
54336    Alerts.prototype.displayStoredAlerts = function() {
54337      var alert, stored_alert;
54338      stored_alert = (function() {
54339        try {
54340          return localStorage.getItem('stored_alert');
54341        } catch (error) {}
54342      })();
54343      if (stored_alert) {
54344        alert = JSON.parse(stored_alert);
54345        this.displayAlert(alert.alert_type, alert.alert_body);
54346        try {
54347          return localStorage.removeItem('stored_alert');
54348        } catch (error) {}
54349      }
54350    };
54351
54352    return Alerts;
54353
54354  })();
54355
54356}).call(this);
54357(function() {
54358  this.CheckEmail = (function() {
54359    var msg_selector;
54360
54361    msg_selector = 'email_check_message';
54362
54363    function CheckEmail(target_selector) {
54364      var $target;
54365      $target = $(target_selector);
54366      this.runMailcheck($target);
54367      this.initializeMailCheck($target);
54368    }
54369
54370    CheckEmail.prototype.initializeMailCheck = function($target) {
54371      return $target.on('blur', (function(_this) {
54372        return function(e) {
54373          $target.parents('.form-group').removeClass('has-warning');
54374          $("#" + msg_selector).slideUp('fast', function() {
54375            return $("#" + msg_selector).remove();
54376          });
54377          return _this.runMailcheck($target);
54378        };
54379      })(this));
54380    };
54381
54382    CheckEmail.prototype.runMailcheck = function($target) {
54383      return Mailcheck.run({
54384        email: $target.val(),
54385        suggested: (function(_this) {
54386          return function(result) {
54387            var msg;
54388            $target.parents('.form-group').addClass('has-warning');
54389            msg = "Did you mean <ins>" + result.full + "</ins> ?";
54390            $target.after("<div id='" + msg_selector + "'>" + msg + "</div>");
54391            $("#" + msg_selector).slideDown('fast');
54392            return $("#" + msg_selector).on('click', function(e) {
54393              $target.val($("#" + msg_selector + " ins").text());
54394              $("#" + msg_selector).slideUp('fast', function() {
54395                return $("#" + msg_selector).remove();
54396              });
54397              return $target.parents('.form-group').removeClass('has-warning');
54398            });
54399          };
54400        })(this)
54401      });
54402    };
54403
54404    return CheckEmail;
54405
54406  })();
54407
54408}).call(this);
54409(function() {
54410  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54411    hasProp = {}.hasOwnProperty;
54412
54413  BikeIndex.FormWell = (function(superClass) {
54414    extend(FormWell, superClass);
54415
54416    function FormWell() {
54417      var placement;
54418      new BikeIndex.OptionalFormUpdate;
54419      placement = this.popoverPlacement;
54420      $('[data-toggle="popover"]').popover({
54421        html: true,
54422        placement: placement
54423      });
54424    }
54425
54426    FormWell.prototype.popoverPlacement = function() {
54427      if (window.innerWidth < 544) {
54428        return 'left';
54429      } else {
54430        return 'top';
54431      }
54432    };
54433
54434    return FormWell;
54435
54436  })(BikeIndex);
54437
54438}).call(this);
54439(function() {
54440  this.FormWellMenu = (function() {
54441    function FormWellMenu() {
54442      $('form.primary-edit-bike-form, form.primary-edit-user-form').dirtyForms();
54443      if ($(window).width() > 767) {
54444        $('.primary-edit-form-well-menu').Stickyfill();
54445      }
54446      $('.form-well-edit-page-select select').change((function(_this) {
54447        return function(e) {
54448          return window.location.href = e.target.value;
54449        };
54450      })(this));
54451    }
54452
54453    return FormWellMenu;
54454
54455  })();
54456
54457}).call(this);
54458(function() {
54459  BikeIndex.GoogleTranslate = (function() {
54460    function GoogleTranslate(sourceLang, targetLang) {
54461      this.baseUrl = "https://translate.googleapis.com";
54462      this.sourceLang = sourceLang || I18n.defaultLocale;
54463      this.targetLang = targetLang || I18n.locale;
54464    }
54465
54466    GoogleTranslate.prototype.translate = function(text) {
54467      var path, query;
54468      path = "translate_a/single";
54469      query = ["client=gtx", "sl=" + this.sourceLang, "tl=" + this.targetLang, "dt=t", "q=" + (encodeURI(text))].join("&");
54470      return fetch(this.baseUrl + "/" + path + "?" + query).then((function(_this) {
54471        return function(resp) {
54472          return resp.json();
54473        };
54474      })(this)).then((function(_this) {
54475        return function(translations) {
54476          return translations[0][0][0];
54477        };
54478      })(this))["catch"]((function(_this) {
54479        return function(err) {
54480          return null;
54481        };
54482      })(this));
54483    };
54484
54485    return GoogleTranslate;
54486
54487  })();
54488
54489}).call(this);
54490(function() {
54491  this.ManufacturersSelect = (function() {
54492    var per_page;
54493
54494    per_page = 10;
54495
54496    function ManufacturersSelect(target_selector, frame_mnfg) {
54497      var $target, initial_opts;
54498      if (frame_mnfg == null) {
54499        frame_mnfg = true;
54500      }
54501      $target = $(target_selector);
54502      if (!$target.hasClass('unfancy')) {
54503        return true;
54504      }
54505      initial_opts = $target.data('initial') ? [$target.data('initial')] : [];
54506      $target.parents('.form-group').addClass('hide-selectize-dropdown-arrow');
54507      if (frame_mnfg) {
54508        this.makeFrameManufacturer($target, initial_opts);
54509      } else {
54510        this.makeComponentManufacturer($target, initial_opts);
54511      }
54512    }
54513
54514    ManufacturersSelect.prototype.selectizeSettings = function(url, initial_opts) {
54515      return {
54516        plugins: ['restore_on_backspace'],
54517        options: initial_opts,
54518        persist: false,
54519        create: false,
54520        maxItems: 1,
54521        selectOnTab: true,
54522        valueField: 'slug',
54523        labelField: 'text',
54524        searchField: 'text',
54525        loadThrottle: 130,
54526        score: function(search) {
54527          var score;
54528          score = this.getScoreFunction(search);
54529          return function(item) {
54530            return score(item) * (1 + Math.min(item.priority / 100, 1));
54531          };
54532        },
54533        load: function(query, callback) {
54534          return $.ajax({
54535            url: "" + url + (encodeURIComponent(query)),
54536            type: 'GET',
54537            error: function() {
54538              return callback();
54539            },
54540            success: function(res) {
54541              return callback(res.matches.slice(0, this.per_page));
54542            }
54543          });
54544        }
54545      };
54546    };
54547
54548    ManufacturersSelect.prototype.makeFrameManufacturer = function($target, initial_opts) {
54549      var url;
54550      url = "/api/autocomplete?per_page=" + per_page + "&categories=frame_mnfg&q=";
54551      $target.selectize(this.selectizeSettings(url, initial_opts));
54552      return $target.removeClass('unfancy');
54553    };
54554
54555    ManufacturersSelect.prototype.makeComponentManufacturer = function($target, initial_opts) {
54556      var component_selectize_opts, opts, url;
54557      url = "/api/autocomplete?per_page=" + per_page + "&categories=frame_mnfg,cmp_mnfg&q=";
54558      component_selectize_opts = {
54559        valueField: 'id'
54560      };
54561      opts = _.merge(this.selectizeSettings(url, initial_opts), component_selectize_opts);
54562      $target.selectize(opts);
54563      return $target.removeClass('unfancy');
54564    };
54565
54566    return ManufacturersSelect;
54567
54568  })();
54569
54570}).call(this);
54571(function() {
54572  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54573    hasProp = {}.hasOwnProperty;
54574
54575  BikeIndex.OptionalFormUpdate = (function(superClass) {
54576    extend(OptionalFormUpdate, superClass);
54577
54578    function OptionalFormUpdate() {
54579      var updateForm;
54580      updateForm = this.updateForm;
54581      $('a.optional-form-block').click(function(e, erase) {
54582        if (erase == null) {
54583          erase = true;
54584        }
54585        return updateForm(e, erase);
54586      });
54587    }
54588
54589    OptionalFormUpdate.prototype.updateForm = function(e, erase) {
54590      var $click_target, $swap, $target, action, selectize;
54591      e.preventDefault();
54592      $target = $(e.target);
54593      if (!$target.is('a')) {
54594        $target = $target.parents('.optional-form-block');
54595      }
54596      $click_target = $($target.attr('data-target'));
54597      $($target.attr('data-toggle')).show().removeClass('currently-hidden');
54598      $target.addClass('currently-hidden').hide();
54599      action = $target.attr('data-action');
54600      if (action === 'rm-block') {
54601        $click_target.slideUp('fast', function() {
54602          $click_target.removeClass('unhidden').addClass('currently-hidden');
54603          return setTimeout(function() {
54604            return $click_target.css('display', 'none');
54605          }, 50);
54606        });
54607      } else if (action === 'swap') {
54608        $swap = $($target.attr('data-swap'));
54609        $swap.slideUp('fast', function() {
54610          $click_target.fadeIn();
54611          $click_target.slideDown().addClass('unhidden').removeClass('currently-hidden');
54612          return $swap.addClass('currently-hidden').removeClass('unhidden');
54613        });
54614      } else {
54615        $click_target.slideDown('fast', function() {
54616          return $click_target.addClass('unhidden').removeClass('currently-hidden');
54617        });
54618      }
54619      if (erase) {
54620        selectize = $click_target.find('select').selectize()[0];
54621        if (selectize) {
54622          return selectize.selectize.setValue('');
54623        }
54624      }
54625    };
54626
54627    return OptionalFormUpdate;
54628
54629  })(BikeIndex);
54630
54631}).call(this);
54632(function() {
54633  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54634    hasProp = {}.hasOwnProperty;
54635
54636  BikeIndex.SubmitUserRequest = (function(superClass) {
54637    extend(SubmitUserRequest, superClass);
54638
54639    function SubmitUserRequest(data_hash, response_callback) {
54640      var url;
54641      $('.modal.in').modal('hide');
54642      url = "/api/v1/users/send_request";
54643      $.ajax({
54644        type: "POST",
54645        url: url,
54646        data: data_hash,
54647        success: function(data, textStatus, jqXHR) {
54648          return response_callback(data, true);
54649        },
54650        error: function(data, textStatus, jqXHR) {
54651          return response_callback(data, false);
54652        }
54653      });
54654    }
54655
54656    return SubmitUserRequest;
54657
54658  })(BikeIndex);
54659
54660}).call(this);
54661(function() {
54662  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54663    hasProp = {}.hasOwnProperty;
54664
54665  BikeIndex.ToggleHiddenOther = (function(superClass) {
54666    extend(ToggleHiddenOther, superClass);
54667
54668    function ToggleHiddenOther(target_input_selector, other_val) {
54669      var form_well_id, toggleOtherDisplay;
54670      form_well_id = $('.primary-edit-bike-form').prop('id');
54671      if (!form_well_id) {
54672        form_well_id = $('body > form').prop('id');
54673      }
54674      if (!form_well_id) {
54675        form_well_id = $("" + target_input_selector).parents('form').prop('id');
54676      }
54677      toggleOtherDisplay = this.toggleOtherDisplay;
54678      $("#" + form_well_id).on('change', target_input_selector, function(e) {
54679        return toggleOtherDisplay(e, other_val);
54680      });
54681    }
54682
54683    ToggleHiddenOther.prototype.toggleOtherDisplay = function(e, other_val) {
54684      var $other_field, $related, $shown_field, $target;
54685      $target = $(e.target);
54686      if (!$target.hasClass('form-control')) {
54687        return true;
54688      }
54689      $related = $target.parents('.related-fields');
54690      $other_field = $related.find('.hidden-other');
54691      $shown_field = $related.find('.shown-other');
54692      if (("" + ($target.val())) === ("" + other_val)) {
54693        $other_field.slideDown('fast', function() {
54694          return $other_field.addClass('unhidden').removeClass('currently-hidden');
54695        });
54696        return $shown_field.slideUp('fast', function() {
54697          $shown_field.removeClass('unhidden').addClass('currently-hidden');
54698          return $shown_field.find('.form-control').val('');
54699        });
54700      } else {
54701        $other_field.slideUp('fast', function() {
54702          $other_field.removeClass('unhidden').addClass('currently-hidden');
54703          return $other_field.find('.form-control').val('');
54704        });
54705        return $shown_field.slideDown('fast', function() {
54706          return $shown_field.addClass('unhidden').removeClass('currently-hidden');
54707        });
54708      }
54709    };
54710
54711    return ToggleHiddenOther;
54712
54713  })(BikeIndex);
54714
54715}).call(this);
54716(function() {
54717  this.UpdatePropulsionType = (function() {
54718    function UpdatePropulsionType(model_name) {
54719      this.updateTypes(model_name);
54720      $("#" + model_name + "_cycle_type").change((function(_this) {
54721        return function(e) {
54722          return _this.updateTypes(model_name);
54723        };
54724      })(this));
54725      $('#propulsion_type_motorized').change((function(_this) {
54726        return function(e) {
54727          return _this.updateTypes(model_name);
54728        };
54729      })(this));
54730      $('.modal').on('show.bs.modal', (function(_this) {
54731        return function() {
54732          return _this.updateTypes(model_name);
54733        };
54734      })(this));
54735    }
54736
54737    UpdatePropulsionType.prototype.updateTypes = function(model_name) {
54738      var cycleTypeValue, newTypeText;
54739      cycleTypeValue = $("#" + model_name + "_cycle_type").val();
54740      if (window.cycleTypesAlwaysMotorized.includes(cycleTypeValue)) {
54741        $('#propulsionTypeFields').collapse('hide');
54742        $('#propulsion_type_motorized').prop('checked', true);
54743        $('#propulsion_type_motorized').attr('disabled', true);
54744        $('#motorizedWrapper').addClass('less-strong cursor-not-allowed').removeClass('cursor-pointer');
54745      } else if (window.cycleTypesNeverMotorized.includes(cycleTypeValue)) {
54746        $('#propulsion_type_motorized').prop('checked', false);
54747        $('#propulsion_type_motorized').attr('disabled', true);
54748        $('#propulsionTypeFields').collapse('hide');
54749        $('#motorizedWrapper').addClass('less-strong cursor-not-allowed').removeClass('cursor-pointer');
54750      } else {
54751        $('#motorizedWrapper').addClass('cursor-pointer').removeClass('less-strong cursor-not-allowed');
54752        $('#propulsion_type_motorized').attr('disabled', false);
54753        if ($('#propulsion_type_motorized').prop('checked')) {
54754          if (window.cycleTypesPedals.includes(cycleTypeValue)) {
54755            $('#propulsionTypeFields').collapse('show');
54756          } else {
54757            $('#propulsionTypeFields').collapse('hide');
54758          }
54759        } else {
54760          $('#propulsionTypeFields').collapse('hide');
54761          $('#propulsion_type_throttle').prop('checked', false);
54762          $('#propulsion_type_pedal_assist').prop('checked', false);
54763        }
54764      }
54765      if (window.cycleTypeTranslations) {
54766        newTypeText = window.cycleTypeTranslations[cycleTypeValue];
54767        if (newTypeText.length) {
54768          $(".cycleTypeText").text(newTypeText);
54769        }
54770        if (window.cycleTypesNot.includes(cycleTypeValue)) {
54771          $(".cycleTypeOnly").collapse("hide");
54772          return $(".notCycleTypeOnly").collapse("show");
54773        } else {
54774          $(".cycleTypeOnly").collapse("show");
54775          return $(".notCycleTypeOnly").collapse("hide");
54776        }
54777      }
54778    };
54779
54780    return UpdatePropulsionType;
54781
54782  })();
54783
54784}).call(this);
54785(function() {
54786  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54787    hasProp = {}.hasOwnProperty;
54788
54789  BikeIndex.BikesEdit = (function(superClass) {
54790    extend(BikesEdit, superClass);
54791
54792    function BikesEdit() {
54793      new BikeIndex.FormWell;
54794      new FormWellMenu;
54795      switch ($('.form-well-header.container').attr('data-template')) {
54796        case 'bike_details':
54797          new BikeIndex.BikesEditBikeDetails;
54798          break;
54799        case 'drivetrain':
54800          new BikeIndex.BikesEditDrivetrain;
54801          break;
54802        case 'report_stolen':
54803          new BikeIndex.BikesEditStolen;
54804          break;
54805        case 'report_recovered':
54806          new BikeIndex.BikesEditStolen;
54807          break;
54808        case 'theft_details':
54809          new BikeIndex.BikesEditStolen;
54810          break;
54811        case 'photos':
54812          new BikeIndex.BikesEditPhotos;
54813          break;
54814        case 'accessories':
54815          new BikeIndex.BikesEditAccessories;
54816          break;
54817        case 'remove':
54818          new BikeIndex.BikesEditRemove;
54819          break;
54820        case 'groups':
54821          new BikeIndex.BikesEditGroups;
54822          break;
54823        case 'alert':
54824          new BikeIndex.BikesEditAlert;
54825      }
54826    }
54827
54828    BikesEdit.prototype.updatePageLocation = function(url) {
54829      return window.location.href = url;
54830    };
54831
54832    BikesEdit.prototype.submitBikeEditForm = function() {
54833      $('form.primary-edit-bike-form').submit();
54834      return setTimeout((function() {
54835        return location.reload(true);
54836      }), 300);
54837    };
54838
54839    return BikesEdit;
54840
54841  })(BikeIndex);
54842
54843}).call(this);
54844(function() {
54845  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54846    hasProp = {}.hasOwnProperty;
54847
54848  BikeIndex.BikesEditAccessories = (function(superClass) {
54849    extend(BikesEditAccessories, superClass);
54850
54851    function BikesEditAccessories() {
54852      var ctype_other_val, manufacturer_other_val;
54853      this.initializeEventListeners();
54854      this.fancySelectForManufacturers();
54855      ctype_other_val = $('#form_well_wrap').data('ctypeother');
54856      manufacturer_other_val = $('#form_well_wrap').data('manufacturerother');
54857      ctype_other_val = $('#form_well_wrap').data('ctypeother');
54858      new BikeIndex.ToggleHiddenOther('.component-manufacturer-input', manufacturer_other_val);
54859      new BikeIndex.ToggleHiddenOther('.component-ctype-input', ctype_other_val);
54860    }
54861
54862    BikesEditAccessories.prototype.initializeEventListeners = function() {
54863      $('#form_well_wrap').on('click', '.remove-part label', (function(_this) {
54864        return function(e) {
54865          return _this.removeComponent(e);
54866        };
54867      })(this));
54868      return $('.add_fields').click((function(_this) {
54869        return function(e) {
54870          return _this.addComponent(e);
54871        };
54872      })(this));
54873    };
54874
54875    BikesEditAccessories.prototype.removeComponent = function(e) {
54876      var $target;
54877      $target = $(e.target);
54878      $target.prev('input[type=hidden]').val('1');
54879      return $target.closest('fieldset').slideUp();
54880    };
54881
54882    BikesEditAccessories.prototype.fancySelectForManufacturers = function() {
54883      var i, len, m, ref, results, toggleOtherDisplay;
54884      toggleOtherDisplay = this.toggleOtherDisplay;
54885      ref = $('.component-manufacturer-input.unfancy');
54886      results = [];
54887      for (i = 0, len = ref.length; i < len; i++) {
54888        m = ref[i];
54889        results.push(new window.ManufacturersSelect(m, false));
54890      }
54891      return results;
54892    };
54893
54894    BikesEditAccessories.prototype.addComponent = function(e) {
54895      var $target, regexp, time;
54896      e.preventDefault();
54897      $target = $('.add_fields');
54898      time = new Date().getTime();
54899      regexp = new RegExp($target.attr('data-id'), 'g');
54900      $target.before($target.data('fields').replace(regexp, time));
54901      this.loadFancySelects();
54902      return this.fancySelectForManufacturers();
54903    };
54904
54905    return BikesEditAccessories;
54906
54907  })(BikeIndex);
54908
54909}).call(this);
54910(function() {
54911  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
54912    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54913    hasProp = {}.hasOwnProperty;
54914
54915  BikeIndex.BikesEditAlert = (function(superClass) {
54916    extend(BikesEditAlert, superClass);
54917
54918    function BikesEditAlert() {
54919      this.selectPlan = bind(this.selectPlan, this);
54920      this.setSelectedImageId = bind(this.setSelectedImageId, this);
54921      this.previewSelectedImage = bind(this.previewSelectedImage, this);
54922      this.highlightSelectedImage = bind(this.highlightSelectedImage, this);
54923      this.initializeEventListeners = bind(this.initializeEventListeners, this);
54924      BikesEditAlert.__super__.constructor.call(this);
54925      this.$alertForm = $('#alert-form');
54926      this.$imageSelectionContainer = $('#js-select-image-container');
54927      this.initializeEventListeners();
54928    }
54929
54930    BikesEditAlert.prototype.initializeEventListeners = function() {
54931      this.$alertForm.on("click", ".js-plan-container", (function(_this) {
54932        return function(event) {
54933          return _this.selectPlan(event);
54934        };
54935      })(this));
54936      return this.$imageSelectionContainer.on("click", ".js-image-select", (function(_this) {
54937        return function(event) {
54938          var $selectedImage;
54939          $selectedImage = $(event.target).closest(".js-image-select");
54940          _this.highlightSelectedImage($selectedImage);
54941          _this.setSelectedImageId($selectedImage);
54942          return _this.previewSelectedImage($selectedImage);
54943        };
54944      })(this));
54945    };
54946
54947    BikesEditAlert.prototype.highlightSelectedImage = function($selectedImage) {
54948      var $allImages;
54949      $allImages = $selectedImage.siblings(".js-image-select").removeClass("selected");
54950      return $selectedImage.addClass("selected");
54951    };
54952
54953    BikesEditAlert.prototype.previewSelectedImage = function($selectedImage) {
54954      var $previewImage, selectedImageUrl;
54955      selectedImageUrl = $selectedImage.data("image-url");
54956      $previewImage = this.$imageSelectionContainer.find("#js-selection-preview-image img");
54957      return $previewImage.attr("src", selectedImageUrl);
54958    };
54959
54960    BikesEditAlert.prototype.setSelectedImageId = function($selectedImage) {
54961      var selectedImageId;
54962      selectedImageId = $selectedImage.data("image-id");
54963      return this.$alertForm.find("#selected_bike_image_id").val(selectedImageId);
54964    };
54965
54966    BikesEditAlert.prototype.selectPlan = function(event) {
54967      var $target;
54968      this.$alertForm.find(".js-plan-container").removeClass("selected");
54969      $target = $(event.target);
54970      if (!$target.hasClass("js-plan-container")) {
54971        $target = $target.parents(".js-plan-container");
54972      }
54973      $target.addClass("selected");
54974      return this.$alertForm.find("#theft_alert_plan_id").val($target.attr("data-id"));
54975    };
54976
54977    return BikesEditAlert;
54978
54979  })(BikeIndex);
54980
54981}).call(this);
54982(function() {
54983  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
54984    hasProp = {}.hasOwnProperty;
54985
54986  BikeIndex.BikesEditBikeDetails = (function(superClass) {
54987    extend(BikesEditBikeDetails, superClass);
54988
54989    function BikesEditBikeDetails() {
54990      new window.ManufacturersSelect('#manufacturer_update_manufacturer');
54991      this.initializeEventListeners();
54992      this.otherManufacturerDisplay($('#manufacturer_update_manufacturer').val());
54993      this.setFrameSize();
54994      this.updateYear();
54995    }
54996
54997    BikesEditBikeDetails.prototype.initializeEventListeners = function() {
54998      var united_states_id;
54999      $('#manufacturer_update_manufacturer').change((function(_this) {
55000        return function(e) {
55001          return _this.otherManufacturerDisplay(e.target.value);
55002        };
55003      })(this));
55004      $('#bike_unknown_year').change((function(_this) {
55005        return function(e) {
55006          return _this.toggleUnknownYear();
55007        };
55008      })(this));
55009      $('#bike_year').change((function(_this) {
55010        return function(e) {
55011          return _this.updateYear();
55012        };
55013      })(this));
55014      $('#serial-correction form').submit((function(_this) {
55015        return function(e) {
55016          e.preventDefault();
55017          return _this.requestSerialUpdate();
55018        };
55019      })(this));
55020      $('#manufacturer-correction form').submit((function(_this) {
55021        return function(e) {
55022          e.preventDefault();
55023          return _this.requestManufacturerUpdate();
55024        };
55025      })(this));
55026      $('.frame-sizes .btn').click((function(_this) {
55027        return function(e) {
55028          return _this.updateFrameSize(e);
55029        };
55030      })(this));
55031      $('.toggle-version-date').click((function(_this) {
55032        return function(e) {
55033          return _this.updateVersionDates(e);
55034        };
55035      })(this));
55036      united_states_id = $('#us_id_data').data('usid');
55037      return new BikeIndex.ToggleHiddenOther('.country-select-input', united_states_id);
55038    };
55039
55040    BikesEditBikeDetails.prototype.updateYear = function() {
55041      if (!$('#bike_year').length) {
55042        return;
55043      }
55044      if ($('#bike_year').val().length === 0) {
55045        return $('#bike_unknown_year').prop('checked', true);
55046      } else {
55047        return $('#bike_unknown_year').prop('checked', false);
55048      }
55049    };
55050
55051    BikesEditBikeDetails.prototype.toggleUnknownYear = function() {
55052      var year_select;
55053      year_select = $('#bike_year').selectize()[0].selectize;
55054      if ($('#bike_unknown_year').prop('checked')) {
55055        return year_select.setValue('');
55056      } else {
55057        return year_select.setValue(new Date().getFullYear());
55058      }
55059    };
55060
55061    BikesEditBikeDetails.prototype.setFrameSize = function() {
55062      var unit;
55063      unit = $('#bike_frame_size_unit').val();
55064      if (unit && unit !== 'ordinal' && unit.length > 0) {
55065        $('.frame-size-other').slideDown().addClass('unhidden');
55066        return $('.frame-size-units').addClass('ex-size');
55067      }
55068    };
55069
55070    BikesEditBikeDetails.prototype.updateFrameSize = function(e) {
55071      var $hidden_other, size;
55072      size = $(e.target).attr('data-size');
55073      $hidden_other = $('.frame-size-other');
55074      if (size === 'cm' || size === 'in') {
55075        $('#bike_frame_size_unit').val(size);
55076        if (!$hidden_other.hasClass('unhidden')) {
55077          $hidden_other.slideDown('fast', function() {
55078            $hidden_other.addClass('unhidden');
55079            $('.ordinal-sizes .btn').removeClass('active');
55080            return $('.frame-sizes').removeClass('unexpanded-unit-size');
55081          });
55082          $('#bike_frame_size').val('');
55083          $('#bike_frame_size_number').val('');
55084          return $('.frame-size-units').addClass('ex-size');
55085        }
55086      } else {
55087        $('#bike_frame_size_unit').val('ordinal');
55088        $('#bike_frame_size_number').val('');
55089        $('#bike_frame_size').val(size);
55090        $('.frame-sizes').addClass('unexpanded-unit-size');
55091        if ($hidden_other.hasClass('unhidden')) {
55092          $hidden_other.slideUp('fast', function() {
55093            return $hidden_other.removeClass('unhidden');
55094          });
55095          $('.frame-size-units').removeClass('ex-size');
55096          return $('.frame-size-units .btn').removeClass('active');
55097        }
55098      }
55099    };
55100
55101    BikesEditBikeDetails.prototype.otherManufacturerDisplay = function(slug) {
55102      var hidden_other;
55103      hidden_other = $('#manufacturer_update_manufacturer').parents('.related-fields').find('.hidden-other');
55104      if (slug === 'other' || slug === 'Other') {
55105        return hidden_other.slideDown().addClass('unhidden');
55106      } else if (hidden_other.hasClass('unhidden')) {
55107        hidden_other.find('input').val('');
55108        return hidden_other.removeClass('unhidden').slideUp();
55109      }
55110    };
55111
55112    BikesEditBikeDetails.prototype.requestSerialUpdateRequestCallback = function(data, success) {
55113      var msg;
55114      if (success) {
55115        msg = "We've updated your serial!";
55116        return window.BikeIndexAlerts.add('success', msg, window.pageScript.submitBikeEditForm);
55117      } else {
55118        return window.BikeIndexAlerts.add('error', "We're unable to process the update! Try again?");
55119      }
55120    };
55121
55122    BikesEditBikeDetails.prototype.requestManufacturerUpdateRequestCallback = function(data, success) {
55123      var msg;
55124      if (success) {
55125        msg = "We've updated your manufacturer!";
55126        return window.BikeIndexAlerts.add('success', msg, window.pageScript.submitBikeEditForm);
55127      } else {
55128        return window.BikeIndexAlerts.add('error', "We're unable to process the update! Try again?");
55129      }
55130    };
55131
55132    BikesEditBikeDetails.prototype.requestSerialUpdate = function() {
55133      var bike_id, data, reason, response_callback, serial;
55134      serial = $('#serial_update_serial').val();
55135      reason = $('#serial_update_reason').val();
55136      bike_id = $('#serial_update_bike_id').val();
55137      if (serial.length > 0 && reason.length > 0 && bike_id.length > 0) {
55138        data = {
55139          request_type: 'serial_update_request',
55140          request_bike_id: bike_id,
55141          request_reason: reason,
55142          serial_update_serial: serial
55143        };
55144        response_callback = this.requestSerialUpdateRequestCallback;
55145        return new BikeIndex.SubmitUserRequest(data, response_callback);
55146      } else {
55147        return $('#serial-correction .alert').slideDown('fast');
55148      }
55149    };
55150
55151    BikesEditBikeDetails.prototype.requestManufacturerUpdate = function() {
55152      var bike_id, data, manufacturer, manufacturer_other, other_missing, other_selected, reason, response_callback;
55153      manufacturer = $('#manufacturer_update_manufacturer').val();
55154      manufacturer_other = $('#manufacturer_update_manufacturer_other').val();
55155      reason = $('#manufacturer_update_reason').val();
55156      bike_id = $('#manufacturer_update_bike_id').val();
55157      other_selected = manufacturer === 'other' || manufacturer === 'Other';
55158      other_missing = other_selected && manufacturer_other.length === 0;
55159      if (manufacturer.length > 0 && reason.length > 0 && bike_id.length > 0 && !other_missing) {
55160        data = {
55161          request_type: 'manufacturer_update_request',
55162          request_bike_id: bike_id,
55163          request_reason: reason,
55164          manufacturer_update_manufacturer: manufacturer,
55165          manufacturer_update_manufacturer_other: manufacturer_other
55166        };
55167        response_callback = this.requestManufacturerUpdateRequestCallback;
55168        return new BikeIndex.SubmitUserRequest(data, response_callback);
55169      } else {
55170        return $('#manufacturer-correction .alert').slideDown('fast');
55171      }
55172    };
55173
55174    BikesEditBikeDetails.prototype.updateVersionDates = function(e) {
55175      return window.setTimeout((function() {
55176        var end_at, start_at;
55177        start_at = $("#start-at").hasClass("unhidden");
55178        $('#bike_version_start_at_shown').val("" + start_at);
55179        end_at = $("#end-at").hasClass("unhidden");
55180        return $('#bike_version_end_at_shown').val("" + end_at);
55181      }), 1000);
55182    };
55183
55184    return BikesEditBikeDetails;
55185
55186  })(BikeIndex);
55187
55188}).call(this);
55189(function() {
55190  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55191    hasProp = {}.hasOwnProperty,
55192    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
55193
55194  BikeIndex.BikesEditDrivetrain = (function(superClass) {
55195    extend(BikesEditDrivetrain, superClass);
55196
55197    function BikesEditDrivetrain() {
55198      var j, len, ref, side;
55199      this.initializeEventListeners();
55200      ref = ['front', 'rear'];
55201      for (j = 0, len = ref.length; j < len; j++) {
55202        side = ref[j];
55203        this.initializeWheelDiams(side);
55204      }
55205      this.setInitialGears();
55206    }
55207
55208    BikesEditDrivetrain.prototype.initializeEventListeners = function() {
55209      $('.standard-diams select').change((function(_this) {
55210        return function(e) {
55211          return _this.updateDiamsFromStandardChange(e);
55212        };
55213      })(this));
55214      $('.drive-check').change((function(_this) {
55215        return function(e) {
55216          return _this.toggleDrivetrainChecks(e);
55217        };
55218      })(this));
55219      return $('#edit_drivetrain select').change((function(_this) {
55220        return function(e) {
55221          return _this.updateDrivetrainValue(e);
55222        };
55223      })(this));
55224    };
55225
55226    BikesEditDrivetrain.prototype.updateDiamsFromStandardChange = function(e) {
55227      var $target, current_val, selectize;
55228      current_val = e.target.value;
55229      $target = $(e.target).parents('.form-well-input').find('.all-diams select');
55230      selectize = $target.selectize()[0].selectize;
55231      return selectize.setValue(current_val);
55232    };
55233
55234    BikesEditDrivetrain.prototype.initializeWheelDiams = function(side) {
55235      var $all_diams_btn, $standard_diams, current_val, selectize, standard_values;
55236      current_val = $("#" + side + "_all select").val();
55237      $standard_diams = $("#" + side + "_standard select");
55238      if (current_val.length > 0) {
55239        selectize = $standard_diams.selectize()[0].selectize;
55240        standard_values = Object.keys(selectize.options);
55241        if (indexOf.call(standard_values, current_val) >= 0) {
55242          return selectize.setValue(current_val);
55243        } else {
55244          $all_diams_btn = $standard_diams.parents('.related-fields').find('.show-all-diams');
55245          return $all_diams_btn.trigger('click', false);
55246        }
55247      }
55248    };
55249
55250    BikesEditDrivetrain.prototype.toggleDrivetrainChecks = function(e) {
55251      var $target, id;
55252      $target = $(e.target);
55253      id = $target.attr('id');
55254      if (id === 'fixed_gear_check') {
55255        return this.toggleFixed($target.prop('checked'));
55256      } else {
55257        if (id === 'front_gear_select_internal') {
55258          this.setDrivetrainValue('front_gear_select');
55259        }
55260        if (id === 'rear_gear_select_internal') {
55261          return this.setDrivetrainValue('rear_gear_select');
55262        }
55263      }
55264    };
55265
55266    BikesEditDrivetrain.prototype.toggleFixed = function(is_fixed) {
55267      var fixed_values, j, len, ref, selectize, side;
55268      fixed_values = {};
55269      ref = ['front', 'rear'];
55270      for (j = 0, len = ref.length; j < len; j++) {
55271        side = ref[j];
55272        selectize = $("#" + side + "_gear_select").selectize()[0];
55273        selectize.selectize.setValue('');
55274        fixed_values[side] = $("#" + side + "_gear_select_value").attr('data-fixed');
55275      }
55276      if (is_fixed) {
55277        return $('#edit_drivetrain .not-fixed').slideUp('medium', function() {
55278          $('#edit_drivetrain .not-fixed input[type="checkbox"]').prop('checked', '').prop('disabled', false);
55279          $("#front_gear_select_value #bike_front_gear_type_id_" + fixed_values.front).prop('checked', true);
55280          return $("#rear_gear_select_value #bike_rear_gear_type_id_" + fixed_values.rear).prop('checked', true);
55281        });
55282      } else {
55283        $('#front_gear_select_value .no-gear-selected, #rear_gear_select_value .no-gear-selected').prop('checked', true);
55284        return $('.not-fixed').slideDown();
55285      }
55286    };
55287
55288    BikesEditDrivetrain.prototype.lockInternalFront = function(count) {
55289      var $checkbox, internal_only;
55290      $checkbox = $('#front_gear_select_internal');
55291      internal_only = !isNaN(count) && $("#front_gear_select_value .count_" + count + ".internal_true").length > 0 && $("#front_gear_select_value .count_" + count + ".internal_false").length === 0;
55292      if (internal_only) {
55293        return $checkbox.prop('checked', true).prop('disabled', true);
55294      } else {
55295        return $checkbox.prop('disabled', false);
55296      }
55297    };
55298
55299    BikesEditDrivetrain.prototype.setDrivetrainValue = function(position) {
55300      var i, v;
55301      v = parseInt($("#" + position).val(), 10);
55302      if (position === 'front_gear_select') {
55303        this.lockInternalFront(v);
55304      }
55305      i = $("#" + position + "_internal").prop('checked');
55306      if (isNaN(v)) {
55307        return $("#" + position + "_value .placeholder").prop('selected', 'selected');
55308      } else {
55309        $("#" + position + "_value .count_" + v + ".internal_" + i).prop('checked', true);
55310        if (v === 0) {
55311          return $('#rear_gear_select_internal').prop('checked', true);
55312        }
55313      }
55314    };
55315
55316    BikesEditDrivetrain.prototype.updateDrivetrainValue = function(event) {
55317      var position;
55318      if ($('#fixed_gear_check').prop('checked')) {
55319        return true;
55320      } else {
55321        position = $(event.target).attr('id');
55322        return this.setDrivetrainValue(position);
55323      }
55324    };
55325
55326    BikesEditDrivetrain.prototype.setInitialGears = function() {
55327      var count, j, len, ref, results, selectize, side;
55328      if ($('#fixed_gear_check').prop('checked') === true) {
55329        return this.toggleFixed(true);
55330      } else {
55331        ref = ['front', 'rear'];
55332        results = [];
55333        for (j = 0, len = ref.length; j < len; j++) {
55334          side = ref[j];
55335          count = $("#" + side + "_gear_select_value").attr('data-initialcount');
55336          if (!isNaN(count)) {
55337            selectize = $("#" + side + "_gear_select").selectize()[0];
55338            results.push(selectize.selectize.setValue(count));
55339          } else {
55340            results.push(void 0);
55341          }
55342        }
55343        return results;
55344      }
55345    };
55346
55347    return BikesEditDrivetrain;
55348
55349  })(BikeIndex);
55350
55351}).call(this);
55352(function() {
55353  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55354    hasProp = {}.hasOwnProperty;
55355
55356  BikeIndex.BikesEditGroups = (function(superClass) {
55357    extend(BikesEditGroups, superClass);
55358
55359    function BikesEditGroups() {
55360      new window.CheckEmail('#bike_owner_email');
55361      this.initializeEventListeners();
55362      this.initializeAdditionalOrganizations();
55363    }
55364
55365    BikesEditGroups.prototype.initializeEventListeners = function() {
55366      $('#edit_bike_organizations').on('click', '.remove-organization', (function(_this) {
55367        return function(e) {
55368          var $formRow;
55369          e.preventDefault();
55370          $formRow = $(e.target).parents('.form-group.row');
55371          return $formRow.slideUp(400, function() {
55372            $formRow.remove();
55373            return _this.updateBikeOrganizations();
55374          });
55375        };
55376      })(this));
55377      return $('#additional_organization_fields').on('change', '.bike_organization_input', (function(_this) {
55378        return function(e) {
55379          return _this.updateBikeOrganizations();
55380        };
55381      })(this));
55382    };
55383
55384    BikesEditGroups.prototype.initializeAdditionalOrganizations = function() {
55385      window.addOrganizationTemplate = $('#additional-organization-template').html();
55386      Mustache.parse(window.addOrganizationTemplate);
55387      $('#add_additional_organization').click((function(_this) {
55388        return function(e) {
55389          e.preventDefault();
55390          return _this.addAdditionalOrganizationSelector();
55391        };
55392      })(this));
55393      return this.addAdditionalOrganizationSelector();
55394    };
55395
55396    BikesEditGroups.prototype.addAdditionalOrganizationSelector = function() {
55397      $('#additional_organization_fields').append(Mustache.render(window.addOrganizationTemplate, {
55398        organizations: window.organizations
55399      }));
55400      this.loadFancySelects();
55401      return $('#additional_organization_fields .collapse').collapse('show');
55402    };
55403
55404    BikesEditGroups.prototype.bikeOrganizationIds = function() {
55405      return _.compact($('.bike_organization_static_input').get().map(function(i) {
55406        return $(i).data('orgid');
55407      }).concat($('.bike_organization_input').get().map(function(i) {
55408        return i.value;
55409      })));
55410    };
55411
55412    BikesEditGroups.prototype.updateBikeOrganizations = function() {
55413      return $('#bike_bike_organization_ids').val(this.bikeOrganizationIds().join(','));
55414    };
55415
55416    return BikesEditGroups;
55417
55418  })(BikeIndex);
55419
55420}).call(this);
55421(function() {
55422  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
55423    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55424    hasProp = {}.hasOwnProperty;
55425
55426  BikeIndex.BikesEditPhotos = (function(superClass) {
55427    extend(BikesEditPhotos, superClass);
55428
55429    function BikesEditPhotos() {
55430      this.initializeSortablePhotos = bind(this.initializeSortablePhotos, this);
55431      this.initializeEventListeners();
55432      this.initializeSortablePhotos();
55433      this.initializeImageUploads();
55434    }
55435
55436    BikesEditPhotos.prototype.initializeEventListeners = function() {
55437      $('#public_images').on('change', '.is_private_check', (function(_this) {
55438        return function(e) {
55439          return _this.updateImagePrivateness(e);
55440        };
55441      })(this));
55442      $('#public_images').on('change', '.kind_select', (function(_this) {
55443        return function(e) {
55444          return _this.updateImageKind(e);
55445        };
55446      })(this));
55447      return $('.saveBikeChanges').click(function(e) {
55448        e.preventDefault();
55449        if ($("#permittedReturnTo").length) {
55450          return window.location = $("#permittedReturnTo").attr("data-path");
55451        } else {
55452          return location.reload(true);
55453        }
55454      });
55455    };
55456
55457    BikesEditPhotos.prototype.initializeImageUploads = function() {
55458      var finished_upload_template;
55459      finished_upload_template = $('#image-upload-finished-template').html();
55460      Mustache.parse(finished_upload_template);
55461      return $('#new_public_image').fileupload({
55462        dataType: "script",
55463        add: function(e, data) {
55464          var file, types;
55465          types = /(\.|\/)(gif|jpe?g|png|tiff?)$/i;
55466          file = data.files[0];
55467          $('#public_images').sortable('disable');
55468          if (types.test(file.type) || types.test(file.name)) {
55469            data.context = $("<div class='upload'><p><em>" + file.name + "</em></p><progress class='progress progress-info'>0%</progress></div>");
55470            $('#new_public_image').append(data.context);
55471            return data.submit();
55472          } else {
55473            return window.BikeIndexAlerts.add('error', file.name + " is not a gif, jpeg, or png image file");
55474          }
55475        },
55476        progress: function(e, data) {
55477          var progress;
55478          if (data.context) {
55479            progress = parseInt(data.loaded / data.total * 95, 10);
55480            return data.context.find('.progress').text(progress + '%');
55481          }
55482        },
55483        done: (function(_this) {
55484          return function(e, data) {
55485            var file;
55486            _this.initializeSortablePhotos();
55487            file = data.files[0];
55488            return $.each(data.files, function(index, file) {
55489              return data.context.addClass('finished_upload').html(Mustache.render(finished_upload_template, file)).fadeOut();
55490            });
55491          };
55492        })(this)
55493      });
55494    };
55495
55496    BikesEditPhotos.prototype.initializeSortablePhotos = function() {
55497      var $sortable_container;
55498      $sortable_container = $('#public_images');
55499      $sortable_container.sortable('destroy');
55500      return $sortable_container.sortable({
55501        onDrop: (function(_this) {
55502          return function($item, container, _super) {
55503            _this.pushImageOrder($sortable_container);
55504            return _super($item, container);
55505          };
55506        })(this)
55507      });
55508    };
55509
55510    BikesEditPhotos.prototype.pushImageOrder = function($sortable_container) {
55511      var array_of_photo_ids, list_item, new_item_order, sortable_list_items, url_target;
55512      url_target = $sortable_container.data('orderurl');
55513      sortable_list_items = $sortable_container.children('li');
55514      array_of_photo_ids = (function() {
55515        var i, len, results;
55516        results = [];
55517        for (i = 0, len = sortable_list_items.length; i < len; i++) {
55518          list_item = sortable_list_items[i];
55519          results.push($(list_item).prop('id'));
55520        }
55521        return results;
55522      })();
55523      new_item_order = {
55524        list_of_photos: array_of_photo_ids
55525      };
55526      return $.post(url_target, new_item_order);
55527    };
55528
55529    BikesEditPhotos.prototype.updateImagePrivateness = function(e) {
55530      var $target, id, is_private, url_target;
55531      $target = $(e.target);
55532      is_private = $target.prop('checked');
55533      id = $target.parents('.edit-photo-display-list-item').prop('id');
55534      url_target = ($('#public_images').data('imagesurl')) + "/" + id + "/is_private";
55535      return $.post(url_target, {
55536        is_private: is_private
55537      });
55538    };
55539
55540    BikesEditPhotos.prototype.updateImageKind = function(e) {
55541      var $target, id, kind, url_target;
55542      $target = $(e.target);
55543      kind = $target.val();
55544      id = $target.parents('.edit-photo-display-list-item').prop('id');
55545      url_target = ($('#public_images').data('imagesurl')) + "/" + id;
55546      return $.ajax({
55547        url: url_target,
55548        method: "put",
55549        data: {
55550          kind: kind
55551        }
55552      });
55553    };
55554
55555    return BikesEditPhotos;
55556
55557  })(BikeIndex);
55558
55559}).call(this);
55560(function() {
55561  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55562    hasProp = {}.hasOwnProperty;
55563
55564  BikeIndex.BikesEditRemove = (function(superClass) {
55565    extend(BikesEditRemove, superClass);
55566
55567    function BikesEditRemove() {
55568      this.initializeEventListeners();
55569    }
55570
55571    BikesEditRemove.prototype.initializeEventListeners = function() {
55572      $('#hide_bike_toggle').click((function(_this) {
55573        return function(e) {
55574          return _this.toggleHidden(e);
55575        };
55576      })(this));
55577      return $('#request-delete form').submit((function(_this) {
55578        return function(e) {
55579          e.preventDefault();
55580          _this.requestDelete();
55581          setTimeout((function() {
55582            return $("#request-delete input[type=submit]").attr("disabled", false);
55583          }), 500);
55584          return false;
55585        };
55586      })(this));
55587    };
55588
55589    BikesEditRemove.prototype.toggleHidden = function(e) {
55590      e.preventDefault();
55591      $('#hide_bike_toggle_group input').val('true');
55592      return window.pageScript.submitBikeEditForm();
55593    };
55594
55595    BikesEditRemove.prototype.requestDeleteRequestCallback = function(data, success) {
55596      var msg;
55597      if (success) {
55598        msg = "Your bike's been deleted!";
55599        return window.BikeIndexAlerts.add('info', msg, function() {
55600          return window.location.href = window.userRootUrl;
55601        });
55602      } else {
55603        msg = "Oh no! Something went wrong and we couldn't send the delete request.";
55604        return window.BikeIndexAlerts.add('error', msg);
55605      }
55606    };
55607
55608    BikesEditRemove.prototype.requestDelete = function() {
55609      var bike_id, data, reason, response_callback;
55610      reason = $('#bike_delete_reason').val();
55611      bike_id = $('#bike_delete_bike_id').val();
55612      if (reason.length > 0 && bike_id.length > 0) {
55613        data = {
55614          request_type: 'bike_delete_request',
55615          request_bike_id: bike_id,
55616          request_reason: reason
55617        };
55618        response_callback = this.requestDeleteRequestCallback;
55619        return new BikeIndex.SubmitUserRequest(data, response_callback);
55620      } else {
55621        return $("#request-delete .alert").slideDown("fast").removeClass("currently-hidden");
55622      }
55623    };
55624
55625    return BikesEditRemove;
55626
55627  })(BikeIndex);
55628
55629}).call(this);
55630(function() {
55631  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55632    hasProp = {}.hasOwnProperty;
55633
55634  BikeIndex.BikesEditStolen = (function(superClass) {
55635    extend(BikesEditStolen, superClass);
55636
55637    function BikesEditStolen() {
55638      var united_states_id;
55639      this.initializeEventListeners();
55640      if ($('.stolenEditPage').length > 0) {
55641        united_states_id = $('#us_id_data').data('usid');
55642        new BikeIndex.ToggleHiddenOther('.country-select-input', united_states_id);
55643      }
55644    }
55645
55646    BikesEditStolen.prototype.initializeEventListeners = function() {
55647      return $('#toggle-stolen form').submit((function(_this) {
55648        return function(e) {
55649          e.preventDefault();
55650          return _this.markRecovered();
55651        };
55652      })(this));
55653    };
55654
55655    BikesEditStolen.prototype.recoveredRequestCallback = function(message, success) {
55656      var msg, redirect_url;
55657      if (success) {
55658        msg = "Thanks for telling us! We're so glad you got your bike back!";
55659        $('#bike_stolen').prop('checked', '0');
55660        redirect_url = window.location.href.replace(window.location.search, "");
55661        return window.BikeIndexAlerts.add('success', msg, function() {
55662          return window.location.href = redirect_url;
55663        });
55664      } else {
55665        $('#mark_recovered_spinner').hide();
55666        $('#mark_recovered_action').show();
55667        msg = "Oh no! Something went wrong and we couldn't mark your bike recovered.";
55668        return window.BikeIndexAlerts.add('error', msg);
55669      }
55670    };
55671
55672    BikesEditStolen.prototype.markRecovered = function() {
55673      var bike_id, can_share_recovery, data, did_we_help, reason, response_callback;
55674      $('#primary_stolen_phone_field input').attr('required', false);
55675      reason = $('#mark_recovered_reason').val();
55676      bike_id = $('#mark_recovered_bike_id').val();
55677      did_we_help = $('#mark_recovered_we_helped').prop('checked');
55678      can_share_recovery = $('#mark_recovered_can_share_recovery').prop('checked');
55679      if (reason.length > 0 && bike_id.length > 0) {
55680        $('#mark_recovered_action').hide();
55681        $('#mark_recovered_spinner').show();
55682        data = {
55683          request_type: 'bike_recovery',
55684          request_bike_id: bike_id,
55685          request_reason: reason,
55686          index_helped_recovery: did_we_help,
55687          can_share_recovery: can_share_recovery
55688        };
55689        response_callback = this.recoveredRequestCallback;
55690        return new BikeIndex.SubmitUserRequest(data, response_callback);
55691      } else {
55692        return $("#toggle-stolen .alert").slideDown("fast").removeClass("currently-hidden");
55693      }
55694    };
55695
55696    return BikesEditStolen;
55697
55698  })(BikeIndex);
55699
55700}).call(this);
55701(function() {
55702  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55703    hasProp = {}.hasOwnProperty;
55704
55705  BikeIndex.BikesIndex = (function(superClass) {
55706    extend(BikesIndex, superClass);
55707
55708    function BikesIndex() {
55709      new BikeIndex.BikeSearchBar;
55710      new BikeIndex.BikeBoxes;
55711    }
55712
55713    return BikesIndex;
55714
55715  })(BikeIndex);
55716
55717}).call(this);
55718(function() {
55719  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55720    hasProp = {}.hasOwnProperty;
55721
55722  BikeIndex.BikesNew = (function(superClass) {
55723    extend(BikesNew, superClass);
55724
55725    function BikesNew() {
55726      var united_stated_id;
55727      new window.ManufacturersSelect('#bike_manufacturer_id');
55728      new BikeIndex.FormWell;
55729      new window.CheckEmail('#bike_owner_email');
55730      new window.UpdatePropulsionType('bike');
55731      this.initializeEventListeners();
55732      this.updateSerial($('#has_no_serial').prop('checked'));
55733      this.otherManufacturerDisplay($('#bike_manufacturer_id').val());
55734      if ($('#stolen_record_us_id').length > 0) {
55735        united_stated_id = $('#stolen_record_us_id').data('usid');
55736        new BikeIndex.ToggleHiddenOther('.country-select-input', united_stated_id);
55737      }
55738    }
55739
55740    BikesNew.prototype.initializeEventListeners = function() {
55741      $('#bike_manufacturer_id').change((function(_this) {
55742        return function(e) {
55743          var current_val;
55744          current_val = e.target.value;
55745          _this.otherManufacturerDisplay(current_val);
55746          return _this.getModelList(current_val);
55747        };
55748      })(this));
55749      $('#bike_unknown_year').change((function(_this) {
55750        return function(e) {
55751          return _this.toggleUnknownYear();
55752        };
55753      })(this));
55754      $('#bike_year').change((function(_this) {
55755        return function(e) {
55756          return _this.updateYear();
55757        };
55758      })(this));
55759      $('#has_no_serial').change((function(_this) {
55760        return function(e) {
55761          return _this.updateSerial($('#has_no_serial').prop('checked'));
55762        };
55763      })(this));
55764      $('#made-without-serial-button').click((function(_this) {
55765        return function(e) {
55766          return _this.madeWithoutSerial(true);
55767        };
55768      })(this));
55769      $('#bike_made_without_serial').change((function(_this) {
55770        return function(e) {
55771          return _this.updateSerial(true);
55772        };
55773      })(this));
55774      return $('#traditional_bike_checkbox').change((function(_this) {
55775        return function(e) {
55776          return _this.updateCycleTypeCheck();
55777        };
55778      })(this));
55779    };
55780
55781    BikesNew.prototype.updateSerial = function(serial_absent) {
55782      var serialVal;
55783      this.madeWithoutSerial();
55784      if (serial_absent) {
55785        serialVal = $("#bike_serial_number").val();
55786        if (!(serialVal === "made_without_serial" || serialVal === "unknown")) {
55787          window.existingSerialNumber = serialVal;
55788        }
55789        $('#bike_serial_number').val("unknown").addClass("absent-serial");
55790        return $("#made-without-serial-help .hidden-other").slideDown();
55791      } else {
55792        if ($("#bike_serial_number").val() === "unknown") {
55793          $("#bike_serial_number").val(window.existingSerialNumber || "").removeClass("absent-serial");
55794        }
55795        return $("#made-without-serial-help .hidden-other").slideUp();
55796      }
55797    };
55798
55799    BikesNew.prototype.madeWithoutSerial = function(no_serial) {
55800      if (no_serial == null) {
55801        no_serial = false;
55802      }
55803      $('#made-without-serial-modal').modal('hide');
55804      if (no_serial) {
55805        $("#serial-input, #made-without-serial-help, .made-without-serial-checkbox").slideUp();
55806        $('#made-without-serial-input').slideDown();
55807        $('#bike_made_without_serial').prop('checked', true);
55808        return $('#bike_serial_number').val("made_without_serial");
55809      } else {
55810        $("#serial-input, #made-without-serial-help, .made-without-serial-checkbox").slideDown();
55811        $('#made-without-serial-input').slideUp();
55812        return $('#bike_made_without_serial').prop('checked', false);
55813      }
55814    };
55815
55816    BikesNew.prototype.otherManufacturerDisplay = function(slug) {
55817      var hidden_other;
55818      hidden_other = $('#bike_manufacturer_id').parents('.related-fields').find('.hidden-other');
55819      if (slug === 'other' || slug === 'Other') {
55820        return hidden_other.slideDown().addClass('unhidden');
55821      } else if (hidden_other.hasClass('unhidden')) {
55822        hidden_other.find('input').val('');
55823        return hidden_other.removeClass('unhidden').slideUp();
55824      }
55825    };
55826
55827    BikesNew.prototype.getModelList = function(mnfg_name) {
55828      var url, year;
55829      if (mnfg_name == null) {
55830        mnfg_name = '';
55831      }
55832      if (mnfg_name === 'absent' || mnfg_name.length < 1) {
55833        return this.setModelTypeahead();
55834      } else {
55835        year = parseInt($('#bike_year').val(), 10);
55836        url = "https://bikebook.herokuapp.com/model_list/?manufacturer=" + mnfg_name;
55837        if (year > 1) {
55838          url += "&year=" + year;
55839        }
55840        return $.ajax({
55841          type: "GET",
55842          url: url,
55843          success: (function(_this) {
55844            return function(data, textStatus, jqXHR) {
55845              return _this.setModelTypeahead(data);
55846            };
55847          })(this),
55848          error: (function(_this) {
55849            return function() {
55850              return _this.setModelTypeahead();
55851            };
55852          })(this)
55853        });
55854      }
55855    };
55856
55857    BikesNew.prototype.setModelTypeahead = function(data) {
55858      if (data == null) {
55859        data = [];
55860      }
55861      $('#bike_frame_model').selectize()[0].selectize.destroy();
55862      if (data.length > 0) {
55863        window.m_data = data.map(function(i) {
55864          return {
55865            id: i
55866          };
55867        });
55868        return $('#bike_frame_model').selectize({
55869          plugins: ['restore_on_backspace'],
55870          options: data.map(function(i) {
55871            return {
55872              'name': i
55873            };
55874          }),
55875          create: true,
55876          maxItems: 1,
55877          valueField: 'name',
55878          labelField: 'name',
55879          searchField: 'name'
55880        });
55881      }
55882    };
55883
55884    BikesNew.prototype.updateYear = function() {
55885      if ($('#bike_year').val()) {
55886        if ($('#bike_year').val().length === 0) {
55887          $('#bike_year').selectize()[0].selectize.disable();
55888          $('#bike_unknown_year').prop('checked', true);
55889        } else {
55890          $('#bike_unknown_year').prop('checked', false);
55891        }
55892      }
55893      return this.getModelList($('#bike_manufacturer_id').val());
55894    };
55895
55896    BikesNew.prototype.toggleUnknownYear = function() {
55897      var year_select;
55898      year_select = $('#bike_year').selectize()[0].selectize;
55899      if ($('#bike_unknown_year').prop('checked')) {
55900        year_select.setValue('');
55901        return year_select.disable();
55902      } else {
55903        year_select.setValue(new Date().getFullYear());
55904        return year_select.enable();
55905      }
55906    };
55907
55908    BikesNew.prototype.updateCycleTypeCheck = function() {
55909      $('#traditional_bike_checkbox').parents('label').collapse('hide');
55910      return $('.cycle-type-select').collapse('show');
55911    };
55912
55913    BikesNew.prototype.updatePropulsionAndCycleType = function() {
55914      var cycleTypeValue, newTypeText;
55915      cycleTypeValue = $('#bike_cycle_type').val();
55916      if (window.cycleTypesAlwaysMotorized.includes(cycleTypeValue)) {
55917        $('#propulsionTypeFields').collapse('hide');
55918        $('#propulsion_type_motorized').prop('checked', true);
55919        $('#propulsion_type_motorized').attr('disabled', true);
55920        $('#motorizedWrapper').addClass('less-strong cursor-not-allowed').removeClass('cursor-pointer');
55921      } else if (window.cycleTypesNeverMotorized.includes(cycleTypeValue)) {
55922        $('#propulsion_type_motorized').prop('checked', false);
55923        $('#propulsion_type_motorized').attr('disabled', true);
55924        $('#propulsionTypeFields').collapse('hide');
55925        $('#motorizedWrapper').addClass('less-strong cursor-not-allowed').removeClass('cursor-pointer');
55926      } else {
55927        $('#motorizedWrapper').addClass('cursor-pointer').removeClass('less-strong cursor-not-allowed');
55928        $('#propulsion_type_motorized').attr('disabled', false);
55929        if ($('#propulsion_type_motorized').prop('checked')) {
55930          if (window.cycleTypesPedals.includes(cycleTypeValue)) {
55931            $('#propulsionTypeFields').collapse('show');
55932          } else {
55933            $('#propulsionTypeFields').collapse('hide');
55934          }
55935        } else {
55936          $('#propulsionTypeFields').collapse('hide');
55937          $('#propulsion_type_throttle').prop('checked', false);
55938          $('#propulsion_type_pedal_assist').prop('checked', false);
55939        }
55940      }
55941      newTypeText = window.cycleTypeTranslations[cycleTypeValue];
55942      if (newTypeText.length) {
55943        $(".cycleTypeText").text(newTypeText);
55944      }
55945      if (window.cycleTypesNot.includes(cycleTypeValue)) {
55946        $(".cycleTypeOnly").collapse("hide");
55947        return $(".notCycleTypeOnly").collapse("show");
55948      } else {
55949        $(".cycleTypeOnly").collapse("show");
55950        return $(".notCycleTypeOnly").collapse("hide");
55951      }
55952    };
55953
55954    return BikesNew;
55955
55956  })(BikeIndex);
55957
55958}).call(this);
55959(function() {
55960  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
55961    hasProp = {}.hasOwnProperty;
55962
55963  window.fillInParkingLocation = function(position) {
55964    window.waitingOnLocation = false;
55965    $(".parkingLocation-latitude").val(position.coords.latitude);
55966    $(".parkingLocation-longitude").val(position.coords.longitude);
55967    $(".parkingLocation-accuracy").val(position.coords.accuracy);
55968    $(".parkingLocation-submit-btn").attr("disabled", false);
55969    $(".hideOnLocationFind").collapse("hide");
55970    return $(".showOnLocationFind").collapse("show");
55971  };
55972
55973  window.parkingLocationError = function(err) {
55974    window.fallbackToManualAddress();
55975    return console.log(err);
55976  };
55977
55978  window.fallbackToManualAddress = function() {
55979    if (!window.waitingOnLocation) {
55980      return true;
55981    }
55982    $(".waitingOnLocationText").text("Unable to determine current location automatically");
55983    $("#parking_notification_use_entered_address_true").prop("checked", true);
55984    $(".address-group").collapse("show");
55985    return $(".parkingLocation-submit-btn").attr("disabled", false);
55986  };
55987
55988  BikeIndex.BikesShow = (function(superClass) {
55989    extend(BikesShow, superClass);
55990
55991    function BikesShow() {
55992      var $current_photo;
55993      window.bike_photos_loaded = false;
55994      if ($(".bike-overlay-wrapper").length > 0) {
55995        this.showBikeOverlay();
55996      }
55997      if ($(".organized-access-panel").length > 0) {
55998        this.showOrganizedAccessPanel();
55999      }
56000      if ($("#impound_claim").length > 0) {
56001        this.initializeImpoundClaimPanel();
56002      }
56003      if (document.getElementById('initial-open-modal')) {
56004        $('#initial-open-modal').modal('show');
56005      }
56006      $('#write_them_a_message a').click(function(e) {
56007        var $target;
56008        $target = $(e.target).parents('#write_them_a_message');
56009        if ($target.data('redirect')) {
56010          window.location = $target.data('redirect');
56011          return false;
56012        } else {
56013          return $('#write_them_a_message').collapse('toggle');
56014        }
56015      });
56016      if (document.getElementById('thumbnails')) {
56017        this.initializeEventListeners();
56018        this.initializeThumbnailSwitching();
56019      }
56020      $current_photo = $('#selected-photo .current-photo');
56021      if ($current_photo.length > 0) {
56022        this.setIdealImageHeight();
56023      }
56024    }
56025
56026    BikesShow.prototype.initializeEventListeners = function() {
56027      $('#thumbnails .clickable-image').click((function(_this) {
56028        return function(e) {
56029          return _this.clickPhoto(e);
56030        };
56031      })(this));
56032      $(document).keyup((function(_this) {
56033        return function(e) {
56034          return _this.rotatePhotosOnArrows(e);
56035        };
56036      })(this));
56037      return $(window).one('scroll', (function(_this) {
56038        return function() {
56039          return _this.loadPhotos();
56040        };
56041      })(this));
56042    };
56043
56044    BikesShow.prototype.showBikeOverlay = function() {
56045      var height;
56046      height = 36 + $(".bike-overlay-wrapper").outerHeight();
56047      return $(".primary-footer .terms-and-stuff").css("padding-bottom", height + "px");
56048    };
56049
56050    BikesShow.prototype.renderParkingNotificationForm = function() {
56051      var united_states_id;
56052      united_states_id = $('#us_id_data').data('usid');
56053      new BikeIndex.ToggleHiddenOther('.country-select-input', united_states_id);
56054      window.waitingOnLocation = true;
56055      setTimeout(((function(_this) {
56056        return function() {
56057          return window.fallbackToManualAddress();
56058        };
56059      })(this)), 45000);
56060      navigator.geolocation.getCurrentPosition(window.fillInParkingLocation, window.parkingLocationError, {
56061        enableHighAccuracy: true,
56062        timeout: 5000,
56063        maximumAge: 0
56064      });
56065      $(".use-entered-address-radios input").on("change", (function(_this) {
56066        return function(e) {
56067          if ($("#parking_notification_use_entered_address_true").prop("checked")) {
56068            $(".address-group").collapse("show");
56069            return $(".ifManualRequired").attr("required", true);
56070          } else {
56071            $(".address-group").collapse("hide");
56072            return $(".ifManualRequired input").attr("required", false);
56073          }
56074        };
56075      })(this));
56076      return $('.avatar-upload-field').change(function(event) {
56077        var name;
56078        name = event.target.files[0].name;
56079        return $(event.target).parent().find('.file-upload-text').text(name);
56080      });
56081    };
56082
56083    BikesShow.prototype.showOrganizedAccessPanel = function() {
56084      if ($("#newParkingNotificationFields").hasClass("in")) {
56085        this.renderParkingNotificationForm();
56086      }
56087      return $("#openNewParkingNotification a").on("click", (function(_this) {
56088        return function(e) {
56089          e.preventDefault();
56090          $("#openNewParkingNotification").collapse("hide");
56091          $("#newParkingNotificationFields").collapse("show");
56092          return _this.renderParkingNotificationForm();
56093        };
56094      })(this));
56095    };
56096
56097    BikesShow.prototype.initializeImpoundClaimPanel = function() {
56098      $('#impound_claim form').dirtyForms();
56099      return $("#submitClaimButton").on("click", (function(_this) {
56100        return function(e) {
56101          e.preventDefault();
56102          $("#impound_claim #impound_claim_status").val("submitting");
56103          return $("#impound_claim form").submit();
56104        };
56105      })(this));
56106    };
56107
56108    BikesShow.prototype.initializeThumbnailSwitching = function() {
56109      window.current_photo_template = $('#current-photo-template').html();
56110      Mustache.parse(window.current_photo_template);
56111      return setTimeout(((function(_this) {
56112        return function() {
56113          return _this.setThumbnailOverflow(_this.isVerticalLayout());
56114        };
56115      })(this)), 500);
56116    };
56117
56118    BikesShow.prototype.isVerticalLayout = function() {
56119      return $(window).width() > 768;
56120    };
56121
56122    BikesShow.prototype.setThumbnailOverflow = function(is_vertical_layout) {
56123      var thumbnails_height, thumbnails_width;
56124      if (is_vertical_layout) {
56125        $('#thumbnails').css('width', 'auto');
56126        thumbnails_height = $('#thumbnails li').length * $('#thumbnails li:first').outerHeight(true);
56127        if (thumbnails_height > $('#thumbnail-photos').height()) {
56128          return $('.bike-photos').addClass('overflown');
56129        }
56130      } else {
56131        thumbnails_width = $('#thumbnails li').length * $('#thumbnails li:first').outerWidth(true);
56132        $('#thumbnails').css('width', thumbnails_width + "px");
56133        if (thumbnails_width > $('#thumbnail-photos').width()) {
56134          return $('.bike-photos').addClass('overflown');
56135        }
56136      }
56137    };
56138
56139    BikesShow.prototype.rotatePhotosOnArrows = function(event) {
56140      var pos;
56141      if (event.keyCode === 39) {
56142        pos = parseInt($('#selected-photo .current-photo').data('pos'), 10);
56143        pos = pos + 1;
56144        if (pos > $('#thumbnail-photos').data('length')) {
56145          pos = 1;
56146        }
56147        return this.shiftToPhoto(pos, true);
56148      } else if (event.keyCode === 37) {
56149        pos = parseInt($('#selected-photo .current-photo').data('pos'), 10);
56150        pos = pos - 1;
56151        if (pos <= 0) {
56152          pos = $('#thumbnail-photos').data('length');
56153        }
56154        return this.shiftToPhoto(pos, true);
56155      }
56156    };
56157
56158    BikesShow.prototype.shiftToPhoto = function(pos, scroll_to_thumb) {
56159      var $target_photo, $thumbs, offset, target_photo_id;
56160      if (scroll_to_thumb == null) {
56161        scroll_to_thumb = false;
56162      }
56163      target_photo_id = $("#selected-photo div[data-pos='" + pos + "']").prop('id');
56164      $target_photo = $("#thumbnail-photos a[data-id='" + target_photo_id + "']");
56165      if (target_photo_id) {
56166        this.photoFadeOut(target_photo_id, $target_photo);
56167        if (scroll_to_thumb && $target_photo.offset()) {
56168          $thumbs = $('#thumbnail-photos');
56169          if (this.isVerticalLayout()) {
56170            offset = $target_photo.offset().top - $thumbs.offset().top;
56171            return $thumbs.animate({
56172              scrollTop: offset
56173            }, 'fast');
56174          } else {
56175
56176          }
56177        }
56178      } else {
56179        return this.loadPhotos();
56180      }
56181    };
56182
56183    BikesShow.prototype.clickPhoto = function(event) {
56184      var $target_photo, target_photo_id;
56185      event.preventDefault();
56186      $target_photo = $(event.target).parents('.clickable-image');
56187      target_photo_id = $target_photo.attr('data-id');
56188      return this.photoFadeOut(target_photo_id, $target_photo);
56189    };
56190
56191    BikesShow.prototype.photoFadeOut = function(target_photo_id, $target_photo) {
56192      $('#selected-photo .current-photo').addClass('transitioning-photo').removeClass('current-photo');
56193      return this.photoFadeIn(target_photo_id, $target_photo);
56194    };
56195
56196    BikesShow.prototype.injectPhoto = function(target_photo_id, $target_photo) {
56197      var attrs;
56198      attrs = {
56199        id: target_photo_id,
56200        alt: $target_photo.attr('alt'),
56201        src: $target_photo.data('img'),
56202        original: $target_photo.data('link'),
56203        image_id: $target_photo.find('img').prop('id')
56204      };
56205      return $('#selected-photo').append(Mustache.render(window.current_photo_template, attrs));
56206    };
56207
56208    BikesShow.prototype.loadPhotos = function() {
56209      var $target_photo, i, index, j, len, li, ref, target_photo_id;
56210      if (window.bike_photos_loaded) {
56211        return true;
56212      }
56213      if (!($('#thumbnail-photos li').length > 0)) {
56214        return true;
56215      }
56216      $('#thumbnail-photos').data('length', $('#thumbnail-photos li').length);
56217      ref = $('#thumbnail-photos li');
56218      for (index = j = 0, len = ref.length; j < len; index = ++j) {
56219        li = ref[index];
56220        $target_photo = $(li).find('.clickable-image');
56221        target_photo_id = $target_photo.attr('data-id');
56222        if (!($("#" + target_photo_id).length > 0)) {
56223          this.injectPhoto(target_photo_id, $target_photo);
56224        }
56225        i = index + 1;
56226        $("#" + target_photo_id).attr('data-pos', i);
56227      }
56228      return window.bike_photos_loaded = true;
56229    };
56230
56231    BikesShow.prototype.photoFadeIn = function(target_photo_id, $target_photo) {
56232      if (!($("#" + target_photo_id).length > 0)) {
56233        this.injectPhoto(target_photo_id, $target_photo);
56234        this.loadPhotos();
56235      }
56236      $("#" + target_photo_id + ", #" + target_photo_id + " img").css('display', 'block');
56237      $("#" + target_photo_id).addClass('current-photo').removeClass('transitioning-photo');
56238      $("#thumbnail-photos a").removeClass('current-thumb');
56239      $("#thumbnail-photos a[data-id='" + target_photo_id + "']").addClass('current-thumb');
56240      setTimeout((function() {
56241        $('#selected-photo .transitioning-photo').hide();
56242        return $('#selected-photo .transitioning-photo').removeClass('transitioning-photo current-photo');
56243      }), 900);
56244      this.setIdealImageHeight(target_photo_id);
56245      return this.setThumbnailOverflow(this.isVerticalLayout());
56246    };
56247
56248    BikesShow.prototype.setIdealImageHeight = function(target_photo_id) {
56249      var ideal_height;
56250      if (target_photo_id == null) {
56251        target_photo_id = null;
56252      }
56253      target_photo_id || (target_photo_id = $('#selected-photo .current-photo').prop('id'));
56254      ideal_height = $(window).height() * 0.75;
56255      return $("#" + target_photo_id + " img").css('max-height', ideal_height + "px").css('width', "auto");
56256    };
56257
56258    return BikesShow;
56259
56260  })(BikeIndex);
56261
56262}).call(this);
56263(function() {
56264  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56265    hasProp = {}.hasOwnProperty;
56266
56267  BikeIndex.Payments = (function(superClass) {
56268    extend(Payments, superClass);
56269
56270    function Payments() {
56271      this.initializeEventListeners();
56272      this.t = window.BikeIndex.translator("payments");
56273    }
56274
56275    Payments.prototype.initializeEventListeners = function() {
56276      $('#new-payment-form').submit((function(_this) {
56277        return function(e) {
56278          return _this.submitDonation();
56279        };
56280      })(this));
56281      $('.amount-list button[data-amount]').click((function(_this) {
56282        return function(e) {
56283          return _this.selectPaymentOption(e);
56284        };
56285      })(this));
56286      $('.amount-list input').focus((function(_this) {
56287        return function(e) {
56288          var $target, is_arbitrary_with_value;
56289          $target = $(e.target);
56290          is_arbitrary_with_value = $target.attr("id") === "arbitrary-amount" && $target.val();
56291          if ($target.attr("data-amount") || is_arbitrary_with_value) {
56292            _this.selectPaymentOption(e);
56293          }
56294          return true;
56295        };
56296      })(this));
56297      return $('.amount-list input').on('input', (function(_this) {
56298        return function(e) {
56299          var $target;
56300          $target = $(e.target);
56301          if ($target.val()) {
56302            return _this.selectPaymentOption(e);
56303          } else {
56304            return $target.removeClass('active');
56305          }
56306        };
56307      })(this));
56308    };
56309
56310    Payments.prototype.getAmountCentsSelected = function() {
56311      var $active, amount_cents;
56312      if (!($('.amount-list .active').length > 0)) {
56313        window.BikeIndexAlerts.add('info', this.t("select_or_enter_amount"));
56314        return null;
56315      }
56316      $active = $('.amount-list .active');
56317      if ($active.attr('id') !== 'arbitrary-amount') {
56318        return $active.data('amount');
56319      }
56320      amount_cents = parseFloat($active.val()) * 100;
56321      if (amount_cents > 100) {
56322        return amount_cents;
56323      }
56324      window.BikeIndexAlerts.add('info', this.t('enter_the_minimum_amount'));
56325      return null;
56326    };
56327
56328    Payments.prototype.selectPaymentOption = function(e) {
56329      var $target;
56330      $target = $(e.currentTarget);
56331      e.preventDefault();
56332      $('.amount-list .active').removeClass('active');
56333      return $target.addClass('active');
56334    };
56335
56336    Payments.prototype.submitDonation = function() {
56337      var amount_cents;
56338      amount_cents = this.getAmountCentsSelected();
56339      if (!amount_cents) {
56340        return false;
56341      }
56342      $('.primary-alert-block .alert').remove();
56343      localStorage.setItem("hideDonationModal", "true");
56344      $("#new-payment-form #is_arbitrary").val($('.amount-list input.active').length > 0);
56345      $("#new-payment-form #payment_amount_cents").val(amount_cents);
56346      return true;
56347    };
56348
56349    return Payments;
56350
56351  })(BikeIndex);
56352
56353}).call(this);
56354(function() {
56355  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56356    hasProp = {}.hasOwnProperty;
56357
56358  BikeIndex.InfoWhere = (function(superClass) {
56359    extend(InfoWhere, superClass);
56360
56361    function InfoWhere() {
56362      this.initializeEventListeners();
56363      google.maps.event.addDomListener(window, 'load', this.initializeMap);
56364    }
56365
56366    InfoWhere.prototype.initializeEventListeners = function() {
56367      return $('a.where-shop-location').click((function(_this) {
56368        return function(e) {
56369          _this.updateMapLocation(e);
56370          return $('html').animate({
56371            scrollTop: ($('#map_canvas').offset().top - 100) + "px"
56372          }, 'fast');
56373        };
56374      })(this));
56375    };
56376
56377    InfoWhere.prototype.initializeMap = function() {
56378      return createMap(40.111689, -96.81839, 4);
56379    };
56380
56381    InfoWhere.prototype.updateMapLocation = function(event) {
56382      var latLng, target;
56383      target = $(event.target);
56384      latLng = new google.maps.LatLng(target.attr('data-lat'), target.attr('data-long'));
56385      window.map.setZoom(13);
56386      return window.map.panTo(latLng);
56387    };
56388
56389    return InfoWhere;
56390
56391  })(BikeIndex);
56392
56393}).call(this);
56394(function() {
56395  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56396    hasProp = {}.hasOwnProperty;
56397
56398  BikeIndex.LandingPage = (function(superClass) {
56399    extend(LandingPage, superClass);
56400
56401    function LandingPage() {
56402      var header_offset;
56403      $(".tryPaidButton").on("click", (function(_this) {
56404        return function(e) {
56405          var plan;
56406          e.preventDefault();
56407          plan = $(e.target).attr("data-plan");
56408          return _this.submitOrganizationPaidPlan(plan);
56409        };
56410      })(this));
56411      if ($(window).width() > 767) {
56412        header_offset = $('.primary-header-nav').outerHeight();
56413        $('.next-steps-wrap').css('top', header_offset + "px");
56414        $('.next-steps-wrap').Stickyfill();
56415      }
56416    }
56417
56418    LandingPage.prototype.submitOrganizationPaidPlan = function(plan) {
56419      if (plan != null) {
56420        $("#organizationSignupModal #feedback_body").val(plan);
56421        $("#organizationSignupModal #feedback_package_size").val(plan);
56422      }
56423      return $("#organizationSignupModal").modal("show");
56424    };
56425
56426    return LandingPage;
56427
56428  })(BikeIndex);
56429
56430}).call(this);
56431(function() {
56432  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56433    hasProp = {}.hasOwnProperty;
56434
56435  BikeIndex.LocksForm = (function(superClass) {
56436    extend(LocksForm, superClass);
56437
56438    function LocksForm() {
56439      var locks_other_id;
56440      locks_other_id = $('.manufacturer-select').data('otherid');
56441      new BikeIndex.ToggleHiddenOther('#lock_manufacturer_id', locks_other_id);
56442    }
56443
56444    return LocksForm;
56445
56446  })(BikeIndex);
56447
56448}).call(this);
56449(function() {
56450  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56451    hasProp = {}.hasOwnProperty;
56452
56453  BikeIndex.OrganizedManageLocations = (function(superClass) {
56454    var $locations_fieldsets;
56455
56456    extend(OrganizedManageLocations, superClass);
56457
56458    $locations_fieldsets = $('#locations_fieldsets');
56459
56460    function OrganizedManageLocations() {
56461      this.initializeEventListeners();
56462    }
56463
56464    OrganizedManageLocations.prototype.initializeEventListeners = function() {
56465      var hideRemoveIfOnlyOne, loadFancySelects, updateImpoundedChecks, updateVisibilityChecks;
56466      loadFancySelects = this.loadFancySelects;
56467      updateVisibilityChecks = this.updateVisibilityChecks;
56468      updateImpoundedChecks = this.updateImpoundedChecks;
56469      hideRemoveIfOnlyOne = this.hideRemoveIfOnlyOne;
56470      updateVisibilityChecks();
56471      updateImpoundedChecks();
56472      hideRemoveIfOnlyOne();
56473      $("form").on("click", ".remove_fields", function(event) {
56474        var $form;
56475        $form = $(this).closest("fieldset").parents(".collapse");
56476        $form.collapse("hide");
56477        $form.find("input:required").attr("required", false);
56478        hideRemoveIfOnlyOne();
56479        return true;
56480      });
56481      $("form").on("click", ".add_fields", function(event) {
56482        var regexp, time;
56483        event.preventDefault();
56484        time = new Date().getTime();
56485        regexp = new RegExp($(this).data("id"), "g");
56486        $("#fieldsetend").before($(this).data("fields").replace(regexp, time));
56487        loadFancySelects();
56488        updateVisibilityChecks();
56489        hideRemoveIfOnlyOne();
56490        return true;
56491      });
56492      $("#organization_show_on_map").on("change", function(event) {
56493        return updateVisibilityChecks();
56494      });
56495      $("form").on("change", ".impoundLocationCheck", function(event) {
56496        return updateImpoundedChecks();
56497      });
56498      return $("form").on("change", ".defaultImpoundLocationCheck", function(event) {
56499        var targetID;
56500        targetID = $(event.target).attr("id");
56501        $(".defaultImpoundLocationCheck").each(function() {
56502          var $check;
56503          $check = $(this);
56504          if ($check.attr("id") !== targetID) {
56505            return $check.prop("checked", false);
56506          }
56507        });
56508        return updateImpoundedChecks();
56509      });
56510    };
56511
56512    OrganizedManageLocations.prototype.updateImpoundedChecks = function() {
56513      var $defaultChecked;
56514      if ($(".impoundLocationCheck:checked").length > 1) {
56515        return $(".defaultImpoundLocationCheckWrapper").collapse("show");
56516      } else {
56517        $(".defaultImpoundLocationCheckWrapper").collapse("hide");
56518        if ($(".impoundLocationCheck:checked").length === 1) {
56519          $defaultChecked = $(".impoundLocationCheck:checked").parents("fieldset").find(".defaultImpoundLocationCheck");
56520          $defaultChecked.prop("checked", true);
56521          return $(".defaultImpoundLocationCheck").each(function() {
56522            var $check;
56523            $check = $(this);
56524            if ($check.attr("id") !== $defaultChecked.attr("id")) {
56525              return $check.prop("checked", false);
56526            }
56527          });
56528        }
56529      }
56530    };
56531
56532    OrganizedManageLocations.prototype.updateVisibilityChecks = function() {
56533      var visibility;
56534      if ($("#organization_show_on_map").prop("checked")) {
56535        visibility = "show";
56536      } else {
56537        visibility = "hide";
56538      }
56539      return $(".publiclyVisibilyCheck").collapse(visibility);
56540    };
56541
56542    OrganizedManageLocations.prototype.hideRemoveIfOnlyOne = function() {
56543      return setTimeout(((function(_this) {
56544        return function() {
56545          if ($(".locations-fieldset-wrapper .location-card:visible").length < 2) {
56546            return $(".locations-fieldset-wrapper .location-card .remove-control").collapse("hide");
56547          } else {
56548            return $(".locations-fieldset-wrapper .location-card .remove-control").collapse("show");
56549          }
56550        };
56551      })(this)), 500);
56552    };
56553
56554    return OrganizedManageLocations;
56555
56556  })(BikeIndex);
56557
56558}).call(this);
56559(function() {
56560  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56561    hasProp = {}.hasOwnProperty;
56562
56563  BikeIndex.StolenBikeListing = (function(superClass) {
56564    extend(StolenBikeListing, superClass);
56565
56566    function StolenBikeListing() {
56567      new BikeIndex.BikeSearchBar;
56568      new BikeIndex.BikeBoxes;
56569      window.photoModalOpen = false;
56570      $(".listing-text-expand-link").click(function(e) {
56571        var $expander, $target;
56572        e.preventDefault();
56573        $target = $(e.target);
56574        $target.css("display", "none");
56575        $expander = $($target.attr("href"));
56576        return $expander.slideDown('fast', function() {
56577          $expander.addClass("listing-text-shown");
56578          return $expander.css("display", "inline-block");
56579        });
56580      });
56581      $(".listing-images a").click((function(_this) {
56582        return function(e) {
56583          return _this.clickPhoto(e);
56584        };
56585      })(this));
56586      $(document).keyup((function(_this) {
56587        return function(e) {
56588          return _this.rotatePhotosOrCloseModal(e);
56589        };
56590      })(this));
56591      $(document).on('hide.bs.modal', function() {
56592        window.photoModalOpen = false;
56593        window.photoExpandedId = null;
56594        return true;
56595      });
56596      $("body").on("click", ".modal .close", function(e) {
56597        return $(e.target).parents(".modal").modal("hide");
56598      });
56599    }
56600
56601    StolenBikeListing.prototype.clickPhoto = function(e) {
56602      var $target;
56603      e.preventDefault();
56604      $target = $(e.target);
56605      if (!$target.is("a")) {
56606        $target = $target.parents("a");
56607      }
56608      if (!$target.is("a")) {
56609        return true;
56610      }
56611      return this.openPhotoModal($target.attr('id'), $target.attr("href"));
56612    };
56613
56614    StolenBikeListing.prototype.openPhotoModal = function(id, href) {
56615      var modal_html, modal_id;
56616      window.photoExpandedId = id;
56617      window.photoModalOpen = true;
56618      modal_id = id + "-modal";
56619      modal_html = "<div class='modal fade stolen-listing-photo-modal' id='" + modal_id + "'><div class='modal-dialog' role='document'><div class='modal-content'>";
56620      modal_html += "<div class='modal-title'><button class='close' 'aria-label'='Close' 'data-dismiss'='modal' type='button'>&times;</button></div>";
56621      modal_html += "<a href='" + href + "'><img src='" + href + "'></a>";
56622      modal_html += "</div></div></div>";
56623      $("#stolen_bike_listings_index").append(modal_html);
56624      return $("#" + modal_id).modal("show");
56625    };
56626
56627    StolenBikeListing.prototype.lookupPhoto = function(direction) {
56628      var $targetPhoto, currentListingId, ids, photoIndex, targetPhotoId, targetPhotoIndex;
56629      if (!window.photoExpandedId) {
56630        return true;
56631      }
56632      ids = window.photoExpandedId.split("-").map(function(s) {
56633        return parseInt(s, 10);
56634      });
56635      currentListingId = ids[0];
56636      photoIndex = ids[1];
56637      if (direction === "forward") {
56638        targetPhotoIndex = photoIndex + 1;
56639      } else {
56640        targetPhotoIndex = photoIndex - 1;
56641      }
56642      if (targetPhotoIndex < 0) {
56643        console.log("First photo, can't go before it!");
56644        return true;
56645      }
56646      targetPhotoId = currentListingId + "-" + targetPhotoIndex;
56647      $targetPhoto = $("#" + targetPhotoId);
56648      if (!$targetPhoto.length) {
56649        console.log("photo not found (probably last photo) - " + targetPhotoId);
56650        return true;
56651      }
56652      $('.modal').modal('hide');
56653      return this.openPhotoModal(targetPhotoId, $targetPhoto.attr("href"));
56654    };
56655
56656    StolenBikeListing.prototype.rotatePhotosOrCloseModal = function(event) {
56657      if (!window.photoModalOpen) {
56658        return true;
56659      }
56660      if (event.keyCode === 27) {
56661        $('.modal').modal('hide');
56662      } else if (event.keyCode === 39) {
56663        this.lookupPhoto("forward");
56664      } else if (event.keyCode === 37) {
56665        this.lookupPhoto("backward");
56666      }
56667      return true;
56668    };
56669
56670    return StolenBikeListing;
56671
56672  })(BikeIndex);
56673
56674}).call(this);
56675(function() {
56676  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56677    hasProp = {}.hasOwnProperty;
56678
56679  BikeIndex.ChooseRegistration = (function(superClass) {
56680    extend(ChooseRegistration, superClass);
56681
56682    function ChooseRegistration() {
56683      this.SetInitialRegistrationType();
56684      $('a.choose-type').click((function(_this) {
56685        return function(e) {
56686          e.preventDefault();
56687          return _this.updateBikeLink(e);
56688        };
56689      })(this));
56690    }
56691
56692    ChooseRegistration.prototype.updateBikeLink = function(e) {
56693      var $target;
56694      $target = $(e.target);
56695      if (!$target.hasClass('choose-type')) {
56696        $target = $target.parents('.choose-type');
56697      }
56698      return this.chooseBikeLink($target);
56699    };
56700
56701    ChooseRegistration.prototype.chooseBikeLink = function($target) {
56702      var new_location;
56703      $('.choose-type').removeClass('current-choice').removeAttr('aria-current');
56704      $target.addClass('current-choice').attr('aria-current', 'true');
56705      new_location = $target.attr('href');
56706      return $('#add-bike').attr('href', new_location);
56707    };
56708
56709    ChooseRegistration.prototype.SetInitialRegistrationType = function() {
56710      var $target;
56711      $target = $('.purchase-choice');
56712      if ($('.free-tix-choice').length > 0) {
56713        $target = $('.free-tix-choice').first();
56714      }
56715      if ($('.organization-choice').length > 0) {
56716        $target = $('.organization-choice').first();
56717      }
56718      return this.chooseBikeLink($target);
56719    };
56720
56721    return ChooseRegistration;
56722
56723  })(BikeIndex);
56724
56725}).call(this);
56726(function() {
56727  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56728    hasProp = {}.hasOwnProperty;
56729
56730  BikeIndex.UserHome = (function(superClass) {
56731    extend(UserHome, superClass);
56732
56733    function UserHome() {
56734      new BikeIndex.BikeBoxes;
56735    }
56736
56737    return UserHome;
56738
56739  })(BikeIndex);
56740
56741}).call(this);
56742(function() {
56743  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56744    hasProp = {}.hasOwnProperty;
56745
56746  BikeIndex.UsersEdit = (function(superClass) {
56747    extend(UsersEdit, superClass);
56748
56749    function UsersEdit() {
56750      var united_states_id;
56751      new FormWellMenu;
56752      if ($('.sharing-collapser').length > 0) {
56753        this.initializePersonalSharing();
56754      }
56755      if ($('#additional-email-template').length > 0) {
56756        this.initializeAdditionalEmails();
56757      }
56758      if ($('#myAccountRegistrationOrganizations').length > 0) {
56759        this.initializeRegistrationOrganizations();
56760      }
56761      united_states_id = $('#us_id_data').data('usid');
56762      new BikeIndex.ToggleHiddenOther('.country-select-input', united_states_id);
56763    }
56764
56765    UsersEdit.prototype.initializePersonalSharing = function() {
56766      var $field, $personal_fields, field, j, len, show_field;
56767      $personal_fields = $('.sharing-collapser');
56768      for (j = 0, len = $personal_fields.length; j < len; j++) {
56769        field = $personal_fields[j];
56770        $field = $(field);
56771        show_field = $field.find('input:checked').val();
56772        if (show_field === 'true') {
56773          $($field.data('target')).collapse('show');
56774        }
56775      }
56776      $('.sharing-collapser input').change(function() {
56777        var collapser;
56778        collapser = $(this).parents('.sharing-collapser').data('target');
56779        return $(collapser).collapse('toggle');
56780      });
56781      return $('.avatar-upload-field').change(function(event) {
56782        var name;
56783        name = event.target.files[0].name;
56784        return $(event.target).parent().find('.file-upload-text').text(name);
56785      });
56786    };
56787
56788    UsersEdit.prototype.initializeAdditionalEmails = function() {
56789      var add_email_template, num;
56790      add_email_template = $('#additional-email-template').html();
56791      Mustache.parse(add_email_template);
56792      num = 0;
56793      $('#add_additional_email').click(function(e) {
56794        num += 1;
56795        e.preventDefault();
56796        $('#additional_email_fields').append(Mustache.render(add_email_template, {
56797          num: num
56798        }));
56799        new window.CheckEmail("#additional_email_field_" + num);
56800        return $('#additional_email_fields .collapse').collapse('show');
56801      });
56802      $('#additional_email_fields').on('change', '.add-email-field', (function(_this) {
56803        return function(e) {
56804          return _this.updateAdditionalEmailValues();
56805        };
56806      })(this));
56807      return $('#additional_email_fields').on('click', '.remove-add-email', (function(_this) {
56808        return function(e) {
56809          var $add_email_field;
56810          $add_email_field = $(e.target).parents('.form-group');
56811          $add_email_field.collapse('hide');
56812          return window.setTimeout((function() {
56813            $add_email_field.remove();
56814            return _this.updateAdditionalEmailValues();
56815          }), 1000);
56816        };
56817      })(this));
56818    };
56819
56820    UsersEdit.prototype.updateAdditionalEmailValues = function() {
56821      var values;
56822      values = $('#additional_email_fields .add-email-field').get().map(function(i) {
56823        return i.value;
56824      });
56825      return $('#user_additional_emails').val(values);
56826    };
56827
56828    UsersEdit.prototype.initializeRegistrationOrganizations = function() {
56829      return $(".allBikesCheck").change(function(event) {
56830        var $target, $uro_fields, checked;
56831        $target = $(event.target);
56832        checked = $target.prop('checked');
56833        $uro_fields = $(event.target).parents(".userRegistrationOrganization");
56834        if (checked) {
56835          $uro_fields.find(".collapse-NotAllBikes").collapse("hide");
56836          return $uro_fields.find(".collapse-AllBikes").collapse("show");
56837        } else {
56838          $uro_fields.find(".collapse-NotAllBikes").collapse("show");
56839          return $uro_fields.find(".collapse-AllBikes").collapse("hide");
56840        }
56841      });
56842    };
56843
56844    return UsersEdit;
56845
56846  })(BikeIndex);
56847
56848}).call(this);
56849(function() {
56850  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
56851    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56852    hasProp = {}.hasOwnProperty;
56853
56854  BikeIndex.WelcomeIndex = (function(superClass) {
56855    extend(WelcomeIndex, superClass);
56856
56857    function WelcomeIndex() {
56858      this.translateText = bind(this.translateText, this);
56859      this.slideText = bind(this.slideText, this);
56860      this.findSlide = bind(this.findSlide, this);
56861      if (!$('#recovery-stories-container').length) {
56862        return;
56863      }
56864      this.translator = new BikeIndex.GoogleTranslate();
56865      this.container = $('#recovery-stories-container');
56866      this.container.removeClass('extras-hidden');
56867      this.container.slick({
56868        infinite: false,
56869        lazyLoad: 'ondemand',
56870        prevArrow: '<span class="slick-prev"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-chevron-left" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0"/></svg></span>',
56871        nextArrow: '<span class="slick-next"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"/></svg></span>',
56872        onBeforeChange: (function(_this) {
56873          return function(slick, curr_i, target_i) {
56874            return _this.translateText(target_i);
56875          };
56876        })(this),
56877        onInit: (function(_this) {
56878          return function(slick) {
56879            return _this.translateText(0);
56880          };
56881        })(this)
56882      });
56883      $(window).scroll(function() {
56884        return $('.root-landing-who').addClass('scrolled');
56885      });
56886    }
56887
56888    WelcomeIndex.prototype.findSlide = function(index) {
56889      return this.container.find(".js-recovery-slide")[index];
56890    };
56891
56892    WelcomeIndex.prototype.slideText = function($slide, textValue) {
56893      var $container;
56894      $container = $slide.find(".precovery");
56895      if (!textValue) {
56896        return $container.text().trim();
56897      }
56898      return $container.text(textValue);
56899    };
56900
56901    WelcomeIndex.prototype.translateText = function(index) {
56902      var $slide, slide, text;
56903      if (I18n.locale === "en") {
56904        return;
56905      }
56906      slide = this.findSlide(index);
56907      if (!slide) {
56908        return;
56909      }
56910      $slide = $(slide);
56911      if ($slide.data("translated")) {
56912        return;
56913      }
56914      text = this.slideText($slide);
56915      return this.translator.translate(text).then((function(_this) {
56916        return function(translatedText) {
56917          if (!translatedText) {
56918            return;
56919          }
56920          _this.slideText($slide, translatedText);
56921          $slide.data("translated", true);
56922          return $slide.find(".translation-credit").toggleClass("d-none");
56923        };
56924      })(this));
56925    };
56926
56927    return WelcomeIndex;
56928
56929  })(BikeIndex);
56930
56931}).call(this);
56932(function() {
56933  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
56934    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56935    hasProp = {}.hasOwnProperty;
56936
56937  BikeIndex.WelcomeRecoveryStories = (function(superClass) {
56938    extend(WelcomeRecoveryStories, superClass);
56939
56940    function WelcomeRecoveryStories(container) {
56941      this.slideText = bind(this.slideText, this);
56942      this.translateText = bind(this.translateText, this);
56943      this.translator = new BikeIndex.GoogleTranslate();
56944      this.$slides = $("#recovery-stories-listing").find(".js-recovery-slide");
56945      this.translateText();
56946    }
56947
56948    WelcomeRecoveryStories.prototype.translateText = function(index) {
56949      if (I18n.locale === "en") {
56950        return;
56951      }
56952      return this.$slides.each((function(_this) {
56953        return function(i, slide) {
56954          var $slide, text;
56955          $slide = $(slide);
56956          if ($slide.data("translated")) {
56957            return;
56958          }
56959          text = _this.slideText($slide);
56960          return _this.translator.translate(text).then(function(translatedText) {
56961            if (!translatedText) {
56962              return;
56963            }
56964            _this.slideText($slide, translatedText);
56965            $slide.data("translated", true);
56966            return $slide.find(".translation-credit").toggleClass("d-none");
56967          });
56968        };
56969      })(this));
56970    };
56971
56972    WelcomeRecoveryStories.prototype.slideText = function($slide, textValue) {
56973      var $container;
56974      $container = $slide.find(".precovery");
56975      if (!textValue) {
56976        return $container.text().trim();
56977      }
56978      return $container.text(textValue);
56979    };
56980
56981    return WelcomeRecoveryStories;
56982
56983  })(BikeIndex);
56984
56985}).call(this);
56986(function() {
56987  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
56988    hasProp = {}.hasOwnProperty;
56989
56990  BikeIndex.BikeBoxes = (function(superClass) {
56991    extend(BikeBoxes, superClass);
56992
56993    function BikeBoxes() {
56994      this.initializeHoverExpand();
56995    }
56996
56997    BikeBoxes.prototype.initializeHoverExpand = function() {
56998      var hoverExpand;
56999      hoverExpand = this.hoverExpand;
57000      window.hoverExpandBlockTemplate = this.hoverExpandBlockTemplate();
57001      Mustache.parse(window.hoverExpandBlockTemplate);
57002      if (!('ontouchstart' in document.documentElement)) {
57003        $('body').on("mouseenter", ".hover-expand", function() {
57004          var $target;
57005          $target = $(this);
57006          hoverExpand($target);
57007          return $target.addClass('img-expanded');
57008        });
57009        return $('body').on("mouseleave", ".hover-expand", function() {
57010          var $target;
57011          $target = $(this);
57012          return $target.removeClass('img-expanded');
57013        });
57014      }
57015    };
57016
57017    BikeBoxes.prototype.hoverExpand = function($target) {
57018      var data, img_src;
57019      if ($target.find('.hover-expand-block').length > 0) {
57020        return true;
57021      }
57022      img_src = $target.data('img-src') || $target.find('img').prop('src');
57023      data = {
57024        title: $target.parents('.bike-box-item').find('.title-link').text(),
57025        img_src: img_src.replace(/\/small_/, '/medium_')
57026      };
57027      return $target.append(Mustache.to_html(window.hoverExpandBlockTemplate, data));
57028    };
57029
57030    BikeBoxes.prototype.hoverExpandBlockTemplate = function() {
57031      return "<div class=\"hover-expand-block\">\n  <img src=\"{{img_src}}\">\n  <p>{{title}}</p>\n</div>";
57032    };
57033
57034    return BikeBoxes;
57035
57036  })(BikeIndex);
57037
57038}).call(this);
57039(function() {
57040  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
57041    hasProp = {}.hasOwnProperty,
57042    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
57043
57044  BikeIndex.BikeSearchBar = (function(superClass) {
57045    extend(BikeSearchBar, superClass);
57046
57047    function BikeSearchBar(target_selector) {
57048      var $location;
57049      if (target_selector == null) {
57050        target_selector = '#bikes_search_form #query_items';
57051      }
57052      this.setCategories();
57053      this.initializeHeaderSearch($(target_selector));
57054      $location = $('#location');
57055      if ($location.length > 0) {
57056        this.setSearchProximity($location);
57057      }
57058      this.initializeEventListeners();
57059    }
57060
57061    BikeSearchBar.prototype.initializeEventListeners = function() {
57062      return $('#stolenness_tabs a').click((function(_this) {
57063        return function(e) {
57064          var tab;
57065          if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
57066            return;
57067          }
57068          tab = $(e.target).parents('li');
57069          $('#stolenness').val(tab.attr('data-stolenness'));
57070          $('#bikes_search_form').submit();
57071          return false;
57072        };
57073      })(this));
57074    };
57075
57076    BikeSearchBar.prototype.setSearchProximity = function($location) {
57077      var location, location_data;
57078      location = $location.val();
57079      location = location != null ? location.replace(/^\s*|\s*$/g, '') : '';
57080      if (window.interpreted_params.location != null) {
57081        location_data = window.interpreted_params.location;
57082        if (Array.isArray(location_data)) {
57083          location = location_data.join(', ');
57084          $('#location').val(location);
57085        }
57086      }
57087      if ((location != null) && location.length > 0) {
57088        if (!location.match(/anywhere/i)) {
57089          localStorage.setItem('location', location);
57090          localStorage.setItem('distance', $('#distance').val());
57091        }
57092      } else {
57093        location = localStorage.getItem('location');
57094        if ((location == null) || location.match(/anywhere/i)) {
57095          location = 'you';
57096        }
57097        $location.val(location);
57098      }
57099      return this.setSearchTabInfo(location);
57100    };
57101
57102    BikeSearchBar.prototype.setSearchTabInfo = function(location) {
57103      var search_data;
57104      $('#search_distance').text($('#distance').val());
57105      $('#search_location').text(location);
57106      search_data = _.merge(window.interpreted_params, {
57107        location: location
57108      });
57109      return $.ajax({
57110        type: 'GET',
57111        url: '/api/v3/search/count',
57112        data: search_data,
57113        success: (function(_this) {
57114          return function(data) {
57115            return _this.insertTabCounts(data);
57116          };
57117        })(this)
57118      });
57119    };
57120
57121    BikeSearchBar.prototype.displayedCountNumber = function(number) {
57122      if (number > 999) {
57123        if (number > 9999) {
57124          number = '10k+';
57125        } else {
57126          number = (String(number).charAt(0)) + "k+";
57127        }
57128      }
57129      return "(" + number + ")";
57130    };
57131
57132    BikeSearchBar.prototype.insertTabCounts = function(counts) {
57133      var count, j, len, ref, results, stolenness;
57134      ref = Object.keys(counts);
57135      results = [];
57136      for (j = 0, len = ref.length; j < len; j++) {
57137        stolenness = ref[j];
57138        count = this.displayedCountNumber(counts[stolenness]);
57139        results.push($("#stolenness_tab_" + stolenness + " .count").text(count));
57140      }
57141      return results;
57142    };
57143
57144    BikeSearchBar.prototype.initializeHeaderSearch = function($query_field) {
57145      var $desc_search, formatSearchText, initial_opts, per_page, processedResults;
57146      per_page = 15;
57147      $('.query-field-wrap').removeClass('nojs');
57148      $('.query-field#query').remove();
57149      initial_opts = $query_field.data('initial') ? $query_field.data('initial') : [];
57150      processedResults = this.processedResults;
57151      formatSearchText = this.formatSearchText;
57152      $desc_search = $query_field.select2({
57153        allowClear: true,
57154        tags: true,
57155        multiple: true,
57156        openOnEnter: false,
57157        tokenSeparators: [','],
57158        placeholder: $query_field.attr('placeholder'),
57159        dropdownParent: $('.bikes-search-form'),
57160        templateResult: formatSearchText,
57161        escapeMarkup: function(markup) {
57162          return markup;
57163        },
57164        ajax: {
57165          url: '/api/autocomplete',
57166          dataType: 'json',
57167          delay: 150,
57168          data: function(params) {
57169            return {
57170              q: params.term,
57171              page: params.page,
57172              per_page: per_page,
57173              categories: window.searchBarCategories
57174            };
57175          },
57176          processResults: function(data, page) {
57177            return {
57178              results: processedResults(data.matches),
57179              pagination: {
57180                more: data.matches.length === per_page
57181              }
57182            };
57183          },
57184          cache: true
57185        }
57186      });
57187      $('.bikes-search-form .select2-selection').on('keyup', function(e) {
57188        if (e.keyCode === 27) {
57189          return window.bike_search_submit = true;
57190        }
57191        if (e.keyCode !== 13) {
57192          return window.bike_search_submit = false;
57193        }
57194        if (window.bike_search_submit) {
57195          $desc_search.select2('close');
57196          return $('#bikes_search_form').submit();
57197        } else {
57198          return window.bike_search_submit = true;
57199        }
57200      });
57201      return $query_field.on('change', (function(_this) {
57202        return function(e) {
57203          return _this.setCategories();
57204        };
57205      })(this));
57206    };
57207
57208    BikeSearchBar.prototype.processedResults = function(items) {
57209      return _.map(items, function(item) {
57210        if (typeof item === 'string') {
57211          return {
57212            id: item,
57213            text: item
57214          };
57215        }
57216        return {
57217          id: item.search_id,
57218          text: item.text,
57219          category: item.category,
57220          display: item.display
57221        };
57222      });
57223    };
57224
57225    BikeSearchBar.prototype.formatSearchText = function(item) {
57226      var p, prefix;
57227      if (item.loading) {
57228        return item.text;
57229      }
57230      if (item.category === 'propulsion') {
57231        return "<span>Search for <strong>" + item.text + "</strong> only</span>";
57232      }
57233      if (item.category === 'cycle_type') {
57234        return "<span>Search only for <strong>" + item.text + "</strong></span>";
57235      }
57236      prefix = (function() {
57237        switch (false) {
57238          case item.category !== 'colors':
57239            p = "<span class=\'sch_\'>Bikes that are </span>";
57240            if (item.display) {
57241              return p + ("<span class=\'sclr\' style=\'background: " + item.display + ";\'></span>");
57242            } else {
57243              return p + "<span class=\'sclr\'>stckrs</span>";
57244            }
57245            break;
57246          case item.category !== 'cycle_type':
57247            return "<span class=\'sch_\'>only for</span>";
57248          case !(item.category === 'cmp_mnfg' || item.category === 'frame_mnfg'):
57249            return "<span class=\'sch_\'>Bikes made by</span>";
57250          default:
57251            return 'Search for';
57252        }
57253      })();
57254      return (prefix + " <span class=\'label\'>") + item.text + '</span>';
57255    };
57256
57257    BikeSearchBar.prototype.setCategories = function() {
57258      var queried_categories, query;
57259      query = $("#bikes_search_form #query_items").val();
57260      if (!query) {
57261        query = [];
57262      }
57263      queried_categories = query.filter(function(x) {
57264        return /^(v|m)_/.test(x);
57265      }).map(function(i) {
57266        return i.split("_")[0];
57267      });
57268      if (queried_categories.length === 0) {
57269        return window.searchBarCategories = "";
57270      } else {
57271        window.searchBarCategories = "colors";
57272        if (indexOf.call(queried_categories, "v") < 0) {
57273          window.searchBarCategories += ",cycle_type";
57274        }
57275        if (indexOf.call(queried_categories, "m") < 0) {
57276          window.searchBarCategories += ",frame_mnfg,cmp_mnfg";
57277        }
57278        if (indexOf.call(queried_categories, "p") < 0) {
57279          return window.searchBarCategories += ",propulsion";
57280        }
57281      }
57282    };
57283
57284    return BikeSearchBar;
57285
57286  })(BikeIndex);
57287
57288}).call(this);
57289(function() {
57290  var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
57291    hasProp = {}.hasOwnProperty;
57292
57293  BikeIndex.Organized = (function(superClass) {
57294    extend(Organized, superClass);
57295
57296    function Organized() {
57297      $('.avatar-upload-field').change(function(event) {
57298        var name;
57299        name = event.target.files[0].name;
57300        return $(event.target).parent().find('.file-upload-text').text(name);
57301      });
57302      $("#organized-bike-code-claimedness .btn").on("click", function(event) {
57303        return window.setTimeout((function() {
57304          return $(".stickers-form").submit();
57305        }), 250);
57306      });
57307    }
57308
57309    return Organized;
57310
57311  })(BikeIndex);
57312
57313}).call(this);
57314// require self
57315
57316
57317
57318
57319// Legacy carousel. Used on homepage.
57320
57321
57322// Translations
57323
57324
57325
57326// Things that are required for File Upload:
57327
57328
57329
57330
57331
57332
57333// Our actual scripts:
57334
57335;

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