2 // http://underscorejs.org
3 // (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4 // Underscore may be freely distributed under the MIT license.
11 // Establish the root object, `window` (`self`) in the browser, `global`
12 // on the server, or `this` in some virtual machines. We use `self`
13 // instead of `window` for `WebWorker` support.
14 var root
= typeof self
== 'object' && self
.self
=== self
&& self
||
15 typeof global
== 'object' && global
.global
=== global
&& global
||
19 // Save the previous value of the `_` variable.
20 var previousUnderscore
= root
._
;
22 // Save bytes in the minified (but not gzipped) version:
23 var ArrayProto
= Array
.prototype, ObjProto
= Object
.prototype;
24 var SymbolProto
= typeof Symbol
!== 'undefined' ? Symbol
.prototype : null;
26 // Create quick reference variables for speed access to core prototypes.
27 var push
= ArrayProto
.push
,
28 slice
= ArrayProto
.slice
,
29 toString
= ObjProto
.toString
,
30 hasOwnProperty
= ObjProto
.hasOwnProperty
;
32 // All **ECMAScript 5** native function implementations that we hope to use
34 var nativeIsArray
= Array
.isArray
,
35 nativeKeys
= Object
.keys
,
36 nativeCreate
= Object
.create
;
38 // Naked function reference for surrogate-prototype-swapping.
39 var Ctor = function(){};
41 // Create a safe reference to the Underscore object for use below.
42 var _ = function(obj
) {
43 if (obj
instanceof _
) return obj
;
44 if (!(this instanceof _
)) return new _(obj
);
48 // Export the Underscore object for **Node.js**, with
49 // backwards-compatibility for their old module API. If we're in
50 // the browser, add `_` as a global object.
51 // (`nodeType` is checked to ensure that `module`
52 // and `exports` are not HTML elements.)
53 if (typeof exports
!= 'undefined' && !exports
.nodeType
) {
54 if (typeof module
!= 'undefined' && !module
.nodeType
&& module
.exports
) {
55 exports
= module
.exports
= _
;
65 // Internal function that returns an efficient (for current engines) version
66 // of the passed-in callback, to be repeatedly applied in other Underscore
68 var optimizeCb = function(func
, context
, argCount
) {
69 if (context
=== void 0) return func
;
70 switch (argCount
== null ? 3 : argCount
) {
71 case 1: return function(value
) {
72 return func
.call(context
, value
);
74 // The 2-argument case is omitted because we’re not using it.
75 case 3: return function(value
, index
, collection
) {
76 return func
.call(context
, value
, index
, collection
);
78 case 4: return function(accumulator
, value
, index
, collection
) {
79 return func
.call(context
, accumulator
, value
, index
, collection
);
83 return func
.apply(context
, arguments
);
89 // An internal function to generate callbacks that can be applied to each
90 // element in a collection, returning the desired result — either `identity`,
91 // an arbitrary callback, a property matcher, or a property accessor.
92 var cb = function(value
, context
, argCount
) {
93 if (_
.iteratee
!== builtinIteratee
) return _
.iteratee(value
, context
);
94 if (value
== null) return _
.identity
;
95 if (_
.isFunction(value
)) return optimizeCb(value
, context
, argCount
);
96 if (_
.isObject(value
) && !_
.isArray(value
)) return _
.matcher(value
);
97 return _
.property(value
);
100 // External wrapper for our callback generator. Users may customize
101 // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
102 // This abstraction hides the internal-only argCount argument.
103 _
.iteratee
= builtinIteratee = function(value
, context
) {
104 return cb(value
, context
, Infinity
);
107 // Some functions take a variable number of arguments, or a few expected
108 // arguments at the beginning and then a variable number of values to operate
109 // on. This helper accumulates all remaining arguments past the function’s
110 // argument length (or an explicit `startIndex`), into an array that becomes
111 // the last argument. Similar to ES6’s "rest parameter".
112 var restArguments = function(func
, startIndex
) {
113 startIndex
= startIndex
== null ? func
.length
- 1 : +startIndex
;
115 var length
= Math
.max(arguments
.length
- startIndex
, 0),
116 rest
= Array(length
),
118 for (; index
< length
; index
++) {
119 rest
[index
] = arguments
[index
+ startIndex
];
121 switch (startIndex
) {
122 case 0: return func
.call(this, rest
);
123 case 1: return func
.call(this, arguments
[0], rest
);
124 case 2: return func
.call(this, arguments
[0], arguments
[1], rest
);
126 var args
= Array(startIndex
+ 1);
127 for (index
= 0; index
< startIndex
; index
++) {
128 args
[index
] = arguments
[index
];
130 args
[startIndex
] = rest
;
131 return func
.apply(this, args
);
135 // An internal function for creating a new object that inherits from another.
136 var baseCreate = function(prototype) {
137 if (!_
.isObject(prototype)) return {};
138 if (nativeCreate
) return nativeCreate(prototype);
139 Ctor
.prototype = prototype;
140 var result
= new Ctor
;
141 Ctor
.prototype = null;
145 var shallowProperty = function(key
) {
146 return function(obj
) {
147 return obj
== null ? void 0 : obj
[key
];
151 var has = function(obj
, path
) {
152 return obj
!= null && hasOwnProperty
.call(obj
, path
);
155 var deepGet = function(obj
, path
) {
156 var length
= path
.length
;
157 for (var i
= 0; i
< length
; i
++) {
158 if (obj
== null) return void 0;
161 return length
? obj
: void 0;
164 // Helper for collection methods to determine whether a collection
165 // should be iterated as an array or as an object.
166 // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
167 // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
168 var MAX_ARRAY_INDEX
= Math
.pow(2, 53) - 1;
169 var getLength
= shallowProperty('length');
170 var isArrayLike = function(collection
) {
171 var length
= getLength(collection
);
172 return typeof length
== 'number' && length
>= 0 && length
<= MAX_ARRAY_INDEX
;
175 // Collection Functions
176 // --------------------
178 // The cornerstone, an `each` implementation, aka `forEach`.
179 // Handles raw objects in addition to array-likes. Treats all
180 // sparse array-likes as if they were dense.
181 _
.each
= _
.forEach = function(obj
, iteratee
, context
) {
182 iteratee
= optimizeCb(iteratee
, context
);
184 if (isArrayLike(obj
)) {
185 for (i
= 0, length
= obj
.length
; i
< length
; i
++) {
186 iteratee(obj
[i
], i
, obj
);
189 var keys
= _
.keys(obj
);
190 for (i
= 0, length
= keys
.length
; i
< length
; i
++) {
191 iteratee(obj
[keys
[i
]], keys
[i
], obj
);
197 // Return the results of applying the iteratee to each element.
198 _
.map
= _
.collect = function(obj
, iteratee
, context
) {
199 iteratee
= cb(iteratee
, context
);
200 var keys
= !isArrayLike(obj
) && _
.keys(obj
),
201 length
= (keys
|| obj
).length
,
202 results
= Array(length
);
203 for (var index
= 0; index
< length
; index
++) {
204 var currentKey
= keys
? keys
[index
] : index
;
205 results
[index
] = iteratee(obj
[currentKey
], currentKey
, obj
);
210 // Create a reducing function iterating left or right.
211 var createReduce = function(dir
) {
212 // Wrap code that reassigns argument variables in a separate function than
213 // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
214 var reducer = function(obj
, iteratee
, memo
, initial
) {
215 var keys
= !isArrayLike(obj
) && _
.keys(obj
),
216 length
= (keys
|| obj
).length
,
217 index
= dir
> 0 ? 0 : length
- 1;
219 memo
= obj
[keys
? keys
[index
] : index
];
222 for (; index
>= 0 && index
< length
; index
+= dir
) {
223 var currentKey
= keys
? keys
[index
] : index
;
224 memo
= iteratee(memo
, obj
[currentKey
], currentKey
, obj
);
229 return function(obj
, iteratee
, memo
, context
) {
230 var initial
= arguments
.length
>= 3;
231 return reducer(obj
, optimizeCb(iteratee
, context
, 4), memo
, initial
);
235 // **Reduce** builds up a single result from a list of values, aka `inject`,
237 _
.reduce
= _
.foldl
= _
.inject
= createReduce(1);
239 // The right-associative version of reduce, also known as `foldr`.
240 _
.reduceRight
= _
.foldr
= createReduce(-1);
242 // Return the first value which passes a truth test. Aliased as `detect`.
243 _
.find
= _
.detect = function(obj
, predicate
, context
) {
244 var keyFinder
= isArrayLike(obj
) ? _
.findIndex
: _
.findKey
;
245 var key
= keyFinder(obj
, predicate
, context
);
246 if (key
!== void 0 && key
!== -1) return obj
[key
];
249 // Return all the elements that pass a truth test.
250 // Aliased as `select`.
251 _
.filter
= _
.select = function(obj
, predicate
, context
) {
253 predicate
= cb(predicate
, context
);
254 _
.each(obj
, function(value
, index
, list
) {
255 if (predicate(value
, index
, list
)) results
.push(value
);
260 // Return all the elements for which a truth test fails.
261 _
.reject = function(obj
, predicate
, context
) {
262 return _
.filter(obj
, _
.negate(cb(predicate
)), context
);
265 // Determine whether all of the elements match a truth test.
267 _
.every
= _
.all = function(obj
, predicate
, context
) {
268 predicate
= cb(predicate
, context
);
269 var keys
= !isArrayLike(obj
) && _
.keys(obj
),
270 length
= (keys
|| obj
).length
;
271 for (var index
= 0; index
< length
; index
++) {
272 var currentKey
= keys
? keys
[index
] : index
;
273 if (!predicate(obj
[currentKey
], currentKey
, obj
)) return false;
278 // Determine if at least one element in the object matches a truth test.
280 _
.some
= _
.any = function(obj
, predicate
, context
) {
281 predicate
= cb(predicate
, context
);
282 var keys
= !isArrayLike(obj
) && _
.keys(obj
),
283 length
= (keys
|| obj
).length
;
284 for (var index
= 0; index
< length
; index
++) {
285 var currentKey
= keys
? keys
[index
] : index
;
286 if (predicate(obj
[currentKey
], currentKey
, obj
)) return true;
291 // Determine if the array or object contains a given item (using `===`).
292 // Aliased as `includes` and `include`.
293 _
.contains
= _
.includes
= _
.include = function(obj
, item
, fromIndex
, guard
) {
294 if (!isArrayLike(obj
)) obj
= _
.values(obj
);
295 if (typeof fromIndex
!= 'number' || guard
) fromIndex
= 0;
296 return _
.indexOf(obj
, item
, fromIndex
) >= 0;
299 // Invoke a method (with arguments) on every item in a collection.
300 _
.invoke
= restArguments(function(obj
, path
, args
) {
301 var contextPath
, func
;
302 if (_
.isFunction(path
)) {
304 } else if (_
.isArray(path
)) {
305 contextPath
= path
.slice(0, -1);
306 path
= path
[path
.length
- 1];
308 return _
.map(obj
, function(context
) {
311 if (contextPath
&& contextPath
.length
) {
312 context
= deepGet(context
, contextPath
);
314 if (context
== null) return void 0;
315 method
= context
[path
];
317 return method
== null ? method
: method
.apply(context
, args
);
321 // Convenience version of a common use case of `map`: fetching a property.
322 _
.pluck = function(obj
, key
) {
323 return _
.map(obj
, _
.property(key
));
326 // Convenience version of a common use case of `filter`: selecting only objects
327 // containing specific `key:value` pairs.
328 _
.where = function(obj
, attrs
) {
329 return _
.filter(obj
, _
.matcher(attrs
));
332 // Convenience version of a common use case of `find`: getting the first object
333 // containing specific `key:value` pairs.
334 _
.findWhere = function(obj
, attrs
) {
335 return _
.find(obj
, _
.matcher(attrs
));
338 // Return the maximum element (or element-based computation).
339 _
.max = function(obj
, iteratee
, context
) {
340 var result
= -Infinity
, lastComputed
= -Infinity
,
342 if (iteratee
== null || typeof iteratee
== 'number' && typeof obj
[0] != 'object' && obj
!= null) {
343 obj
= isArrayLike(obj
) ? obj
: _
.values(obj
);
344 for (var i
= 0, length
= obj
.length
; i
< length
; i
++) {
346 if (value
!= null && value
> result
) {
351 iteratee
= cb(iteratee
, context
);
352 _
.each(obj
, function(v
, index
, list
) {
353 computed
= iteratee(v
, index
, list
);
354 if (computed
> lastComputed
|| computed
=== -Infinity
&& result
=== -Infinity
) {
356 lastComputed
= computed
;
363 // Return the minimum element (or element-based computation).
364 _
.min = function(obj
, iteratee
, context
) {
365 var result
= Infinity
, lastComputed
= Infinity
,
367 if (iteratee
== null || typeof iteratee
== 'number' && typeof obj
[0] != 'object' && obj
!= null) {
368 obj
= isArrayLike(obj
) ? obj
: _
.values(obj
);
369 for (var i
= 0, length
= obj
.length
; i
< length
; i
++) {
371 if (value
!= null && value
< result
) {
376 iteratee
= cb(iteratee
, context
);
377 _
.each(obj
, function(v
, index
, list
) {
378 computed
= iteratee(v
, index
, list
);
379 if (computed
< lastComputed
|| computed
=== Infinity
&& result
=== Infinity
) {
381 lastComputed
= computed
;
388 // Shuffle a collection.
389 _
.shuffle = function(obj
) {
390 return _
.sample(obj
, Infinity
);
393 // Sample **n** random values from a collection using the modern version of the
394 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
395 // If **n** is not specified, returns a single random element.
396 // The internal `guard` argument allows it to work with `map`.
397 _
.sample = function(obj
, n
, guard
) {
398 if (n
== null || guard
) {
399 if (!isArrayLike(obj
)) obj
= _
.values(obj
);
400 return obj
[_
.random(obj
.length
- 1)];
402 var sample
= isArrayLike(obj
) ? _
.clone(obj
) : _
.values(obj
);
403 var length
= getLength(sample
);
404 n
= Math
.max(Math
.min(n
, length
), 0);
405 var last
= length
- 1;
406 for (var index
= 0; index
< n
; index
++) {
407 var rand
= _
.random(index
, last
);
408 var temp
= sample
[index
];
409 sample
[index
] = sample
[rand
];
412 return sample
.slice(0, n
);
415 // Sort the object's values by a criterion produced by an iteratee.
416 _
.sortBy = function(obj
, iteratee
, context
) {
418 iteratee
= cb(iteratee
, context
);
419 return _
.pluck(_
.map(obj
, function(value
, key
, list
) {
423 criteria
: iteratee(value
, key
, list
)
425 }).sort(function(left
, right
) {
426 var a
= left
.criteria
;
427 var b
= right
.criteria
;
429 if (a
> b
|| a
=== void 0) return 1;
430 if (a
< b
|| b
=== void 0) return -1;
432 return left
.index
- right
.index
;
436 // An internal function used for aggregate "group by" operations.
437 var group = function(behavior
, partition
) {
438 return function(obj
, iteratee
, context
) {
439 var result
= partition
? [[], []] : {};
440 iteratee
= cb(iteratee
, context
);
441 _
.each(obj
, function(value
, index
) {
442 var key
= iteratee(value
, index
, obj
);
443 behavior(result
, value
, key
);
449 // Groups the object's values by a criterion. Pass either a string attribute
450 // to group by, or a function that returns the criterion.
451 _
.groupBy
= group(function(result
, value
, key
) {
452 if (has(result
, key
)) result
[key
].push(value
); else result
[key
] = [value
];
455 // Indexes the object's values by a criterion, similar to `groupBy`, but for
456 // when you know that your index values will be unique.
457 _
.indexBy
= group(function(result
, value
, key
) {
461 // Counts instances of an object that group by a certain criterion. Pass
462 // either a string attribute to count by, or a function that returns the
464 _
.countBy
= group(function(result
, value
, key
) {
465 if (has(result
, key
)) result
[key
]++; else result
[key
] = 1;
468 var reStrSymbol
= /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
469 // Safely create a real, live array from anything iterable.
470 _
.toArray = function(obj
) {
472 if (_
.isArray(obj
)) return slice
.call(obj
);
473 if (_
.isString(obj
)) {
474 // Keep surrogate pair characters together
475 return obj
.match(reStrSymbol
);
477 if (isArrayLike(obj
)) return _
.map(obj
, _
.identity
);
478 return _
.values(obj
);
481 // Return the number of elements in an object.
482 _
.size = function(obj
) {
483 if (obj
== null) return 0;
484 return isArrayLike(obj
) ? obj
.length
: _
.keys(obj
).length
;
487 // Split a collection into two arrays: one whose elements all satisfy the given
488 // predicate, and one whose elements all do not satisfy the predicate.
489 _
.partition
= group(function(result
, value
, pass
) {
490 result
[pass
? 0 : 1].push(value
);
496 // Get the first element of an array. Passing **n** will return the first N
497 // values in the array. Aliased as `head` and `take`. The **guard** check
498 // allows it to work with `_.map`.
499 _
.first
= _
.head
= _
.take = function(array
, n
, guard
) {
500 if (array
== null || array
.length
< 1) return n
== null ? void 0 : [];
501 if (n
== null || guard
) return array
[0];
502 return _
.initial(array
, array
.length
- n
);
505 // Returns everything but the last entry of the array. Especially useful on
506 // the arguments object. Passing **n** will return all the values in
507 // the array, excluding the last N.
508 _
.initial = function(array
, n
, guard
) {
509 return slice
.call(array
, 0, Math
.max(0, array
.length
- (n
== null || guard
? 1 : n
)));
512 // Get the last element of an array. Passing **n** will return the last N
513 // values in the array.
514 _
.last = function(array
, n
, guard
) {
515 if (array
== null || array
.length
< 1) return n
== null ? void 0 : [];
516 if (n
== null || guard
) return array
[array
.length
- 1];
517 return _
.rest(array
, Math
.max(0, array
.length
- n
));
520 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
521 // Especially useful on the arguments object. Passing an **n** will return
522 // the rest N values in the array.
523 _
.rest
= _
.tail
= _
.drop = function(array
, n
, guard
) {
524 return slice
.call(array
, n
== null || guard
? 1 : n
);
527 // Trim out all falsy values from an array.
528 _
.compact = function(array
) {
529 return _
.filter(array
, Boolean
);
532 // Internal implementation of a recursive `flatten` function.
533 var flatten = function(input
, shallow
, strict
, output
) {
534 output
= output
|| [];
535 var idx
= output
.length
;
536 for (var i
= 0, length
= getLength(input
); i
< length
; i
++) {
537 var value
= input
[i
];
538 if (isArrayLike(value
) && (_
.isArray(value
) || _
.isArguments(value
))) {
539 // Flatten current level of array or arguments object.
541 var j
= 0, len
= value
.length
;
542 while (j
< len
) output
[idx
++] = value
[j
++];
544 flatten(value
, shallow
, strict
, output
);
547 } else if (!strict
) {
548 output
[idx
++] = value
;
554 // Flatten out an array, either recursively (by default), or just one level.
555 _
.flatten = function(array
, shallow
) {
556 return flatten(array
, shallow
, false);
559 // Return a version of the array that does not contain the specified value(s).
560 _
.without
= restArguments(function(array
, otherArrays
) {
561 return _
.difference(array
, otherArrays
);
564 // Produce a duplicate-free version of the array. If the array has already
565 // been sorted, you have the option of using a faster algorithm.
566 // The faster algorithm will not work with an iteratee if the iteratee
567 // is not a one-to-one function, so providing an iteratee will disable
568 // the faster algorithm.
569 // Aliased as `unique`.
570 _
.uniq
= _
.unique = function(array
, isSorted
, iteratee
, context
) {
571 if (!_
.isBoolean(isSorted
)) {
576 if (iteratee
!= null) iteratee
= cb(iteratee
, context
);
579 for (var i
= 0, length
= getLength(array
); i
< length
; i
++) {
580 var value
= array
[i
],
581 computed
= iteratee
? iteratee(value
, i
, array
) : value
;
582 if (isSorted
&& !iteratee
) {
583 if (!i
|| seen
!== computed
) result
.push(value
);
585 } else if (iteratee
) {
586 if (!_
.contains(seen
, computed
)) {
590 } else if (!_
.contains(result
, value
)) {
597 // Produce an array that contains the union: each distinct element from all of
598 // the passed-in arrays.
599 _
.union
= restArguments(function(arrays
) {
600 return _
.uniq(flatten(arrays
, true, true));
603 // Produce an array that contains every item shared between all the
605 _
.intersection = function(array
) {
607 var argsLength
= arguments
.length
;
608 for (var i
= 0, length
= getLength(array
); i
< length
; i
++) {
610 if (_
.contains(result
, item
)) continue;
612 for (j
= 1; j
< argsLength
; j
++) {
613 if (!_
.contains(arguments
[j
], item
)) break;
615 if (j
=== argsLength
) result
.push(item
);
620 // Take the difference between one array and a number of other arrays.
621 // Only the elements present in just the first array will remain.
622 _
.difference
= restArguments(function(array
, rest
) {
623 rest
= flatten(rest
, true, true);
624 return _
.filter(array
, function(value
){
625 return !_
.contains(rest
, value
);
629 // Complement of _.zip. Unzip accepts an array of arrays and groups
630 // each array's elements on shared indices.
631 _
.unzip = function(array
) {
632 var length
= array
&& _
.max(array
, getLength
).length
|| 0;
633 var result
= Array(length
);
635 for (var index
= 0; index
< length
; index
++) {
636 result
[index
] = _
.pluck(array
, index
);
641 // Zip together multiple lists into a single array -- elements that share
642 // an index go together.
643 _
.zip
= restArguments(_
.unzip
);
645 // Converts lists into objects. Pass either a single array of `[key, value]`
646 // pairs, or two parallel arrays of the same length -- one of keys, and one of
647 // the corresponding values. Passing by pairs is the reverse of _.pairs.
648 _
.object = function(list
, values
) {
650 for (var i
= 0, length
= getLength(list
); i
< length
; i
++) {
652 result
[list
[i
]] = values
[i
];
654 result
[list
[i
][0]] = list
[i
][1];
660 // Generator function to create the findIndex and findLastIndex functions.
661 var createPredicateIndexFinder = function(dir
) {
662 return function(array
, predicate
, context
) {
663 predicate
= cb(predicate
, context
);
664 var length
= getLength(array
);
665 var index
= dir
> 0 ? 0 : length
- 1;
666 for (; index
>= 0 && index
< length
; index
+= dir
) {
667 if (predicate(array
[index
], index
, array
)) return index
;
673 // Returns the first index on an array-like that passes a predicate test.
674 _
.findIndex
= createPredicateIndexFinder(1);
675 _
.findLastIndex
= createPredicateIndexFinder(-1);
677 // Use a comparator function to figure out the smallest index at which
678 // an object should be inserted so as to maintain order. Uses binary search.
679 _
.sortedIndex = function(array
, obj
, iteratee
, context
) {
680 iteratee
= cb(iteratee
, context
, 1);
681 var value
= iteratee(obj
);
682 var low
= 0, high
= getLength(array
);
684 var mid
= Math
.floor((low
+ high
) / 2);
685 if (iteratee(array
[mid
]) < value
) low
= mid
+ 1; else high
= mid
;
690 // Generator function to create the indexOf and lastIndexOf functions.
691 var createIndexFinder = function(dir
, predicateFind
, sortedIndex
) {
692 return function(array
, item
, idx
) {
693 var i
= 0, length
= getLength(array
);
694 if (typeof idx
== 'number') {
696 i
= idx
>= 0 ? idx
: Math
.max(idx
+ length
, i
);
698 length
= idx
>= 0 ? Math
.min(idx
+ 1, length
) : idx
+ length
+ 1;
700 } else if (sortedIndex
&& idx
&& length
) {
701 idx
= sortedIndex(array
, item
);
702 return array
[idx
] === item
? idx
: -1;
705 idx
= predicateFind(slice
.call(array
, i
, length
), _
.isNaN
);
706 return idx
>= 0 ? idx
+ i
: -1;
708 for (idx
= dir
> 0 ? i
: length
- 1; idx
>= 0 && idx
< length
; idx
+= dir
) {
709 if (array
[idx
] === item
) return idx
;
715 // Return the position of the first occurrence of an item in an array,
716 // or -1 if the item is not included in the array.
717 // If the array is large and already in sort order, pass `true`
718 // for **isSorted** to use binary search.
719 _
.indexOf
= createIndexFinder(1, _
.findIndex
, _
.sortedIndex
);
720 _
.lastIndexOf
= createIndexFinder(-1, _
.findLastIndex
);
722 // Generate an integer Array containing an arithmetic progression. A port of
723 // the native Python `range()` function. See
724 // [the Python documentation](http://docs.python.org/library/functions.html#range).
725 _
.range = function(start
, stop
, step
) {
731 step
= stop
< start
? -1 : 1;
734 var length
= Math
.max(Math
.ceil((stop
- start
) / step
), 0);
735 var range
= Array(length
);
737 for (var idx
= 0; idx
< length
; idx
++, start
+= step
) {
744 // Chunk a single array into multiple arrays, each containing `count` or fewer
746 _
.chunk = function(array
, count
) {
747 if (count
== null || count
< 1) return [];
749 var i
= 0, length
= array
.length
;
751 result
.push(slice
.call(array
, i
, i
+= count
));
756 // Function (ahem) Functions
757 // ------------------
759 // Determines whether to execute a function as a constructor
760 // or a normal function with the provided arguments.
761 var executeBound = function(sourceFunc
, boundFunc
, context
, callingContext
, args
) {
762 if (!(callingContext
instanceof boundFunc
)) return sourceFunc
.apply(context
, args
);
763 var self
= baseCreate(sourceFunc
.prototype);
764 var result
= sourceFunc
.apply(self
, args
);
765 if (_
.isObject(result
)) return result
;
769 // Create a function bound to a given object (assigning `this`, and arguments,
770 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
772 _
.bind
= restArguments(function(func
, context
, args
) {
773 if (!_
.isFunction(func
)) throw new TypeError('Bind must be called on a function');
774 var bound
= restArguments(function(callArgs
) {
775 return executeBound(func
, bound
, context
, this, args
.concat(callArgs
));
780 // Partially apply a function by creating a version that has had some of its
781 // arguments pre-filled, without changing its dynamic `this` context. _ acts
782 // as a placeholder by default, allowing any combination of arguments to be
783 // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
784 _
.partial
= restArguments(function(func
, boundArgs
) {
785 var placeholder
= _
.partial
.placeholder
;
786 var bound = function() {
787 var position
= 0, length
= boundArgs
.length
;
788 var args
= Array(length
);
789 for (var i
= 0; i
< length
; i
++) {
790 args
[i
] = boundArgs
[i
] === placeholder
? arguments
[position
++] : boundArgs
[i
];
792 while (position
< arguments
.length
) args
.push(arguments
[position
++]);
793 return executeBound(func
, bound
, this, this, args
);
798 _
.partial
.placeholder
= _
;
800 // Bind a number of an object's methods to that object. Remaining arguments
801 // are the method names to be bound. Useful for ensuring that all callbacks
802 // defined on an object belong to it.
803 _
.bindAll
= restArguments(function(obj
, keys
) {
804 keys
= flatten(keys
, false, false);
805 var index
= keys
.length
;
806 if (index
< 1) throw new Error('bindAll must be passed function names');
808 var key
= keys
[index
];
809 obj
[key
] = _
.bind(obj
[key
], obj
);
813 // Memoize an expensive function by storing its results.
814 _
.memoize = function(func
, hasher
) {
815 var memoize = function(key
) {
816 var cache
= memoize
.cache
;
817 var address
= '' + (hasher
? hasher
.apply(this, arguments
) : key
);
818 if (!has(cache
, address
)) cache
[address
] = func
.apply(this, arguments
);
819 return cache
[address
];
825 // Delays a function for the given number of milliseconds, and then calls
826 // it with the arguments supplied.
827 _
.delay
= restArguments(function(func
, wait
, args
) {
828 return setTimeout(function() {
829 return func
.apply(null, args
);
833 // Defers a function, scheduling it to run after the current call stack has
835 _
.defer
= _
.partial(_
.delay
, _
, 1);
837 // Returns a function, that, when invoked, will only be triggered at most once
838 // during a given window of time. Normally, the throttled function will run
839 // as much as it can, without ever going more than once per `wait` duration;
840 // but if you'd like to disable the execution on the leading edge, pass
841 // `{leading: false}`. To disable execution on the trailing edge, ditto.
842 _
.throttle = function(func
, wait
, options
) {
843 var timeout
, context
, args
, result
;
845 if (!options
) options
= {};
847 var later = function() {
848 previous
= options
.leading
=== false ? 0 : _
.now();
850 result
= func
.apply(context
, args
);
851 if (!timeout
) context
= args
= null;
854 var throttled = function() {
856 if (!previous
&& options
.leading
=== false) previous
= now
;
857 var remaining
= wait
- (now
- previous
);
860 if (remaining
<= 0 || remaining
> wait
) {
862 clearTimeout(timeout
);
866 result
= func
.apply(context
, args
);
867 if (!timeout
) context
= args
= null;
868 } else if (!timeout
&& options
.trailing
!== false) {
869 timeout
= setTimeout(later
, remaining
);
874 throttled
.cancel = function() {
875 clearTimeout(timeout
);
877 timeout
= context
= args
= null;
883 // Returns a function, that, as long as it continues to be invoked, will not
884 // be triggered. The function will be called after it stops being called for
885 // N milliseconds. If `immediate` is passed, trigger the function on the
886 // leading edge, instead of the trailing.
887 _
.debounce = function(func
, wait
, immediate
) {
890 var later = function(context
, args
) {
892 if (args
) result
= func
.apply(context
, args
);
895 var debounced
= restArguments(function(args
) {
896 if (timeout
) clearTimeout(timeout
);
898 var callNow
= !timeout
;
899 timeout
= setTimeout(later
, wait
);
900 if (callNow
) result
= func
.apply(this, args
);
902 timeout
= _
.delay(later
, wait
, this, args
);
908 debounced
.cancel = function() {
909 clearTimeout(timeout
);
916 // Returns the first function passed as an argument to the second,
917 // allowing you to adjust arguments, run code before and after, and
918 // conditionally execute the original function.
919 _
.wrap = function(func
, wrapper
) {
920 return _
.partial(wrapper
, func
);
923 // Returns a negated version of the passed-in predicate.
924 _
.negate = function(predicate
) {
926 return !predicate
.apply(this, arguments
);
930 // Returns a function that is the composition of a list of functions, each
931 // consuming the return value of the function that follows.
932 _
.compose = function() {
933 var args
= arguments
;
934 var start
= args
.length
- 1;
937 var result
= args
[start
].apply(this, arguments
);
938 while (i
--) result
= args
[i
].call(this, result
);
943 // Returns a function that will only be executed on and after the Nth call.
944 _
.after = function(times
, func
) {
947 return func
.apply(this, arguments
);
952 // Returns a function that will only be executed up to (but not including) the Nth call.
953 _
.before = function(times
, func
) {
957 memo
= func
.apply(this, arguments
);
959 if (times
<= 1) func
= null;
964 // Returns a function that will be executed at most one time, no matter how
965 // often you call it. Useful for lazy initialization.
966 _
.once
= _
.partial(_
.before
, 2);
968 _
.restArguments
= restArguments
;
973 // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
974 var hasEnumBug
= !{toString
: null}.propertyIsEnumerable('toString');
975 var nonEnumerableProps
= ['valueOf', 'isPrototypeOf', 'toString',
976 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
978 var collectNonEnumProps = function(obj
, keys
) {
979 var nonEnumIdx
= nonEnumerableProps
.length
;
980 var constructor = obj
.constructor;
981 var proto
= _
.isFunction(constructor) && constructor.prototype || ObjProto
;
983 // Constructor is a special case.
984 var prop
= 'constructor';
985 if (has(obj
, prop
) && !_
.contains(keys
, prop
)) keys
.push(prop
);
987 while (nonEnumIdx
--) {
988 prop
= nonEnumerableProps
[nonEnumIdx
];
989 if (prop
in obj
&& obj
[prop
] !== proto
[prop
] && !_
.contains(keys
, prop
)) {
995 // Retrieve the names of an object's own properties.
996 // Delegates to **ECMAScript 5**'s native `Object.keys`.
997 _
.keys = function(obj
) {
998 if (!_
.isObject(obj
)) return [];
999 if (nativeKeys
) return nativeKeys(obj
);
1001 for (var key
in obj
) if (has(obj
, key
)) keys
.push(key
);
1003 if (hasEnumBug
) collectNonEnumProps(obj
, keys
);
1007 // Retrieve all the property names of an object.
1008 _
.allKeys = function(obj
) {
1009 if (!_
.isObject(obj
)) return [];
1011 for (var key
in obj
) keys
.push(key
);
1013 if (hasEnumBug
) collectNonEnumProps(obj
, keys
);
1017 // Retrieve the values of an object's properties.
1018 _
.values = function(obj
) {
1019 var keys
= _
.keys(obj
);
1020 var length
= keys
.length
;
1021 var values
= Array(length
);
1022 for (var i
= 0; i
< length
; i
++) {
1023 values
[i
] = obj
[keys
[i
]];
1028 // Returns the results of applying the iteratee to each element of the object.
1029 // In contrast to _.map it returns an object.
1030 _
.mapObject = function(obj
, iteratee
, context
) {
1031 iteratee
= cb(iteratee
, context
);
1032 var keys
= _
.keys(obj
),
1033 length
= keys
.length
,
1035 for (var index
= 0; index
< length
; index
++) {
1036 var currentKey
= keys
[index
];
1037 results
[currentKey
] = iteratee(obj
[currentKey
], currentKey
, obj
);
1042 // Convert an object into a list of `[key, value]` pairs.
1043 // The opposite of _.object.
1044 _
.pairs = function(obj
) {
1045 var keys
= _
.keys(obj
);
1046 var length
= keys
.length
;
1047 var pairs
= Array(length
);
1048 for (var i
= 0; i
< length
; i
++) {
1049 pairs
[i
] = [keys
[i
], obj
[keys
[i
]]];
1054 // Invert the keys and values of an object. The values must be serializable.
1055 _
.invert = function(obj
) {
1057 var keys
= _
.keys(obj
);
1058 for (var i
= 0, length
= keys
.length
; i
< length
; i
++) {
1059 result
[obj
[keys
[i
]]] = keys
[i
];
1064 // Return a sorted list of the function names available on the object.
1065 // Aliased as `methods`.
1066 _
.functions
= _
.methods = function(obj
) {
1068 for (var key
in obj
) {
1069 if (_
.isFunction(obj
[key
])) names
.push(key
);
1071 return names
.sort();
1074 // An internal function for creating assigner functions.
1075 var createAssigner = function(keysFunc
, defaults
) {
1076 return function(obj
) {
1077 var length
= arguments
.length
;
1078 if (defaults
) obj
= Object(obj
);
1079 if (length
< 2 || obj
== null) return obj
;
1080 for (var index
= 1; index
< length
; index
++) {
1081 var source
= arguments
[index
],
1082 keys
= keysFunc(source
),
1084 for (var i
= 0; i
< l
; i
++) {
1086 if (!defaults
|| obj
[key
] === void 0) obj
[key
] = source
[key
];
1093 // Extend a given object with all the properties in passed-in object(s).
1094 _
.extend
= createAssigner(_
.allKeys
);
1096 // Assigns a given object with all the own properties in the passed-in object(s).
1097 // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
1098 _
.extendOwn
= _
.assign
= createAssigner(_
.keys
);
1100 // Returns the first key on an object that passes a predicate test.
1101 _
.findKey = function(obj
, predicate
, context
) {
1102 predicate
= cb(predicate
, context
);
1103 var keys
= _
.keys(obj
), key
;
1104 for (var i
= 0, length
= keys
.length
; i
< length
; i
++) {
1106 if (predicate(obj
[key
], key
, obj
)) return key
;
1110 // Internal pick helper function to determine if `obj` has key `key`.
1111 var keyInObj = function(value
, key
, obj
) {
1115 // Return a copy of the object only containing the whitelisted properties.
1116 _
.pick
= restArguments(function(obj
, keys
) {
1117 var result
= {}, iteratee
= keys
[0];
1118 if (obj
== null) return result
;
1119 if (_
.isFunction(iteratee
)) {
1120 if (keys
.length
> 1) iteratee
= optimizeCb(iteratee
, keys
[1]);
1121 keys
= _
.allKeys(obj
);
1123 iteratee
= keyInObj
;
1124 keys
= flatten(keys
, false, false);
1127 for (var i
= 0, length
= keys
.length
; i
< length
; i
++) {
1129 var value
= obj
[key
];
1130 if (iteratee(value
, key
, obj
)) result
[key
] = value
;
1135 // Return a copy of the object without the blacklisted properties.
1136 _
.omit
= restArguments(function(obj
, keys
) {
1137 var iteratee
= keys
[0], context
;
1138 if (_
.isFunction(iteratee
)) {
1139 iteratee
= _
.negate(iteratee
);
1140 if (keys
.length
> 1) context
= keys
[1];
1142 keys
= _
.map(flatten(keys
, false, false), String
);
1143 iteratee = function(value
, key
) {
1144 return !_
.contains(keys
, key
);
1147 return _
.pick(obj
, iteratee
, context
);
1150 // Fill in a given object with default properties.
1151 _
.defaults
= createAssigner(_
.allKeys
, true);
1153 // Creates an object that inherits from the given prototype object.
1154 // If additional properties are provided then they will be added to the
1156 _
.create = function(prototype, props
) {
1157 var result
= baseCreate(prototype);
1158 if (props
) _
.extendOwn(result
, props
);
1162 // Create a (shallow-cloned) duplicate of an object.
1163 _
.clone = function(obj
) {
1164 if (!_
.isObject(obj
)) return obj
;
1165 return _
.isArray(obj
) ? obj
.slice() : _
.extend({}, obj
);
1168 // Invokes interceptor with the obj, and then returns obj.
1169 // The primary purpose of this method is to "tap into" a method chain, in
1170 // order to perform operations on intermediate results within the chain.
1171 _
.tap = function(obj
, interceptor
) {
1176 // Returns whether an object has a given set of `key:value` pairs.
1177 _
.isMatch = function(object
, attrs
) {
1178 var keys
= _
.keys(attrs
), length
= keys
.length
;
1179 if (object
== null) return !length
;
1180 var obj
= Object(object
);
1181 for (var i
= 0; i
< length
; i
++) {
1183 if (attrs
[key
] !== obj
[key
] || !(key
in obj
)) return false;
1189 // Internal recursive comparison function for `isEqual`.
1191 eq = function(a
, b
, aStack
, bStack
) {
1192 // Identical objects are equal. `0 === -0`, but they aren't identical.
1193 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1194 if (a
=== b
) return a
!== 0 || 1 / a
=== 1 / b
;
1195 // `null` or `undefined` only equal to itself (strict comparison).
1196 if (a
== null || b
== null) return false;
1197 // `NaN`s are equivalent, but non-reflexive.
1198 if (a
!== a
) return b
!== b
;
1199 // Exhaust primitive checks
1200 var type
= typeof a
;
1201 if (type
!== 'function' && type
!== 'object' && typeof b
!= 'object') return false;
1202 return deepEq(a
, b
, aStack
, bStack
);
1205 // Internal recursive comparison function for `isEqual`.
1206 deepEq = function(a
, b
, aStack
, bStack
) {
1207 // Unwrap any wrapped objects.
1208 if (a
instanceof _
) a
= a
._wrapped
;
1209 if (b
instanceof _
) b
= b
._wrapped
;
1210 // Compare `[[Class]]` names.
1211 var className
= toString
.call(a
);
1212 if (className
!== toString
.call(b
)) return false;
1213 switch (className
) {
1214 // Strings, numbers, regular expressions, dates, and booleans are compared by value.
1215 case '[object RegExp]':
1216 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
1217 case '[object String]':
1218 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1219 // equivalent to `new String("5")`.
1220 return '' + a
=== '' + b
;
1221 case '[object Number]':
1222 // `NaN`s are equivalent, but non-reflexive.
1223 // Object(NaN) is equivalent to NaN.
1224 if (+a
!== +a
) return +b
!== +b
;
1225 // An `egal` comparison is performed for other numeric values.
1226 return +a
=== 0 ? 1 / +a
=== 1 / b
: +a
=== +b
;
1227 case '[object Date]':
1228 case '[object Boolean]':
1229 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1230 // millisecond representations. Note that invalid dates with millisecond representations
1231 // of `NaN` are not equivalent.
1233 case '[object Symbol]':
1234 return SymbolProto
.valueOf
.call(a
) === SymbolProto
.valueOf
.call(b
);
1237 var areArrays
= className
=== '[object Array]';
1239 if (typeof a
!= 'object' || typeof b
!= 'object') return false;
1241 // Objects with different constructors are not equivalent, but `Object`s or `Array`s
1242 // from different frames are.
1243 var aCtor
= a
.constructor, bCtor
= b
.constructor;
1244 if (aCtor
!== bCtor
&& !(_
.isFunction(aCtor
) && aCtor
instanceof aCtor
&&
1245 _
.isFunction(bCtor
) && bCtor
instanceof bCtor
)
1246 && ('constructor' in a
&& 'constructor' in b
)) {
1250 // Assume equality for cyclic structures. The algorithm for detecting cyclic
1251 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1253 // Initializing stack of traversed objects.
1254 // It's done here since we only need them for objects and arrays comparison.
1255 aStack
= aStack
|| [];
1256 bStack
= bStack
|| [];
1257 var length
= aStack
.length
;
1259 // Linear search. Performance is inversely proportional to the number of
1260 // unique nested structures.
1261 if (aStack
[length
] === a
) return bStack
[length
] === b
;
1264 // Add the first object to the stack of traversed objects.
1268 // Recursively compare objects and arrays.
1270 // Compare array lengths to determine if a deep comparison is necessary.
1272 if (length
!== b
.length
) return false;
1273 // Deep compare the contents, ignoring non-numeric properties.
1275 if (!eq(a
[length
], b
[length
], aStack
, bStack
)) return false;
1278 // Deep compare objects.
1279 var keys
= _
.keys(a
), key
;
1280 length
= keys
.length
;
1281 // Ensure that both objects contain the same number of properties before comparing deep equality.
1282 if (_
.keys(b
).length
!== length
) return false;
1284 // Deep compare each member
1286 if (!(has(b
, key
) && eq(a
[key
], b
[key
], aStack
, bStack
))) return false;
1289 // Remove the first object from the stack of traversed objects.
1295 // Perform a deep comparison to check if two objects are equal.
1296 _
.isEqual = function(a
, b
) {
1300 // Is a given array, string, or object empty?
1301 // An "empty" object has no enumerable own-properties.
1302 _
.isEmpty = function(obj
) {
1303 if (obj
== null) return true;
1304 if (isArrayLike(obj
) && (_
.isArray(obj
) || _
.isString(obj
) || _
.isArguments(obj
))) return obj
.length
=== 0;
1305 return _
.keys(obj
).length
=== 0;
1308 // Is a given value a DOM element?
1309 _
.isElement = function(obj
) {
1310 return !!(obj
&& obj
.nodeType
=== 1);
1313 // Is a given value an array?
1314 // Delegates to ECMA5's native Array.isArray
1315 _
.isArray
= nativeIsArray
|| function(obj
) {
1316 return toString
.call(obj
) === '[object Array]';
1319 // Is a given variable an object?
1320 _
.isObject = function(obj
) {
1321 var type
= typeof obj
;
1322 return type
=== 'function' || type
=== 'object' && !!obj
;
1325 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet.
1326 _
.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name
) {
1327 _
['is' + name
] = function(obj
) {
1328 return toString
.call(obj
) === '[object ' + name
+ ']';
1332 // Define a fallback version of the method in browsers (ahem, IE < 9), where
1333 // there isn't any inspectable "Arguments" type.
1334 if (!_
.isArguments(arguments
)) {
1335 _
.isArguments = function(obj
) {
1336 return has(obj
, 'callee');
1340 // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
1341 // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
1342 var nodelist
= root
.document
&& root
.document
.childNodes
;
1343 if (typeof /./ != 'function' && typeof Int8Array
!= 'object' && typeof nodelist
!= 'function') {
1344 _
.isFunction = function(obj
) {
1345 return typeof obj
== 'function' || false;
1349 // Is a given object a finite number?
1350 _
.isFinite = function(obj
) {
1351 return !_
.isSymbol(obj
) && isFinite(obj
) && !isNaN(parseFloat(obj
));
1354 // Is the given value `NaN`?
1355 _
.isNaN = function(obj
) {
1356 return _
.isNumber(obj
) && isNaN(obj
);
1359 // Is a given value a boolean?
1360 _
.isBoolean = function(obj
) {
1361 return obj
=== true || obj
=== false || toString
.call(obj
) === '[object Boolean]';
1364 // Is a given value equal to null?
1365 _
.isNull = function(obj
) {
1366 return obj
=== null;
1369 // Is a given variable undefined?
1370 _
.isUndefined = function(obj
) {
1371 return obj
=== void 0;
1374 // Shortcut function for checking if an object has a given property directly
1375 // on itself (in other words, not on a prototype).
1376 _
.has = function(obj
, path
) {
1377 if (!_
.isArray(path
)) {
1378 return has(obj
, path
);
1380 var length
= path
.length
;
1381 for (var i
= 0; i
< length
; i
++) {
1383 if (obj
== null || !hasOwnProperty
.call(obj
, key
)) {
1391 // Utility Functions
1392 // -----------------
1394 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1395 // previous owner. Returns a reference to the Underscore object.
1396 _
.noConflict = function() {
1397 root
._
= previousUnderscore
;
1401 // Keep the identity function around for default iteratees.
1402 _
.identity = function(value
) {
1406 // Predicate-generating functions. Often useful outside of Underscore.
1407 _
.constant = function(value
) {
1413 _
.noop = function(){};
1415 // Creates a function that, when passed an object, will traverse that object’s
1416 // properties down the given `path`, specified as an array of keys or indexes.
1417 _
.property = function(path
) {
1418 if (!_
.isArray(path
)) {
1419 return shallowProperty(path
);
1421 return function(obj
) {
1422 return deepGet(obj
, path
);
1426 // Generates a function for a given object that returns a given property.
1427 _
.propertyOf = function(obj
) {
1429 return function(){};
1431 return function(path
) {
1432 return !_
.isArray(path
) ? obj
[path
] : deepGet(obj
, path
);
1436 // Returns a predicate for checking whether an object has a given set of
1437 // `key:value` pairs.
1438 _
.matcher
= _
.matches = function(attrs
) {
1439 attrs
= _
.extendOwn({}, attrs
);
1440 return function(obj
) {
1441 return _
.isMatch(obj
, attrs
);
1445 // Run a function **n** times.
1446 _
.times = function(n
, iteratee
, context
) {
1447 var accum
= Array(Math
.max(0, n
));
1448 iteratee
= optimizeCb(iteratee
, context
, 1);
1449 for (var i
= 0; i
< n
; i
++) accum
[i
] = iteratee(i
);
1453 // Return a random integer between min and max (inclusive).
1454 _
.random = function(min
, max
) {
1459 return min
+ Math
.floor(Math
.random() * (max
- min
+ 1));
1462 // A (possibly faster) way to get the current timestamp as an integer.
1463 _
.now
= Date
.now
|| function() {
1464 return new Date().getTime();
1467 // List of HTML entities for escaping.
1476 var unescapeMap
= _
.invert(escapeMap
);
1478 // Functions for escaping and unescaping strings to/from HTML interpolation.
1479 var createEscaper = function(map
) {
1480 var escaper = function(match
) {
1483 // Regexes for identifying a key that needs to be escaped.
1484 var source
= '(?:' + _
.keys(map
).join('|') + ')';
1485 var testRegexp
= RegExp(source
);
1486 var replaceRegexp
= RegExp(source
, 'g');
1487 return function(string
) {
1488 string
= string
== null ? '' : '' + string
;
1489 return testRegexp
.test(string
) ? string
.replace(replaceRegexp
, escaper
) : string
;
1492 _
.escape
= createEscaper(escapeMap
);
1493 _
.unescape
= createEscaper(unescapeMap
);
1495 // Traverses the children of `obj` along `path`. If a child is a function, it
1496 // is invoked with its parent as context. Returns the value of the final
1497 // child, or `fallback` if any child is undefined.
1498 _
.result = function(obj
, path
, fallback
) {
1499 if (!_
.isArray(path
)) path
= [path
];
1500 var length
= path
.length
;
1502 return _
.isFunction(fallback
) ? fallback
.call(obj
) : fallback
;
1504 for (var i
= 0; i
< length
; i
++) {
1505 var prop
= obj
== null ? void 0 : obj
[path
[i
]];
1506 if (prop
=== void 0) {
1508 i
= length
; // Ensure we don't continue iterating.
1510 obj
= _
.isFunction(prop
) ? prop
.call(obj
) : prop
;
1515 // Generate a unique integer id (unique within the entire client session).
1516 // Useful for temporary DOM ids.
1518 _
.uniqueId = function(prefix
) {
1519 var id
= ++idCounter
+ '';
1520 return prefix
? prefix
+ id
: id
;
1523 // By default, Underscore uses ERB-style template delimiters, change the
1524 // following template settings to use alternative delimiters.
1525 _
.templateSettings
= {
1526 evaluate
: /<%([\s\S]+?)%>/g,
1527 interpolate
: /<%=([\s\S]+?)%>/g,
1528 escape
: /<%-([\s\S]+?)%>/g
1531 // When customizing `templateSettings`, if you don't want to define an
1532 // interpolation, evaluation or escaping regex, we need one that is
1533 // guaranteed not to match.
1534 var noMatch
= /(.)^/;
1536 // Certain characters need to be escaped so that they can be put into a
1547 var escapeRegExp
= /\\|'|\r|\n|\u2028|\u2029/g;
1549 var escapeChar = function(match
) {
1550 return '\\' + escapes
[match
];
1553 // In order to prevent third-party code injection through
1554 // `_.templateSettings.variable`, we test it against the following regular
1555 // expression. It is intentionally a bit more liberal than just matching valid
1556 // identifiers, but still prevents possible loopholes through defaults or
1557 // destructuring assignment.
1558 var bareIdentifier
= /^\s*(\w|\$)+\s*$/;
1560 // JavaScript micro-templating, similar to John Resig's implementation.
1561 // Underscore templating handles arbitrary delimiters, preserves whitespace,
1562 // and correctly escapes quotes within interpolated code.
1563 // NB: `oldSettings` only exists for backwards compatibility.
1564 _
.template = function(text
, settings
, oldSettings
) {
1565 if (!settings
&& oldSettings
) settings
= oldSettings
;
1566 settings
= _
.defaults({}, settings
, _
.templateSettings
);
1568 // Combine delimiters into one regular expression via alternation.
1569 var matcher
= RegExp([
1570 (settings
.escape
|| noMatch
).source
,
1571 (settings
.interpolate
|| noMatch
).source
,
1572 (settings
.evaluate
|| noMatch
).source
1573 ].join('|') + '|$', 'g');
1575 // Compile the template source, escaping string literals appropriately.
1577 var source
= "__p+='";
1578 text
.replace(matcher
, function(match
, escape
, interpolate
, evaluate
, offset
) {
1579 source
+= text
.slice(index
, offset
).replace(escapeRegExp
, escapeChar
);
1580 index
= offset
+ match
.length
;
1583 source
+= "'+\n((__t=(" + escape
+ "))==null?'':_.escape(__t))+\n'";
1584 } else if (interpolate
) {
1585 source
+= "'+\n((__t=(" + interpolate
+ "))==null?'':__t)+\n'";
1586 } else if (evaluate
) {
1587 source
+= "';\n" + evaluate
+ "\n__p+='";
1590 // Adobe VMs need the match returned to produce the correct offset.
1595 var argument
= settings
.variable
;
1597 // Insure against third-party code injection.
1598 if (!bareIdentifier
.test(argument
)) throw new Error(
1599 'variable is not a bare identifier: ' + argument
1602 // If a variable is not specified, place data values in local scope.
1603 source
= 'with(obj||{}){\n' + source
+ '}\n';
1607 source
= "var __t,__p='',__j=Array.prototype.join," +
1608 "print=function(){__p+=__j.call(arguments,'');};\n" +
1609 source
+ 'return __p;\n';
1613 render
= new Function(argument
, '_', source
);
1619 var template = function(data
) {
1620 return render
.call(this, data
, _
);
1623 // Provide the compiled source as a convenience for precompilation.
1624 template
.source
= 'function(' + argument
+ '){\n' + source
+ '}';
1629 // Add a "chain" function. Start chaining a wrapped Underscore object.
1630 _
.chain = function(obj
) {
1631 var instance
= _(obj
);
1632 instance
._chain
= true;
1638 // If Underscore is called as a function, it returns a wrapped object that
1639 // can be used OO-style. This wrapper holds altered versions of all the
1640 // underscore functions. Wrapped objects may be chained.
1642 // Helper function to continue chaining intermediate results.
1643 var chainResult = function(instance
, obj
) {
1644 return instance
._chain
? _(obj
).chain() : obj
;
1647 // Add your own custom functions to the Underscore object.
1648 _
.mixin = function(obj
) {
1649 _
.each(_
.functions(obj
), function(name
) {
1650 var func
= _
[name
] = obj
[name
];
1651 _
.prototype[name
] = function() {
1652 var args
= [this._wrapped
];
1653 push
.apply(args
, arguments
);
1654 return chainResult(this, func
.apply(_
, args
));
1660 // Add all of the Underscore functions to the wrapper object.
1663 // Add all mutator Array functions to the wrapper.
1664 _
.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name
) {
1665 var method
= ArrayProto
[name
];
1666 _
.prototype[name
] = function() {
1667 var obj
= this._wrapped
;
1668 method
.apply(obj
, arguments
);
1669 if ((name
=== 'shift' || name
=== 'splice') && obj
.length
=== 0) delete obj
[0];
1670 return chainResult(this, obj
);
1674 // Add all accessor Array functions to the wrapper.
1675 _
.each(['concat', 'join', 'slice'], function(name
) {
1676 var method
= ArrayProto
[name
];
1677 _
.prototype[name
] = function() {
1678 return chainResult(this, method
.apply(this._wrapped
, arguments
));
1682 // Extracts the result from a wrapped and chained object.
1683 _
.prototype.value = function() {
1684 return this._wrapped
;
1687 // Provide unwrapping proxy for some methods used in engine operations
1688 // such as arithmetic and JSON stringification.
1689 _
.prototype.valueOf
= _
.prototype.toJSON
= _
.prototype.value
;
1691 _
.prototype.toString = function() {
1692 return String(this._wrapped
);
1695 // AMD registration happens at the end for compatibility with AMD loaders
1696 // that may not enforce next-turn semantics on modules. Even though general
1697 // practice for AMD registration is to be anonymous, underscore registers
1698 // as a named module because, like jQuery, it is a base library that is
1699 // popular enough to be bundled in a third party lib, but not be part of
1700 // an AMD load request. Those cases could generate an error when an
1701 // anonymous define() is called outside of a loader request.
1702 if (typeof define
== 'function' && define
.amd
) {
1703 define('underscore', [], function() {