diff --git a/README.md b/README.md index ca8f2b5f6b..ba13495f66 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash v3.3.0 +# lodash v3.3.1 The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) with packages for [Bower](http://bower.io/), [Component](http://component.github.io/), & [Volo](http://volojs.org/). @@ -12,8 +12,8 @@ $ lodash modern -o ./lodash.js lodash is also available in a variety of other builds & module formats. * npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds - * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.3.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.3.0-amd) builds - * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.3.0-es) build + * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.3.1-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.3.1-amd) builds + * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.3.1-es) build ## Further Reading diff --git a/bower.json b/bower.json index 0ee8e0225c..6e519dd669 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "3.3.0", + "version": "3.3.1", "main": "lodash.js", "ignore": [ ".*", diff --git a/component.json b/component.json index e3b503d227..09c584e2d4 100644 --- a/component.json +++ b/component.json @@ -1,7 +1,7 @@ { "name": "lodash", "repo": "lodash/lodash", - "version": "3.3.0", + "version": "3.3.1", "description": "The modern build of lodash.", "license": "MIT", "main": "lodash.js", diff --git a/doc/README.md b/doc/README.md index 6c31751ef6..ff8e9bf46f 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -# lodash v3.3.0 +# lodash v3.3.1 @@ -133,7 +133,7 @@ * `_.compose` -> `flowRight` * `_.curry` * `_.curryRight` -* `_.debounce` +* `_.debounce` * `_.defer` * `_.delay` * `_.flow` @@ -145,7 +145,7 @@ * `_.partialRight` * `_.rearg` * `_.spread` -* `_.throttle` +* `_.throttle` * `_.wrap` @@ -313,7 +313,7 @@ ### `_.chunk(array, [size=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4197 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.chunk "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4200 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.chunk "See the npm package") Creates an array of elements split into groups the length of `size`. If `collection` can't be split evenly, the final chunk will be the remaining @@ -341,7 +341,7 @@ _.chunk(['a', 'b', 'c', 'd'], 3); ### `_.compact(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4228 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.compact "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4231 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.compact "See the npm package") Creates an array with all falsey values removed. The values `false`, `null`, `0`, `""`, `undefined`, and `NaN` are falsey. @@ -364,7 +364,7 @@ _.compact([0, 1, false, 2, '', 3]); ### `_.difference(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4263 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.difference "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4266 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.difference "See the npm package") Creates an array excluding all values of the provided arrays using `SameValueZero` for equality comparisons. @@ -394,7 +394,7 @@ _.difference([1, 2, 3], [4, 2]); ### `_.drop(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4300 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.drop "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4303 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.drop "See the npm package") Creates a slice of `array` with `n` elements dropped from the beginning. @@ -426,7 +426,7 @@ _.drop([1, 2, 3], 0); ### `_.dropRight(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4335 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4338 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropright "See the npm package") Creates a slice of `array` with `n` elements dropped from the end. @@ -458,7 +458,7 @@ _.dropRight([1, 2, 3], 0); ### `_.dropRightWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4396 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4399 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package") Creates a slice of `array` excluding elements dropped from the end. Elements are dropped until `predicate` returns falsey. The predicate is @@ -518,7 +518,7 @@ _.pluck(_.dropRightWhile(users, 'active'), 'user'); ### `_.dropWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4455 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4458 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropwhile "See the npm package") Creates a slice of `array` excluding elements dropped from the beginning. Elements are dropped until `predicate` returns falsey. The predicate is @@ -578,7 +578,7 @@ _.pluck(_.dropWhile(users, 'active'), 'user'); ### `_.fill(array, value, [start=0], [end=array.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4481 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.fill "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4484 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.fill "See the npm package") Fills elements of `array` with `value` from `start` up to, but not including, `end`. @@ -602,7 +602,7 @@ including, `end`. ### `_.findIndex(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4541 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4544 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findindex "See the npm package") This method is like `_.find` except that it returns the index of the first element `predicate` returns truthy for, instead of the element itself. @@ -661,7 +661,7 @@ _.findIndex(users, 'active'); ### `_.findLastIndex(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4602 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4605 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastindex "See the npm package") This method is like `_.findIndex` except that it iterates over elements of `collection` from right to left. @@ -720,7 +720,7 @@ _.findLastIndex(users, 'active'); ### `_.first(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4630 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.first "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4633 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.first "See the npm package") Gets the first element of `array`. @@ -745,7 +745,7 @@ _.first([]); ### `_.flatten(array, [isDeep])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4654 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatten "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4657 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatten "See the npm package") Flattens a nested array. If `isDeep` is `true` the array is recursively flattened, otherwise it is only flattened a single level. @@ -773,7 +773,7 @@ _.flatten([1, [2, 3, [4]]], true); ### `_.flattenDeep(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4675 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4678 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendeep "See the npm package") Recursively flattens a nested array. @@ -795,7 +795,7 @@ _.flattenDeep([1, [2, 3, [4]]]); ### `_.indexOf(array, value, [fromIndex=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4712 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4715 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexof "See the npm package") Gets the index at which the first occurrence of `value` is found in `array` using `SameValueZero` for equality comparisons. If `fromIndex` is negative, @@ -836,7 +836,7 @@ _.indexOf([1, 1, 2, 2], 2, true); ### `_.initial(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4741 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.initial "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4744 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.initial "See the npm package") Gets all but the last element of `array`. @@ -858,7 +858,7 @@ _.initial([1, 2, 3]); ### `_.intersection([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4763 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersection "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4766 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersection "See the npm package") Creates an array of unique values in all provided arrays using `SameValueZero` for equality comparisons. @@ -887,7 +887,7 @@ _.intersection([1, 2], [4, 2], [2, 1]); ### `_.last(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4818 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.last "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4821 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.last "See the npm package") Gets the last element of `array`. @@ -909,7 +909,7 @@ _.last([1, 2, 3]); ### `_.lastIndexOf(array, value, [fromIndex=array.length-1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4848 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lastindexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4851 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lastindexof "See the npm package") This method is like `_.indexOf` except that it iterates over elements of `array` from right to left. @@ -942,7 +942,7 @@ _.lastIndexOf([1, 1, 2, 2], 2, true); ### `_.pull(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4896 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pull "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4899 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pull "See the npm package") Removes all provided values from `array` using `SameValueZero` for equality comparisons. @@ -978,7 +978,7 @@ console.log(array); ### `_.pullAt(array, [indexes])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4941 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4944 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullat "See the npm package") Removes elements from `array` corresponding to the given indexes and returns an array of the removed elements. Indexes may be specified as an array of @@ -1012,7 +1012,7 @@ console.log(evens); ### `_.remove(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L4984 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.remove "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L4987 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.remove "See the npm package") Removes all elements from `array` that `predicate` returns truthy for and returns an array of the removed elements. The predicate is bound to @@ -1063,7 +1063,7 @@ console.log(evens); ### `_.rest(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5015 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rest "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5018 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rest "See the npm package") Gets all but the first element of `array`. @@ -1085,7 +1085,7 @@ _.rest([1, 2, 3]); ### `_.slice(array, [start=0], [end=array.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5033 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.slice "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5036 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.slice "See the npm package") Creates a slice of `array` from `start` up to, but not including, `end`.
@@ -1108,7 +1108,7 @@ lists in IE < 9 and to ensure dense arrays are returned. ### `_.sortedIndex(array, value, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5093 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5096 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindex "See the npm package") Uses a binary search to determine the lowest index at which `value` should be inserted into `array` in order to maintain its sort order. If an iteratee @@ -1167,7 +1167,7 @@ _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); ### `_.sortedLastIndex(array, value, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5120 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5123 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package") This method is like `_.sortedIndex` except that it returns the highest index at which `value` should be inserted into `array` in order to @@ -1195,7 +1195,7 @@ _.sortedLastIndex([4, 4, 5, 5], 5); ### `_.take(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5151 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.take "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5154 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.take "See the npm package") Creates a slice of `array` with `n` elements taken from the beginning. @@ -1227,7 +1227,7 @@ _.take([1, 2, 3], 0); ### `_.takeRight(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5186 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takeright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5189 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takeright "See the npm package") Creates a slice of `array` with `n` elements taken from the end. @@ -1259,7 +1259,7 @@ _.takeRight([1, 2, 3], 0); ### `_.takeRightWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5247 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5250 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package") Creates a slice of `array` with elements taken from the end. Elements are taken until `predicate` returns falsey. The predicate is bound to `thisArg` @@ -1319,7 +1319,7 @@ _.pluck(_.takeRightWhile(users, 'active'), 'user'); ### `_.takeWhile(array, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5306 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takewhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5309 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takewhile "See the npm package") Creates a slice of `array` with elements taken from the beginning. Elements are taken until `predicate` returns falsey. The predicate is bound to @@ -1379,7 +1379,7 @@ _.pluck(_.takeWhile(users, 'active'), 'user'); ### `_.union([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5336 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.union "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5339 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.union "See the npm package") Creates an array of unique values, in order, of the provided arrays using `SameValueZero` for equality comparisons. @@ -1408,7 +1408,7 @@ _.union([1, 2], [4, 2], [2, 1]); ### `_.uniq(array, [isSorted], [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5392 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniq "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5395 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniq "See the npm package") Creates a duplicate-value-free version of an array using `SameValueZero` for equality comparisons. Providing `true` for `isSorted` performs a faster @@ -1472,7 +1472,7 @@ _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); ### `_.unzip(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5429 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5432 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzip "See the npm package") This method is like `_.zip` except that it accepts an array of grouped elements and creates an array regrouping the elements to their pre-`_.zip` @@ -1499,7 +1499,7 @@ _.unzip(zipped); ### `_.without(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5460 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.without "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5463 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.without "See the npm package") Creates an array excluding all provided values using `SameValueZero` for equality comparisons. @@ -1529,7 +1529,7 @@ _.without([1, 2, 1, 3], 1, 2); ### `_.xor([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5479 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xor "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5482 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xor "See the npm package") Creates an array that is the symmetric difference of the provided arrays. See [Wikipedia](https://en.wikipedia.org/wiki/Symmetric_difference) for @@ -1553,7 +1553,7 @@ _.xor([1, 2], [4, 2]); ### `_.zip([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5509 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5512 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zip "See the npm package") Creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements @@ -1577,7 +1577,7 @@ _.zip(['fred', 'barney'], [30, 40], [true, false]); ### `_.zipObject(props, [values=[]])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5536 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5539 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobject "See the npm package") Creates an object composed from arrays of property names and values. Provide either a single two dimensional array, e.g. `[[key1, value1], [key2, value2]]` @@ -1608,7 +1608,7 @@ _.zipObject(['fred', 'barney'], [30, 40]); ### `_(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L938 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L938 "View in source") [Ⓣ][1] Creates a `lodash` object which wraps `value` to enable implicit chaining. Methods that operate on and return arrays, collections, and functions can @@ -1712,7 +1712,7 @@ _.isArray(squares.value()); ### `_.chain(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5583 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5586 "View in source") [Ⓣ][1] Creates a `lodash` object that wraps `value` with explicit method chaining enabled. @@ -1747,7 +1747,7 @@ var youngest = _.chain(users) ### `_.tap(value, interceptor, [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5612 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5615 "View in source") [Ⓣ][1] This method invokes `interceptor` and returns `value`. The interceptor is bound to `thisArg` and invoked with one argument; (value). The purpose of @@ -1779,7 +1779,7 @@ _([1, 2, 3]) ### `_.thru(value, interceptor, [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5637 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5640 "View in source") [Ⓣ][1] This method is like `_.tap` except that it returns the result of `interceptor`. @@ -1808,7 +1808,7 @@ _([1, 2, 3]) ### `_.prototype.chain()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5666 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5669 "View in source") [Ⓣ][1] Enables explicit method chaining on the wrapper object. @@ -1840,7 +1840,7 @@ _(users).chain() ### `_.prototype.commit()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5695 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5698 "View in source") [Ⓣ][1] Executes the chained sequence and returns the wrapped result. @@ -1872,7 +1872,7 @@ console.log(array); ### `_.prototype.plant()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5722 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5725 "View in source") [Ⓣ][1] Creates a clone of the chained sequence planting `value` as the wrapped value. @@ -1902,7 +1902,7 @@ wrapper.value(); ### `_.prototype.reverse()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5760 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5763 "View in source") [Ⓣ][1] Reverses the wrapped array so the first element becomes the last, the second element becomes the second to last, and so on. @@ -1930,7 +1930,7 @@ console.log(array); ### `_.prototype.toString()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5785 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5788 "View in source") [Ⓣ][1] Produces the result of coercing the unwrapped value to a string. @@ -1949,7 +1949,7 @@ _([1, 2, 3]).toString(); ### `_.prototype.value()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5802 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5805 "View in source") [Ⓣ][1] Executes the chained sequence to extract the unwrapped value. @@ -1974,7 +1974,7 @@ _([1, 2, 3]).value(); ### `_.at(collection, [props])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5828 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.at "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5831 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.at "See the npm package") Creates an array of elements corresponding to the given keys, or indexes, of `collection`. Keys may be specified as individual arguments or as arrays @@ -2002,7 +2002,7 @@ _.at(['fred', 'barney', 'pebbles'], 0, 2); ### `_.countBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5877 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.countby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5880 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.countby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2054,7 +2054,7 @@ _.countBy(['one', 'two', 'three'], 'length'); ### `_.every(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5929 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.every "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5932 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.every "See the npm package") Checks if `predicate` returns truthy for **all** elements of `collection`. The predicate is bound to `thisArg` and invoked with three arguments; @@ -2112,7 +2112,7 @@ _.every(users, 'active'); ### `_.filter(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L5986 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.filter "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L5989 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.filter "See the npm package") Iterates over elements of `collection`, returning an array of all elements `predicate` returns truthy for. The predicate is bound to `thisArg` and @@ -2171,7 +2171,7 @@ _.pluck(_.filter(users, 'active'), 'user'); ### `_.find(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6042 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.find "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6045 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.find "See the npm package") Iterates over elements of `collection`, returning the first element `predicate` returns truthy for. The predicate is bound to `thisArg` and @@ -2231,7 +2231,7 @@ _.result(_.find(users, 'active'), 'user'); ### `_.findLast(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6070 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlast "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6073 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlast "See the npm package") This method is like `_.find` except that it iterates over elements of `collection` from right to left. @@ -2258,7 +2258,7 @@ _.findLast([1, 2, 3, 4], function(n) { ### `_.findWhere(collection, source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6104 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findwhere "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6107 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findwhere "See the npm package") Performs a deep comparison between each element in `collection` and the source object, returning the first element that has equivalent property @@ -2297,7 +2297,7 @@ _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); ### `_.forEach(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6138 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreach "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6141 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreach "See the npm package") Iterates over elements of `collection` invoking `iteratee` for each element. The `iteratee` is bound to `thisArg` and invoked with three arguments; @@ -2336,7 +2336,7 @@ _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { ### `_.forEachRight(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6163 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreachright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6166 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreachright "See the npm package") This method is like `_.forEach` except that it iterates over elements of `collection` from right to left. @@ -2363,7 +2363,7 @@ _([1, 2]).forEachRight(function(n) { ### `_.groupBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6211 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.groupby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6214 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.groupby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2416,7 +2416,7 @@ _.groupBy(['one', 'two', 'three'], 'length'); ### `_.includes(collection, target, [fromIndex=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6251 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.includes "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6254 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.includes "See the npm package") Checks if `value` is in `collection` using `SameValueZero` for equality comparisons. If `fromIndex` is negative, it is used as the offset from @@ -2457,7 +2457,7 @@ _.includes('pebbles', 'eb'); ### `_.indexBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6316 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6319 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2514,7 +2514,7 @@ _.indexBy(keyData, function(object) { ### `_.invoke(collection, methodName, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6342 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invoke "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6345 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invoke "See the npm package") Invokes the method named by `methodName` on each element in `collection`, returning an array of the results of each invoked method. Any additional @@ -2544,7 +2544,7 @@ _.invoke([123, 456], String.prototype.split, ''); ### `_.map(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6402 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.map "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6405 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.map "See the npm package") Creates an array of values by running each element in `collection` through `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three @@ -2611,7 +2611,7 @@ _.map(users, 'user'); ### `_.max(collection, [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6455 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.max "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6458 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.max "See the npm package") Gets the maximum value of `collection`. If `collection` is empty or falsey `-Infinity` is returned. If an iteratee function is provided it is invoked @@ -2670,7 +2670,7 @@ _.max(users, 'age'); ### `_.min(collection, [iteratee], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6504 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.min "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6507 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.min "See the npm package") Gets the minimum value of `collection`. If `collection` is empty or falsey `Infinity` is returned. If an iteratee function is provided it is invoked @@ -2729,7 +2729,7 @@ _.min(users, 'age'); ### `_.partition(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6565 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partition "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6568 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partition "See the npm package") Creates an array of elements split into two groups, the first of which contains elements `predicate` returns truthy for, while the second of which @@ -2799,7 +2799,7 @@ _.map(_.partition(users, 'active'), mapper); ### `_.pluck(collection, key)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6592 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pluck "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6595 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pluck "See the npm package") Gets the value of `key` from all elements in `collection`. @@ -2831,7 +2831,7 @@ _.pluck(userIndex, 'age'); ### `_.reduce(collection, [iteratee=_.identity], [accumulator], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6632 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduce "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6635 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduce "See the npm package") Reduces `collection` to a value which is the accumulated result of running each element in `collection` through `iteratee`, where each successive @@ -2877,7 +2877,7 @@ _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { ### `_.reduceRight(collection, [iteratee=_.identity], [accumulator], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6659 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduceright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6662 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduceright "See the npm package") This method is like `_.reduce` except that it iterates over elements of `collection` from right to left. @@ -2907,7 +2907,7 @@ _.reduceRight(array, function(flattened, other) { ### `_.reject(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6711 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6714 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reject "See the npm package") The opposite of `_.filter`; this method returns the elements of `collection` that `predicate` does **not** return truthy for. @@ -2965,7 +2965,7 @@ _.pluck(_.reject(users, 'active'), 'user'); ### `_.sample(collection, [n])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6737 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sample "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6740 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sample "See the npm package") Gets a random element or `n` random elements from a collection. @@ -2991,7 +2991,7 @@ _.sample([1, 2, 3, 4], 2); ### `_.shuffle(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6763 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.shuffle "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6766 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.shuffle "See the npm package") Creates an array of shuffled values, using a version of the Fisher-Yates shuffle. See [Wikipedia](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle) @@ -3015,7 +3015,7 @@ _.shuffle([1, 2, 3, 4]); ### `_.size(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6800 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.size "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6803 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.size "See the npm package") Gets the size of `collection` by returning `collection.length` for array-like values or the number of own enumerable properties for objects. @@ -3044,7 +3044,7 @@ _.size('pebbles'); ### `_.some(collection, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6854 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.some "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6857 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.some "See the npm package") Checks if `predicate` returns truthy for **any** element of `collection`. The function returns as soon as it finds a passing value and does not iterate @@ -3103,7 +3103,7 @@ _.some(users, 'active'); ### `_.sortBy(collection, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6911 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6914 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortby "See the npm package") Creates an array of elements, sorted in ascending order by the results of running each element in a collection through `iteratee`. This method performs @@ -3162,7 +3162,7 @@ _.pluck(_.sortBy(users, 'user'), 'user'); ### `_.sortByAll(collection, props)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L6949 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortbyall "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L6952 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortbyall "See the npm package") This method is like `_.sortBy` except that it sorts by property names instead of an iteratee function. @@ -3193,7 +3193,7 @@ _.map(_.sortByAll(users, ['user', 'age']), _.values); ### `_.where(collection, source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7000 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.where "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7003 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.where "See the npm package") Performs a deep comparison between each element in `collection` and the source object, returning an array of all elements that have equivalent @@ -3238,7 +3238,7 @@ _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); ### `_.now` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7020 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.now "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7023 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.now "See the npm package") Gets the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC). @@ -3263,7 +3263,7 @@ _.defer(function(stamp) { ### `_.after(n, func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7049 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.after "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7052 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.after "See the npm package") The opposite of `_.before`; this method creates a function that invokes `func` once it is called `n` or more times. @@ -3295,7 +3295,7 @@ _.forEach(saves, function(type) { ### `_.ary(func, [n=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7083 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ary "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7086 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ary "See the npm package") Creates a function that accepts up to `n` arguments ignoring any additional arguments. @@ -3319,7 +3319,7 @@ _.map(['6', '8', '10'], _.ary(parseInt, 1)); ### `_.before(n, func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7107 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.before "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7110 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.before "See the npm package") Creates a function that invokes `func`, with the `this` binding and arguments of the created function, while it is called less than `n` times. Subsequent @@ -3344,7 +3344,7 @@ jQuery('#add').on('click', _.before(5, addContactToList)); ### `_.bind(func, thisArg, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7163 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bind "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7166 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bind "See the npm package") Creates a function that invokes `func` with the `this` binding of `thisArg` and prepends any additional `_.bind` arguments to those provided to the @@ -3390,7 +3390,7 @@ bound('hi'); ### `_.bindAll(object, [methodNames])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7202 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindall "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7205 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindall "See the npm package") Binds methods of an object to the object itself, overwriting the existing method. Method names may be specified as individual arguments or as arrays @@ -3427,7 +3427,7 @@ jQuery('#docs').on('click', view.onClick); ### `_.bindKey(object, key, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7254 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7257 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindkey "See the npm package") Creates a function that invokes the method at `object[key]` and prepends any additional `_.bindKey` arguments to those provided to the bound function. @@ -3482,7 +3482,7 @@ bound('hi'); ### `_.curry(func, [arity=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7305 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curry "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7308 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curry "See the npm package") Creates a function that accepts one or more arguments of `func` that when called either invokes `func` returning its result, if all `func` arguments @@ -3532,7 +3532,7 @@ curried(1)(_, 3)(2); ### `_.curryRight(func, [arity=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7351 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curryright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7354 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curryright "See the npm package") This method is like `_.curry` except that arguments are applied to `func` in the manner of `_.partialRight` instead of `_.partial`. @@ -3578,8 +3578,8 @@ curried(3)(1, _)(2); -### `_.debounce(func, wait, [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7422 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.debounce "See the npm package") +### `_.debounce(func, [wait=0], [options])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7425 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.debounce "See the npm package") Creates a function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time it was invoked. The created function comes @@ -3599,7 +3599,7 @@ for details over the differences between `_.debounce` and `_.throttle`. #### Arguments 1. `func` *(Function)*: The function to debounce. -2. `wait` *(number)*: The number of milliseconds to delay. +2. `[wait=0]` *(number)*: The number of milliseconds to delay. 3. `[options]` *(Object)*: The options object. 4. `[options.leading=false]` *(boolean)*: Specify invoking on the leading edge of the timeout. 5. `[options.maxWait]` *(number)*: The maximum time `func` is allowed to be delayed before it is invoked. @@ -3649,7 +3649,7 @@ delete models.todo; ### `_.defer(func, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7553 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defer "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7556 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defer "See the npm package") Defers invoking the `func` until the current call stack has cleared. Any additional arguments are provided to `func` when it is invoked. @@ -3675,7 +3675,7 @@ _.defer(function(text) { ### `_.delay(func, wait, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7575 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.delay "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7578 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.delay "See the npm package") Invokes `func` after `wait` milliseconds. Any additional arguments are provided to `func` when it is invoked. @@ -3702,7 +3702,7 @@ _.delay(function(text) { ### `_.flow([funcs])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7603 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flow "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7606 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flow "See the npm package") Creates a function that returns the result of invoking the provided functions with the `this` binding of the created function, where each @@ -3735,7 +3735,7 @@ addSquare(1, 2); ### `_.flowRight([funcs])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7648 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flowright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7651 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flowright "See the npm package") This method is like `_.flow` except that it creates a function that invokes the provided functions from right to left. @@ -3767,7 +3767,7 @@ addSquare(1, 2); ### `_.memoize(func, [resolver])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7722 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.memoize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7725 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.memoize "See the npm package") Creates a function that memoizes the result of `func`. If `resolver` is provided it determines the cache key for storing the result based on the @@ -3830,7 +3830,7 @@ identity(other); ### `_.negate(predicate)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7760 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.negate "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7763 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.negate "See the npm package") Creates a function that negates the result of the predicate `func`. The `func` predicate is invoked with the `this` binding and arguments of the @@ -3858,7 +3858,7 @@ _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); ### `_.once(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7786 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.once "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7789 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.once "See the npm package") Creates a function that is restricted to invoking `func` once. Repeat calls to the function return the value of the first call. The `func` is invoked @@ -3884,7 +3884,7 @@ initialize(); ### `_.partial(func, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7822 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partial "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7825 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partial "See the npm package") Creates a function that invokes `func` with `partial` arguments prepended to those provided to the new function. This method is like `_.bind` except @@ -3927,7 +3927,7 @@ greetFred('hi'); ### `_.partialRight(func, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7860 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partialright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partialright "See the npm package") This method is like `_.partial` except that partially applied arguments are appended to those provided to the new function. @@ -3969,7 +3969,7 @@ sayHelloTo('fred'); ### `_.rearg(func, indexes)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7895 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rearg "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7898 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rearg "See the npm package") Creates a function that invokes `func` with arguments arranged according to the specified indexes where the argument value at the first index is @@ -4005,7 +4005,7 @@ map(function(n) { ### `_.spread(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7930 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.spread "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7933 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.spread "See the npm package") Creates a function that invokes `func` with the `this` binding of the created function and the array of arguments provided to the created @@ -4043,8 +4043,8 @@ numbers.then(_.spread(function(x, y) { -### `_.throttle(func, wait, [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L7978 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.throttle "See the npm package") +### `_.throttle(func, [wait=0], [options])` +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L7981 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.throttle "See the npm package") Creates a function that only invokes `func` at most once per every `wait` milliseconds. The created function comes with a `cancel` method to cancel @@ -4064,7 +4064,7 @@ for details over the differences between `_.throttle` and `_.debounce`. #### Arguments 1. `func` *(Function)*: The function to throttle. -2. `wait` *(number)*: The number of milliseconds to throttle invocations to. +2. `[wait=0]` *(number)*: The number of milliseconds to throttle invocations to. 3. `[options]` *(Object)*: The options object. 4. `[options.leading=true]` *(boolean)*: Specify invoking on the leading edge of the timeout. 5. `[options.trailing=true]` *(boolean)*: Specify invoking on the trailing edge of the timeout. @@ -4092,7 +4092,7 @@ jQuery(window).on('popstate', throttled.cancel); ### `_.wrap(value, wrapper)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8018 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.wrap "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8021 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.wrap "See the npm package") Creates a function that provides `value` to the wrapper function as its first argument. Any additional arguments provided to the function are @@ -4128,7 +4128,7 @@ p('fred, barney, & pebbles'); ### `_.clone(value, [isDeep], [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8076 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clone "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8079 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clone "See the npm package") Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, otherwise they are assigned by reference. If `customizer` is provided it is @@ -4189,7 +4189,7 @@ el.childNodes.length; ### `_.cloneDeep(value, [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8134 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8137 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeep "See the npm package") Creates a deep clone of `value`. If `customizer` is provided it is invoked to produce the cloned values. If `customizer` returns `undefined` cloning @@ -4244,7 +4244,7 @@ el.childNodes.length; ### `_.isArguments(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8155 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarguments "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8158 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarguments "See the npm package") Checks if `value` is classified as an `arguments` object. @@ -4269,7 +4269,7 @@ _.isArguments([1, 2, 3]); ### `_.isArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8184 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8187 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarray "See the npm package") Checks if `value` is classified as an `Array` object. @@ -4294,7 +4294,7 @@ _.isArray(function() { return arguments; }()); ### `_.isBoolean(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8204 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isboolean "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8207 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isboolean "See the npm package") Checks if `value` is classified as a boolean primitive or object. @@ -4319,7 +4319,7 @@ _.isBoolean(null); ### `_.isDate(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8224 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isdate "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8227 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isdate "See the npm package") Checks if `value` is classified as a `Date` object. @@ -4344,7 +4344,7 @@ _.isDate('Mon April 23 2012'); ### `_.isElement(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8244 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iselement "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8247 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iselement "See the npm package") Checks if `value` is a DOM element. @@ -4369,7 +4369,7 @@ _.isElement(''); ### `_.isEmpty(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8282 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isempty "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8285 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isempty "See the npm package") Checks if a value is empty. A value is considered empty unless it is an `arguments` object, array, string, or jQuery-like collection with a length @@ -4405,7 +4405,7 @@ _.isEmpty({ 'a': 1 }); ### `_.isEqual(value, other, [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8337 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequal "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8340 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequal "See the npm package") Performs a deep comparison between two values to determine if they are equivalent. If `customizer` is provided it is invoked to compare values. @@ -4458,7 +4458,7 @@ _.isEqual(array, other, function(value, other) { ### `_.isError(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8363 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iserror "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8366 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iserror "See the npm package") Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, or `URIError` object. @@ -4484,7 +4484,7 @@ _.isError(Error); ### `_.isFinite(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8396 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfinite "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8399 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfinite "See the npm package") Checks if `value` is a finite primitive number.
@@ -4523,7 +4523,7 @@ _.isFinite(Infinity); ### `_.isFunction(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8416 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfunction "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8419 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfunction "See the npm package") Checks if `value` is classified as a `Function` object. @@ -4548,7 +4548,7 @@ _.isFunction(/abc/); ### `_.isMatch(object, source, [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8491 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatch "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8494 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatch "See the npm package") Performs a deep comparison between `object` and `source` to determine if `object` contains equivalent property values. If `customizer` is provided @@ -4597,7 +4597,7 @@ _.isMatch(object, source, function(value, other) { ### `_.isNaN(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8540 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnan "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8543 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnan "See the npm package") Checks if `value` is `NaN`.
@@ -4633,7 +4633,7 @@ _.isNaN(undefined); ### `_.isNative(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8562 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnative "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8565 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnative "See the npm package") Checks if `value` is a native function. @@ -4658,7 +4658,7 @@ _.isNative(_); ### `_.isNull(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8589 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnull "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8592 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnull "See the npm package") Checks if `value` is `null`. @@ -4683,7 +4683,7 @@ _.isNull(void 0); ### `_.isNumber(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8615 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnumber "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8618 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnumber "See the npm package") Checks if `value` is classified as a `Number` primitive or object.
@@ -4715,7 +4715,7 @@ _.isNumber('8.4'); ### `_.isObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8445 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8448 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobject "See the npm package") Checks if `value` is the language type of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) @@ -4747,7 +4747,7 @@ _.isObject(1); ### `_.isPlainObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8649 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isplainobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8652 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isplainobject "See the npm package") Checks if `value` is a plain object, that is, an object created by the `Object` constructor or one with a `[[Prototype]]` of `null`. @@ -4787,7 +4787,7 @@ _.isPlainObject(Object.create(null)); ### `_.isRegExp(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8677 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isregexp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8680 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isregexp "See the npm package") Checks if `value` is classified as a `RegExp` object. @@ -4812,7 +4812,7 @@ _.isRegExp('/abc/'); ### `_.isString(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8697 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isstring "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8700 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isstring "See the npm package") Checks if `value` is classified as a `String` primitive or object. @@ -4837,7 +4837,7 @@ _.isString(1); ### `_.isTypedArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8717 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.istypedarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8720 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.istypedarray "See the npm package") Checks if `value` is classified as a typed array. @@ -4862,7 +4862,7 @@ _.isTypedArray([]); ### `_.isUndefined(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8737 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isundefined "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8740 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isundefined "See the npm package") Checks if `value` is `undefined`. @@ -4887,7 +4887,7 @@ _.isUndefined(null); ### `_.toArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8756 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8759 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toarray "See the npm package") Converts `value` to an array. @@ -4911,7 +4911,7 @@ Converts `value` to an array. ### `_.toPlainObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8792 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toplainobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8795 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toplainobject "See the npm package") Converts `value` to a plain object flattening inherited enumerable properties of `value` to own properties of the plain object. @@ -4949,7 +4949,7 @@ _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); ### `_.inRange(n, [start=0], end)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9722 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.inrange "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9725 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.inrange "See the npm package") Checks if `n` is between `start` and up to but not including, `end`. If `end` is not specified it defaults to `start` with `start` becoming `0`. @@ -4989,7 +4989,7 @@ _.inRange(5.2, 4); ### `_.random([min=0], [max=1], [floating])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9760 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.random "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9763 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.random "See the npm package") Produces a random number between `min` and `max` (inclusive). If only one argument is provided a number between `0` and the given number is returned. @@ -5031,7 +5031,7 @@ _.random(1.2, 5.2); ### `_.assign(object, [sources], [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8827 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assign "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8830 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assign "See the npm package") Assigns own enumerable properties of source object(s) to the destination object. Subsequent sources overwrite property assignments of previous sources. @@ -5068,7 +5068,7 @@ defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); ### `_.create(prototype, [properties])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.create "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8866 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.create "See the npm package") Creates an object that inherits from the given `prototype` object. If a `properties` object is provided its own enumerable properties are assigned @@ -5110,7 +5110,7 @@ circle instanceof Shape; ### `_.defaults(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8887 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaults "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8890 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaults "See the npm package") Assigns own enumerable properties of source object(s) to the destination object for all destination properties that resolve to `undefined`. Once a @@ -5135,7 +5135,7 @@ _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); ### `_.findKey(object, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8944 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L8947 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findkey "See the npm package") This method is like `_.findIndex` except that it returns the key of the first element `predicate` returns truthy for, instead of the element itself. @@ -5194,7 +5194,7 @@ _.findKey(users, 'active'); ### `_.findLastKey(object, [predicate=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L8997 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9000 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastkey "See the npm package") This method is like `_.findKey` except that it iterates over elements of a collection in the opposite order. @@ -5253,7 +5253,7 @@ _.findLastKey(users, 'active'); ### `_.forIn(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9029 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9032 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forin "See the npm package") Iterates over own and inherited enumerable properties of an object invoking `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked @@ -5289,7 +5289,7 @@ _.forIn(new Foo, function(value, key) { ### `_.forInRight(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9061 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forinright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9064 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forinright "See the npm package") This method is like `_.forIn` except that it iterates over properties of `object` in the opposite order. @@ -5323,7 +5323,7 @@ _.forInRight(new Foo, function(value, key) { ### `_.forOwn(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9093 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forown "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9096 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forown "See the npm package") Iterates over own enumerable properties of an object invoking `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked with @@ -5359,7 +5359,7 @@ _.forOwn(new Foo, function(value, key) { ### `_.forOwnRight(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9125 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forownright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9128 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forownright "See the npm package") This method is like `_.forOwn` except that it iterates over properties of `object` in the opposite order. @@ -5393,7 +5393,7 @@ _.forOwnRight(new Foo, function(value, key) { ### `_.functions(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9145 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functions "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9148 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functions "See the npm package") Creates an array of function property names from all enumerable properties, own and inherited, of `object`. @@ -5416,7 +5416,7 @@ _.functions(_); ### `_.has(object, key)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9166 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.has "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9169 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.has "See the npm package") Checks if `key` exists as a direct property of `object` instead of an inherited property. @@ -5442,7 +5442,7 @@ _.has(object, 'b'); ### `_.invert(object, [multiValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9193 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invert "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9196 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invert "See the npm package") Creates an object composed of the inverted keys and values of `object`. If `object` contains duplicate values, subsequent values overwrite property @@ -5473,7 +5473,7 @@ _.invert(object, true); ### `_.keys(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9247 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keys "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9250 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keys "See the npm package") Creates an array of the own enumerable property names of `object`.
@@ -5510,7 +5510,7 @@ _.keys('hi'); ### `_.keysIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9281 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keysin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9284 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keysin "See the npm package") Creates an array of the own and inherited enumerable property names of `object`.
@@ -5542,7 +5542,7 @@ _.keysIn(new Foo); ### `_.mapValues(object, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9380 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapvalues "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9383 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapvalues "See the npm package") Creates an object with the same keys as `object` and values generated by running each own enumerable property of `object` through `iteratee`. The @@ -5594,7 +5594,7 @@ _.mapValues(users, 'age'); ### `_.merge(object, [sources], [customizer], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9438 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.merge "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9441 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.merge "See the npm package") Recursively merges own enumerable properties of the source object(s), that don't resolve to `undefined` into the destination object. Subsequent sources @@ -5651,7 +5651,7 @@ _.merge(object, other, function(a, b) { ### `_.omit(object, [predicate], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9468 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omit "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9471 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omit "See the npm package") The opposite of `_.pick`; this method creates an object composed of the own and inherited enumerable properties of `object` that are not omitted. @@ -5686,7 +5686,7 @@ _.omit(object, _.isNumber); ### `_.pairs(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9496 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pairs "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9499 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pairs "See the npm package") Creates a two dimensional array of the key-value pairs for `object`, e.g. `[[key1, value1], [key2, value2]]`. @@ -5709,7 +5709,7 @@ _.pairs({ 'barney': 36, 'fred': 40 }); ### `_.pick(object, [predicate], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9535 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pick "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9538 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pick "See the npm package") Creates an object composed of the picked `object` properties. Property names may be specified as individual arguments or as arrays of property @@ -5742,7 +5742,7 @@ _.pick(object, _.isString); ### `_.result(object, key, [defaultValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9574 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.result "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9577 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.result "See the npm package") Resolves the value of property `key` on `object`. If the value of `key` is a function it is invoked with the `this` binding of `object` and its result @@ -5780,7 +5780,7 @@ _.result(object, 'status', _.constant('busy')); ### `_.transform(object, [iteratee=_.identity], [accumulator], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9611 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.transform "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9614 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.transform "See the npm package") An alternative to `_.reduce`; this method transforms `object` to a new `accumulator` object which is the result of running each of its own enumerable @@ -5818,7 +5818,7 @@ _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { ### `_.values(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9658 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.values "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9661 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.values "See the npm package") Creates an array of the own enumerable property values of `object`.
@@ -5853,7 +5853,7 @@ _.values('hi'); ### `_.valuesIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9685 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.valuesin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9688 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.valuesin "See the npm package") Creates an array of the own and inherited enumerable property values of `object`. @@ -5892,7 +5892,7 @@ _.valuesIn(new Foo); ### `_.camelCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9817 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.camelcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9820 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.camelcase "See the npm package") Converts `string` to camel case. See [Wikipedia](https://en.wikipedia.org/wiki/CamelCase) for more details. @@ -5921,7 +5921,7 @@ _.camelCase('__foo_bar__'); ### `_.capitalize([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9835 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.capitalize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9838 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.capitalize "See the npm package") Capitalizes the first character of `string`. @@ -5943,7 +5943,7 @@ _.capitalize('fred'); ### `_.deburr([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9855 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.deburr "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9858 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.deburr "See the npm package") Deburrs `string` by converting latin-1 supplementary letters to basic latin letters. See [Wikipedia](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) @@ -5967,7 +5967,7 @@ _.deburr('déjà vu'); ### `_.endsWith([string=''], [target], [position=string.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9881 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.endswith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9884 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.endswith "See the npm package") Checks if `string` ends with the given target string. @@ -5997,7 +5997,7 @@ _.endsWith('abc', 'b', 2); ### `_.escape([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9922 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escape "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9925 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escape "See the npm package") Converts the characters "&", "<", ">", '"', "'", and '`', in `string` to their corresponding HTML entities. @@ -6042,7 +6042,7 @@ _.escape('fred, barney, & pebbles'); ### `_.escapeRegExp([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9944 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9947 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package") Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. @@ -6065,7 +6065,7 @@ _.escapeRegExp('[lodash](https://lodash.com/)'); ### `_.kebabCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9972 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.kebabcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L9975 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.kebabcase "See the npm package") Converts `string` to kebab case. See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) for @@ -6095,7 +6095,7 @@ _.kebabCase('__foo_bar__'); ### `_.pad([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L9999 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pad "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10002 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pad "See the npm package") Pads `string` on the left and right sides if it is shorter then the given padding length. The `chars` string may be truncated if the number of padding @@ -6127,7 +6127,7 @@ _.pad('abc', 3); ### `_.padLeft([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10038 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padleft "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10041 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padleft "See the npm package") Pads `string` on the left side if it is shorter then the given padding length. The `chars` string may be truncated if the number of padding @@ -6159,7 +6159,7 @@ _.padLeft('abc', 3); ### `_.padRight([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10066 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10069 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padright "See the npm package") Pads `string` on the right side if it is shorter then the given padding length. The `chars` string may be truncated if the number of padding @@ -6191,7 +6191,7 @@ _.padRight('abc', 3); ### `_.parseInt(string, [radix])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10094 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.parseint "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10097 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.parseint "See the npm package") Converts `string` to an integer of the specified radix. If `radix` is `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, @@ -6223,7 +6223,7 @@ _.map(['6', '08', '10'], _.parseInt); ### `_.repeat([string=''], [n=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10136 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.repeat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10139 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.repeat "See the npm package") Repeats the given string `n` times. @@ -6252,7 +6252,7 @@ _.repeat('abc', 0); ### `_.snakeCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10176 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.snakecase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10179 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.snakecase "See the npm package") Converts `string` to snake case. See [Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details. @@ -6281,7 +6281,7 @@ _.snakeCase('--foo-bar'); ### `_.startCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10201 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10204 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startcase "See the npm package") Converts `string` to start case. See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage) @@ -6311,7 +6311,7 @@ _.startCase('__foo_bar__'); ### `_.startsWith([string=''], [target], [position=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10226 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startswith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10229 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startswith "See the npm package") Checks if `string` starts with the given target string. @@ -6341,7 +6341,7 @@ _.startsWith('abc', 'b', 1); ### `_.template([string=''], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10328 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.template "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10331 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.template "See the npm package") Creates a compiled template function that can interpolate data properties in "interpolate" delimiters, HTML-escape interpolated data properties in @@ -6448,7 +6448,7 @@ fs.writeFileSync(path.join(cwd, 'jst.js'), '\ ### `_.trim([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10455 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trim "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10458 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trim "See the npm package") Removes leading and trailing whitespace or specified characters from `string`. @@ -6477,7 +6477,7 @@ _.map([' foo ', ' bar '], _.trim); ### `_.trimLeft([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10486 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimleft "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10489 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimleft "See the npm package") Removes leading whitespace or specified characters from `string`. @@ -6503,7 +6503,7 @@ _.trimLeft('-_-abc-_-', '_-'); ### `_.trimRight([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10516 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10519 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimright "See the npm package") Removes trailing whitespace or specified characters from `string`. @@ -6529,7 +6529,7 @@ _.trimRight('-_-abc-_-', '_-'); ### `_.trunc([string=''], [options], [options.length=30], [options.omission='...'], [options.separator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10568 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trunc "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10571 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trunc "See the npm package") Truncates `string` if it is longer than the given maximum string length. The last characters of the truncated string are replaced with the omission @@ -6577,7 +6577,7 @@ _.trunc('hi-diddly-ho there, neighborino', { ### `_.unescape([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10638 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unescape "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10641 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unescape "See the npm package") The inverse of `_.escape`; this method converts the HTML entities `&`, `<`, `>`, `"`, `'`, and ``` in `string` to their @@ -6605,7 +6605,7 @@ _.unescape('fred, barney, & pebbles'); ### `_.words([string=''], [pattern])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10663 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.words "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10666 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.words "See the npm package") Splits `string` into an array of its words. @@ -6637,7 +6637,7 @@ _.words('fred, barney, & pebbles', /[^, ]+/g); ### `_.attempt(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10693 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.attempt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10696 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.attempt "See the npm package") Attempts to invoke `func`, returning either the result or the caught error object. Any additional arguments are provided to `func` when it is invoked. @@ -6666,7 +6666,7 @@ if (_.isError(elements)) { ### `_.callback([func=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10746 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.callback "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10749 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.callback "See the npm package") Creates a function that invokes `func` with the `this` binding of `thisArg` and arguments of the created function. If `func` is a property name the @@ -6711,7 +6711,7 @@ _.filter(users, 'age__gt36'); ### `_.constant(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10771 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.constant "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10774 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.constant "See the npm package") Creates a function that returns `value`. @@ -6736,7 +6736,7 @@ getter() === object; ### `_.identity(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10792 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.identity "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10795 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.identity "See the npm package") This method returns the first argument provided to it. @@ -6760,7 +6760,7 @@ _.identity(object) === object; ### `_.matches(source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10821 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matches "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10824 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matches "See the npm package") Creates a function which performs a deep comparison between a given object and `source`, returning `true` if the given object has equivalent property @@ -6795,7 +6795,7 @@ _.filter(users, _.matches({ 'age': 40, 'active': false })); ### `_.matchesProperty(key, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10850 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10853 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package") Creates a function which compares the property value of `key` on a given object to `value`. @@ -6830,7 +6830,7 @@ _.find(users, _.matchesProperty('user', 'fred')); ### `_.mixin([object=this], source, [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10890 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mixin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10893 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mixin "See the npm package") Adds all own enumerable function properties of a source object to the destination object. If `object` is a function then methods are added to @@ -6874,7 +6874,7 @@ _('fred').vowels(); ### `_.noConflict()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10953 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noconflict "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10956 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noconflict "See the npm package") Reverts the `_` variable to its previous value and returns a reference to the `lodash` function. @@ -6893,7 +6893,7 @@ var lodash = _.noConflict(); ### `_.noop()` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10972 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noop "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L10975 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noop "See the npm package") A no-operation function which returns `undefined` regardless of the arguments it receives. @@ -6912,7 +6912,7 @@ _.noop(object) === undefined; ### `_.property(key)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L10999 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.property "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L11002 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.property "See the npm package") Creates a function which returns the property value of `key` on a given object. @@ -6944,7 +6944,7 @@ _.pluck(_.sortBy(users, getName), 'user'); ### `_.propertyOf(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L11022 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.propertyof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L11025 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.propertyof "See the npm package") The inverse of `_.property`; this method creates a function which returns the property value of a given key on `object`. @@ -6972,7 +6972,7 @@ _.sortBy(['a', 'b', 'c'], _.propertyOf(object)); ### `_.range([start=0], end, [step=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L11061 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.range "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L11064 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.range "See the npm package") Creates an array of numbers (positive and/or negative) progressing from `start` up to, but not including, `end`. If `end` is not specified it @@ -7014,7 +7014,7 @@ _.range(0); ### `_.runInContext([context=root])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L703 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.runincontext "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L703 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.runincontext "See the npm package") Create a new pristine `lodash` function using the given `context` object. @@ -7058,7 +7058,7 @@ var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; ### `_.times(n, [iteratee=_.identity], [thisArg])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L11114 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.times "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L11117 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.times "See the npm package") Invokes the iteratee function `n` times, returning an array of the results of each invocation. The `iteratee` is bound to `thisArg` and invoked with @@ -7094,7 +7094,7 @@ _.times(3, function(n) { ### `_.uniqueId([prefix])` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L11152 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqueid "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L11155 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqueid "See the npm package") Generates a unique ID. If `prefix` is provided the ID is appended to it. @@ -7125,7 +7125,7 @@ _.uniqueId(); ### `_.templateSettings.imports._` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1191 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1191 "View in source") [Ⓣ][1] A reference to the `lodash` function. @@ -7142,7 +7142,7 @@ A reference to the `lodash` function. ### `_.VERSION` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L11423 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L11426 "View in source") [Ⓣ][1] (string): The semantic version number. @@ -7153,7 +7153,7 @@ A reference to the `lodash` function. ### `_.support` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L980 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.support "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L980 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.support "See the npm package") (Object): An object environment feature flags. @@ -7164,7 +7164,7 @@ A reference to the `lodash` function. ### `_.support.argsTag` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L997 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L997 "View in source") [Ⓣ][1] (boolean): Detect if the `toStringTag` of `arguments` objects is resolvable (all but Firefox < 4, IE < 9). @@ -7176,7 +7176,7 @@ A reference to the `lodash` function. ### `_.support.enumErrorProps` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1006 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1006 "View in source") [Ⓣ][1] (boolean): Detect if `name` or `message` properties of `Error.prototype` are enumerable by default (IE < 9, Safari < 5.1). @@ -7188,7 +7188,7 @@ enumerable by default (IE < 9, Safari < 5.1). ### `_.support.enumPrototypes` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1020 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1020 "View in source") [Ⓣ][1] (boolean): Detect if `prototype` properties are enumerable by default.
@@ -7205,7 +7205,7 @@ property to `true`. ### `_.support.funcDecomp` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1030 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1030 "View in source") [Ⓣ][1] (boolean): Detect if functions can be decompiled by `Function#toString` (all but Firefox OS certified apps, older Opera mobile browsers, and @@ -7218,7 +7218,7 @@ the PlayStation 3; forced `false` for Windows 8 apps). ### `_.support.funcNames` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1038 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1038 "View in source") [Ⓣ][1] (boolean): Detect if `Function#name` is supported (all but IE). @@ -7229,7 +7229,7 @@ the PlayStation 3; forced `false` for Windows 8 apps). ### `_.support.nodeTag` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1046 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1046 "View in source") [Ⓣ][1] (boolean): Detect if the `toStringTag` of DOM nodes is resolvable (all but IE < 9). @@ -7240,7 +7240,7 @@ the PlayStation 3; forced `false` for Windows 8 apps). ### `_.support.nonEnumShadows` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1067 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1067 "View in source") [Ⓣ][1] (boolean): Detect if properties shadowing those on `Object.prototype` are non-enumerable. @@ -7256,7 +7256,7 @@ are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). ### `_.support.nonEnumStrings` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1055 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1055 "View in source") [Ⓣ][1] (boolean): Detect if string indexes are non-enumerable (IE < 9, RingoJS, Rhino, Narwhal). @@ -7268,7 +7268,7 @@ are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). ### `_.support.ownLast` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1075 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1075 "View in source") [Ⓣ][1] (boolean): Detect if own properties are iterated after inherited properties (IE < 9). @@ -7279,7 +7279,7 @@ are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). ### `_.support.spliceObjects` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1090 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1090 "View in source") [Ⓣ][1] (boolean): Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. @@ -7298,7 +7298,7 @@ is buggy regardless of mode in IE < 9. ### `_.support.unindexedChars` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1101 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1101 "View in source") [Ⓣ][1] (boolean): Detect lack of support for accessing string characters by index.
@@ -7313,7 +7313,7 @@ by index on string literals, not string objects. ### `_.templateSettings` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1143 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.templatesettings "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1143 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.templatesettings "See the npm package") (Object): By default, the template delimiters used by lodash are like those in embedded Ruby (ERB). Change the following template settings to use @@ -7326,7 +7326,7 @@ alternative delimiters. ### `_.templateSettings.escape` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1151 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1151 "View in source") [Ⓣ][1] (RegExp): Used to detect `data` property values to be HTML-escaped. @@ -7337,7 +7337,7 @@ alternative delimiters. ### `_.templateSettings.evaluate` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1159 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1159 "View in source") [Ⓣ][1] (RegExp): Used to detect code to be evaluated. @@ -7348,7 +7348,7 @@ alternative delimiters. ### `_.templateSettings.imports` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1183 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1183 "View in source") [Ⓣ][1] (Object): Used to import variables into the compiled template. @@ -7359,7 +7359,7 @@ alternative delimiters. ### `_.templateSettings.interpolate` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1167 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1167 "View in source") [Ⓣ][1] (RegExp): Used to detect `data` property values to inject. @@ -7370,7 +7370,7 @@ alternative delimiters. ### `_.templateSettings.variable` -# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.0/lodash.src.js#L1175 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/3.3.1/lodash.src.js#L1175 "View in source") [Ⓣ][1] (string): Used to reference the data object in the template text. diff --git a/lodash.js b/lodash.js index 941668b11a..369ad15f64 100644 --- a/lodash.js +++ b/lodash.js @@ -1,9 +1,9 @@ /** * @license - * lodash 3.3.0 (Custom Build) + * lodash 3.3.1 (Custom Build) * Build: `lodash modern -o ./lodash.js` * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.7.0 + * Based on Underscore.js 1.8.2 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '3.3.0'; + var VERSION = '3.3.1'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -1804,7 +1804,7 @@ var index = -1, indexOf = getIndexOf(), isCommon = indexOf == baseIndexOf, - cache = isCommon && values.length >= 200 && createCache(values), + cache = (isCommon && values.length >= 200) ? createCache(values) : null, valuesLength = values.length; if (cache) { @@ -2624,7 +2624,7 @@ length = array.length, isCommon = indexOf == baseIndexOf, isLarge = isCommon && length >= 200, - seen = isLarge && createCache(), + seen = isLarge ? createCache() : null, result = []; if (seen) { @@ -3676,8 +3676,11 @@ } else { prereq = type == 'string' && index in object; } - var other = object[index]; - return prereq && (value === value ? value === other : other !== other); + if (prereq) { + var other = object[index]; + return value === value ? value === other : other !== other; + } + return false; } /** @@ -4403,7 +4406,7 @@ * // => 2 * * // using the `_.matches` callback shorthand - * _.findLastIndex(users, { user': 'barney', 'active': true }); + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); * // => 0 * * // using the `_.matchesProperty` callback shorthand @@ -4514,7 +4517,7 @@ * @example * * _.indexOf([1, 2, 1, 2], 2); - * // => 2 + * // => 1 * * // using `fromIndex` * _.indexOf([1, 2, 1, 2], 2, 2); @@ -4587,7 +4590,7 @@ var value = arguments[argsIndex]; if (isArray(value) || isArguments(value)) { args.push(value); - caches.push(isCommon && value.length >= 120 && createCache(argsIndex && value)); + caches.push((isCommon && value.length >= 120) ? createCache(argsIndex && value) : null); } } argsLength = args.length; @@ -6655,7 +6658,7 @@ * ]; * * // using the `_.matches` callback shorthand - * _.some(users, { user': 'barney', 'active': false }); + * _.some(users, { 'user': 'barney', 'active': false }); * // => false * * // using the `_.matchesProperty` callback shorthand @@ -7191,7 +7194,7 @@ * @memberOf _ * @category Function * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. + * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options] The options object. * @param {boolean} [options.leading=false] Specify invoking on the leading * edge of the timeout. @@ -7249,7 +7252,7 @@ if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - wait = wait < 0 ? 0 : wait; + wait = wait < 0 ? 0 : (+wait || 0); if (options === true) { var leading = true; trailing = false; @@ -7770,7 +7773,7 @@ * @memberOf _ * @category Function * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle invocations to. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options] The options object. * @param {boolean} [options.leading=true] Specify invoking on the leading * edge of the timeout. @@ -10087,10 +10090,10 @@ * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); * compiled.source; * // => function(data) { - * var __t, __p = ''; - * __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; - * return __p; - * } + * // var __t, __p = ''; + * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; + * // return __p; + * // } * * // using the `source` property to inline compiled templates for meaningful * // line numbers in error messages and a stack trace @@ -11204,15 +11207,13 @@ // Add `LazyWrapper` methods that accept an `iteratee` value. arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { - var isFilter = index == LAZY_FILTER_FLAG, - isWhile = index == LAZY_WHILE_FLAG; + var isFilter = index == LAZY_FILTER_FLAG || index == LAZY_WHILE_FLAG; LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { var result = this.clone(), - filtered = result.__filtered__, iteratees = result.__iteratees__ || (result.__iteratees__ = []); - result.__filtered__ = filtered || isFilter || (isWhile && result.__dir__ < 0); + result.__filtered__ = result.__filtered__ || isFilter; iteratees.push({ 'iteratee': getCallback(iteratee, thisArg, 3), 'type': index }); return result; }; @@ -11279,9 +11280,14 @@ }; LazyWrapper.prototype.dropWhile = function(predicate, thisArg) { - var done; + var done, + lastIndex, + isRight = this.__dir__ < 0; + predicate = getCallback(predicate, thisArg, 3); return this.filter(function(value, index, array) { + done = done && (isRight ? index < lastIndex : index > lastIndex); + lastIndex = index; return done || (done = !predicate(value, index, array)); }); }; diff --git a/lodash.min.js b/lodash.min.js index 8a9315fc55..e5abf6319b 100644 --- a/lodash.min.js +++ b/lodash.min.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.3.0 (Custom Build) lodash.com/license | Underscore.js 1.7.0 underscorejs.org/LICENSE + * lodash 3.3.1 (Custom Build) lodash.com/license | Underscore.js 1.8.2 underscorejs.org/LICENSE * Build: `lodash modern -o ./lodash.js` */ ;(function(){function n(n,t){if(n!==t){var r=n===n,e=t===t;if(n>t||!r||typeof n=="undefined"&&e)return 1;if(ne&&(e=u)}return e}function Gt(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++ui(r,a)&&u.push(a);return u}function fr(n,t){var r=n?n.length:0;if(!fe(r))return vr(n,t);for(var e=-1,u=_e(n);++et&&(t=-t>u?0:u+t),r=typeof r=="undefined"||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=bu(u);++eu(a,s)&&((r||f)&&a.push(s),c.push(l))}return c}function Sr(n,t){for(var r=-1,e=t.length,u=bu(e);++ru(a,s)&&((r||f)&&a.push(s),c.push(l))}return c}function Sr(n,t){for(var r=-1,e=t.length,u=bu(e);++r>>1,i=n[o];(r?i<=t:it||null==r)return r;if(3u)||i===e&&i===o)&&(u=i,o=n)}),o}function ne(n,t,r){var e=Nt.callback||gu,e=e===gu?er:e;return r?e(n,t,r):e}function te(n,r,e){var u=Nt.indexOf||we,u=u===we?t:u;return n?u(n,r,e):u}function re(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&Fu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function ee(n){return n=n.constructor,typeof n=="function"&&n instanceof n||(n=Ru),new n -}function ue(n,t,r){var e=n.constructor;switch(t){case X:return Lr(n);case q:case P:return new e(+n);case H:case Q:case nt:case tt:case rt:case et:case ut:case ot:case it:return t=n.buffer,new e(r?Lr(t):t,n.byteOffset,n.length);case Y:case J:return new e(n);case G:var u=new e(n.source,dt.exec(n));u.lastIndex=n.lastIndex}return u}function oe(n,t){return n=+n,t=null==t?yo:t,-1t?0:t)):[]}function ye(n,t,r){var e=n?n.length:0; return e?((r?ie(n,t,r):null==t)&&(t=1),t=e-(+t||0),Or(n,0,0>t?0:t)):[]}function de(n,t,r){var e=-1,u=n?n.length:0;for(t=ne(t,r,3);++ee?oo(u+e,0):e||0;else if(e)return e=Nr(n,r),n=n[e],(r===r?r===n:n!==n)?e:-1;return t(n,r,e)}function be(n){return ve(n,1)}function xe(n,r,e,u){if(!n||!n.length)return[];null!=r&&typeof r!="boolean"&&(u=e,e=ie(n,r,u)?null:r,r=false); @@ -38,7 +38,7 @@ var o=ne();if((o!==er||null!=e)&&(e=o(e,u,3)),r&&te()==t){r=e;var i;e=-1,u=n.len }function Se(n,t,r){var e=n?n.length:0;return fe(e)||(n=fu(n),e=n.length),e?(r=typeof r=="number"?0>r?oo(e+r,0):r||0:0,typeof n=="string"||!Wo(n)&&ru(n)?rarguments.length,fr)}function Ue(n,t,r,e){return(Wo(n)?Jt:Ir)(n,ne(t,e,4),r,3>arguments.length,ar)}function Fe(n,t,r){return(r?ie(n,t,r):null==t)?(n=he(n),t=n.length,0t?0:+t||0,n.length),n) }function Le(n){n=he(n);for(var t=-1,r=n.length,e=bu(r);++t=r||r>t?(f&&Pu(f),r=p,f=s=p=b,r&&(h=So(),a=n.apply(l,i),s||f||(i=l=null))):s=Ju(e,r)}function u(){s&&Pu(s),f=s=p=b,(g||_!==t)&&(h=So(),a=n.apply(l,i),s||f||(i=l=null)) -}function o(){if(i=arguments,c=So(),l=this,p=g&&(s||!v),false===_)var r=v&&!s;else{f||v||(h=c);var o=_-(c-h),y=0>=o||o>_;y?(f&&(f=Pu(f)),h=c,a=n.apply(l,i)):f||(f=Ju(u,o))}return y&&s?s=Pu(s):s||t===_||(s=Ju(e,t)),r&&(y=true,a=n.apply(l,i)),!y||s||f||(i=l=null),a}var i,f,a,c,l,s,p,h=0,_=false,g=true;if(typeof n!="function")throw new Cu(B);if(t=0>t?0:t,true===r)var v=true,g=false;else He(r)&&(v=r.leading,_="maxWait"in r&&oo(+r.maxWait||0,t),g="trailing"in r?r.trailing:g);return o.cancel=function(){s&&Pu(s),f&&Pu(f),f=s=p=b +}function o(){if(i=arguments,c=So(),l=this,p=g&&(s||!v),false===_)var r=v&&!s;else{f||v||(h=c);var o=_-(c-h),y=0>=o||o>_;y?(f&&(f=Pu(f)),h=c,a=n.apply(l,i)):f||(f=Ju(u,o))}return y&&s?s=Pu(s):s||t===_||(s=Ju(e,t)),r&&(y=true,a=n.apply(l,i)),!y||s||f||(i=l=null),a}var i,f,a,c,l,s,p,h=0,_=false,g=true;if(typeof n!="function")throw new Cu(B);if(t=0>t?0:+t||0,true===r)var v=true,g=false;else He(r)&&(v=r.leading,_="maxWait"in r&&oo(+r.maxWait||0,t),g="trailing"in r?r.trailing:g);return o.cancel=function(){s&&Pu(s),f&&Pu(f),f=s=p=b },o}function Ke(){var n=arguments,t=n.length-1;if(0>t)return function(n){return n};if(!Kt(n,r))throw new Cu(B);return function(){for(var r=t,e=n[r].apply(this,arguments);r--;)e=n[r].call(this,e);return e}}function Ve(n,t){function r(){var e=r.cache,u=t?t.apply(this,arguments):arguments[0];if(e.has(u))return e.get(u);var o=n.apply(this,arguments);return e.set(u,o),o}if(typeof n!="function"||t&&typeof t!="function")throw new Cu(B);return r.cache=new Ve.Cache,r}function Ye(n){var t=Or(arguments,1),r=v(t,Ye.placeholder); return Gr(n,I,null,t,r)}function Ze(n){var t=Or(arguments,1),r=v(t,Ze.placeholder);return Gr(n,O,null,t,r)}function Ge(n){return fe(_(n)?n.length:b)&&$u.call(n)==D||false}function Je(n){return n&&1===n.nodeType&&_(n)&&-1<$u.call(n).indexOf("Element")||false}function Xe(n){return _(n)&&typeof n.message=="string"&&$u.call(n)==K||false}function He(n){var t=typeof n;return"function"==t||n&&"object"==t||false}function Qe(n){return null==n?false:$u.call(n)==V?zu.test(Nu.call(n)):_(n)&&bt.test(n)||false}function nu(n){return typeof n=="number"||_(n)&&$u.call(n)==Y||false }function tu(n){return _(n)&&$u.call(n)==G||false}function ru(n){return typeof n=="string"||_(n)&&$u.call(n)==J||false}function eu(n){return _(n)&&fe(n.length)&&Tt[$u.call(n)]||false}function uu(n){return rr(n,iu(n))}function ou(n){return dr(n,iu(n))}function iu(n){if(null==n)return[];He(n)||(n=Ru(n));for(var t=n.length,t=t&&fe(t)&&(Wo(n)||wo.nonEnumArgs&&Ge(n))&&t||0,r=n.constructor,e=-1,r=typeof r=="function"&&r.prototype===n,u=bu(t),o=0r&&(r=-r>u?0:u+r),e=typeof e=="undefined"||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r(s?Dt(s,f):o(l,f))){for(r=e;--r;){var p=u[r];if(0>(p?Dt(p,f):o(n[r],f)))continue n}s&&s.push(f),l.push(f)}return l},Nt.invert=function(n,t,r){r&&ie(n,t,r)&&(t=null),r=-1; +},Nt.functions=ou,Nt.groupBy=Ro,Nt.indexBy=Io,Nt.initial=function(n){return ye(n,1)},Nt.intersection=function(){for(var n=[],r=-1,e=arguments.length,u=[],o=te(),i=o==t;++r(s?Dt(s,f):o(l,f))){for(r=e;--r;){var p=u[r];if(0>(p?Dt(p,f):o(n[r],f)))continue n}s&&s.push(f),l.push(f)}return l},Nt.invert=function(n,t,r){r&&ie(n,t,r)&&(t=null),r=-1; for(var e=$o(n),u=e.length,o={};++r=n.length)return n;if(e-=r.length,1>e)return r; if(t=n.slice(0,e),null==o)return t+r;if(tu(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Iu(o.source,(dt.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),-1o.__dir__,f.push({iteratee:ne(n,u,3),type:t}),o +return vr(Nt,function(t,r){Nt.prototype[r]||(n[r]=t)}),n}(),false),Nt.sample=Fe,Nt.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return Fe(t,n)}):Fe(this.value())},Nt.VERSION=x,Pt("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nt[n].placeholder=Nt}),Pt(["filter","map","takeWhile"],function(n,t){var r=t==F||t==$;Lt.prototype[n]=function(n,e){var u=this.clone(),o=u.__iteratees__||(u.__iteratees__=[]);return u.__filtered__=u.__filtered__||r,o.push({iteratee:ne(n,e,3),type:t}),u }}),Pt(["drop","take"],function(n,t){var r="__"+n+"Count__",e=n+"While";Lt.prototype[n]=function(e){e=null==e?1:oo(Ku(e)||0,0);var u=this.clone();if(u.__filtered__){var o=u[r];u[r]=t?io(o,e):o+e}else(u.__views__||(u.__views__=[])).push({size:e,type:n+(0>u.__dir__?"Right":"")});return u},Lt.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()},Lt.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[e](n,t).reverse()}}),Pt(["first","last"],function(n,t){var r="take"+(t?"Right":""); -Lt.prototype[n]=function(){return this[r](1).value()[0]}}),Pt(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Lt.prototype[n]=function(){return this[r](1)}}),Pt(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?Ar:Er;Lt.prototype[n]=function(n){return this[r](e(n))}}),Lt.prototype.compact=function(){return this.filter(yu)},Lt.prototype.dropWhile=function(n,t){var r;return n=ne(n,t,3),this.filter(function(t,e,u){return r||(r=!n(t,e,u))})},Lt.prototype.reject=function(n,t){return n=ne(n,t,3),this.filter(function(t,r,e){return!n(t,r,e) -})},Lt.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=0>n?this.takeRight(-n):this.drop(n);return typeof t!="undefined"&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Lt.prototype.toArray=function(){return this.drop(0)},vr(Lt.prototype,function(n,t){var r=Nt[t],e=/^(?:first|last)$/.test(t);Nt.prototype[t]=function(){function t(n){return n=[n],Yu.apply(n,o),r.apply(Nt,n)}var u=this.__wrapped__,o=arguments,i=this.__chain__,f=!!this.__actions__.length,a=u instanceof Lt,c=a&&!f;return e&&!i?c?n.call(u):r.call(Nt,this.value()):a||Wo(u)?(u=n.apply(c?u:new Lt(this),o),e||!f&&!u.__actions__||(u.__actions__||(u.__actions__=[])).push({func:Ee,args:[t],thisArg:Nt}),new Ft(u,i)):this.thru(t) -}}),Pt("concat join pop push shift sort splice unshift".split(" "),function(n){var t=Tu[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|shift)$/.test(n);Nt.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),Lt.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Lt(this.__wrapped__);return e.__actions__=n?qt(n):null,e.__dir__=this.__dir__,e.__dropCount__=this.__dropCount__,e.__filtered__=this.__filtered__,e.__iteratees__=t?qt(t):null,e.__takeCount__=this.__takeCount__,e.__views__=r?qt(r):null,e -},Lt.prototype.reverse=function(){if(this.__filtered__){var n=new Lt(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Lt.prototype.value=function(){var n=this.__wrapped__.value();if(!Wo(n))return Wr(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,o=0,i=-1,f=u?u.length:0;++i"'`]/g,pt=RegExp(lt.source),ht=RegExp(st.source),_t=/<%-([\s\S]+?)%>/g,gt=/<%([\s\S]+?)%>/g,vt=/<%=([\s\S]+?)%>/g,yt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,dt=/\w*$/,mt=/^\s*function[ \n\r\t]+\w/,wt=/^0[xX]/,bt=/^\[object .+?Constructor\]$/,xt=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,At=/($^)/,jt=/[.*+?^${}()|[\]\/\\]/g,kt=RegExp(jt.source),Et=/\bthis\b/,Rt=/['\n\r\u2028\u2029\\]/g,It=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]{2,}(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Ot=" \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",Ct="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window WinRTError".split(" "),Tt={}; +Lt.prototype[n]=function(){return this[r](1).value()[0]}}),Pt(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Lt.prototype[n]=function(){return this[r](1)}}),Pt(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?Ar:Er;Lt.prototype[n]=function(n){return this[r](e(n))}}),Lt.prototype.compact=function(){return this.filter(yu)},Lt.prototype.dropWhile=function(n,t){var r,e,u=0>this.__dir__;return n=ne(n,t,3),this.filter(function(t,o,i){return r=r&&(u?oe),e=o,r||(r=!n(t,o,i))}) +},Lt.prototype.reject=function(n,t){return n=ne(n,t,3),this.filter(function(t,r,e){return!n(t,r,e)})},Lt.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=0>n?this.takeRight(-n):this.drop(n);return typeof t!="undefined"&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Lt.prototype.toArray=function(){return this.drop(0)},vr(Lt.prototype,function(n,t){var r=Nt[t],e=/^(?:first|last)$/.test(t);Nt.prototype[t]=function(){function t(n){return n=[n],Yu.apply(n,o),r.apply(Nt,n)}var u=this.__wrapped__,o=arguments,i=this.__chain__,f=!!this.__actions__.length,a=u instanceof Lt,c=a&&!f; +return e&&!i?c?n.call(u):r.call(Nt,this.value()):a||Wo(u)?(u=n.apply(c?u:new Lt(this),o),e||!f&&!u.__actions__||(u.__actions__||(u.__actions__=[])).push({func:Ee,args:[t],thisArg:Nt}),new Ft(u,i)):this.thru(t)}}),Pt("concat join pop push shift sort splice unshift".split(" "),function(n){var t=Tu[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|shift)$/.test(n);Nt.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n) +})}}),Lt.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Lt(this.__wrapped__);return e.__actions__=n?qt(n):null,e.__dir__=this.__dir__,e.__dropCount__=this.__dropCount__,e.__filtered__=this.__filtered__,e.__iteratees__=t?qt(t):null,e.__takeCount__=this.__takeCount__,e.__views__=r?qt(r):null,e},Lt.prototype.reverse=function(){if(this.__filtered__){var n=new Lt(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Lt.prototype.value=function(){var n=this.__wrapped__.value(); +if(!Wo(n))return Wr(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,o=0,i=-1,f=u?u.length:0;++i"'`]/g,pt=RegExp(lt.source),ht=RegExp(st.source),_t=/<%-([\s\S]+?)%>/g,gt=/<%([\s\S]+?)%>/g,vt=/<%=([\s\S]+?)%>/g,yt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,dt=/\w*$/,mt=/^\s*function[ \n\r\t]+\w/,wt=/^0[xX]/,bt=/^\[object .+?Constructor\]$/,xt=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,At=/($^)/,jt=/[.*+?^${}()|[\]\/\\]/g,kt=RegExp(jt.source),Et=/\bthis\b/,Rt=/['\n\r\u2028\u2029\\]/g,It=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]{2,}(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Ot=" \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",Ct="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window WinRTError".split(" "),Tt={}; Tt[H]=Tt[Q]=Tt[nt]=Tt[tt]=Tt[rt]=Tt[et]=Tt[ut]=Tt[ot]=Tt[it]=true,Tt[D]=Tt[M]=Tt[X]=Tt[q]=Tt[P]=Tt[K]=Tt[V]=Tt["[object Map]"]=Tt[Y]=Tt[Z]=Tt[G]=Tt["[object Set]"]=Tt[J]=Tt["[object WeakMap]"]=false;var St={};St[D]=St[M]=St[X]=St[q]=St[P]=St[H]=St[Q]=St[nt]=St[tt]=St[rt]=St[Y]=St[Z]=St[G]=St[J]=St[et]=St[ut]=St[ot]=St[it]=true,St[K]=St[V]=St["[object Map]"]=St["[object Set]"]=St["[object WeakMap]"]=false;var Wt={leading:false,maxWait:0,trailing:false},Nt={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ut={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Ft={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Lt={"function":true,object:true},$t={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Bt=Lt[typeof window]&&window!==(this&&this.window)?window:this,zt=Lt[typeof exports]&&exports&&!exports.nodeType&&exports,Lt=Lt[typeof module]&&module&&!module.nodeType&&module,Dt=zt&&Lt&&typeof global=="object"&&global; !Dt||Dt.global!==Dt&&Dt.window!==Dt&&Dt.self!==Dt||(Bt=Dt);var Dt=Lt&&Lt.exports===zt&&zt,Mt=w();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Bt._=Mt, define(function(){return Mt})):zt&&Lt?Dt?(Lt.exports=Mt)._=Mt:zt._=Mt:Bt._=Mt}).call(this); \ No newline at end of file diff --git a/lodash.src.js b/lodash.src.js index 80a6cc5bc8..d65e6061af 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -1,8 +1,8 @@ /** * @license - * lodash 3.3.0 + * lodash 3.3.1 * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.7.0 + * Based on Underscore.js 1.8.2 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ @@ -12,7 +12,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '3.3.0'; + var VERSION = '3.3.1'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -1963,7 +1963,7 @@ var index = -1, indexOf = getIndexOf(), isCommon = indexOf == baseIndexOf, - cache = isCommon && values.length >= 200 && createCache(values), + cache = (isCommon && values.length >= 200) ? createCache(values) : null, valuesLength = values.length; if (cache) { @@ -2783,7 +2783,7 @@ length = array.length, isCommon = indexOf == baseIndexOf, isLarge = isCommon && length >= 200, - seen = isLarge && createCache(), + seen = isLarge ? createCache() : null, result = []; if (seen) { @@ -3839,8 +3839,11 @@ } else { prereq = type == 'string' && index in object; } - var other = object[index]; - return prereq && (value === value ? value === other : other !== other); + if (prereq) { + var other = object[index]; + return value === value ? value === other : other !== other; + } + return false; } /** @@ -4588,7 +4591,7 @@ * // => 2 * * // using the `_.matches` callback shorthand - * _.findLastIndex(users, { user': 'barney', 'active': true }); + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); * // => 0 * * // using the `_.matchesProperty` callback shorthand @@ -4699,7 +4702,7 @@ * @example * * _.indexOf([1, 2, 1, 2], 2); - * // => 2 + * // => 1 * * // using `fromIndex` * _.indexOf([1, 2, 1, 2], 2, 2); @@ -4772,7 +4775,7 @@ var value = arguments[argsIndex]; if (isArray(value) || isArguments(value)) { args.push(value); - caches.push(isCommon && value.length >= 120 && createCache(argsIndex && value)); + caches.push((isCommon && value.length >= 120) ? createCache(argsIndex && value) : null); } } argsLength = args.length; @@ -6840,7 +6843,7 @@ * ]; * * // using the `_.matches` callback shorthand - * _.some(users, { user': 'barney', 'active': false }); + * _.some(users, { 'user': 'barney', 'active': false }); * // => false * * // using the `_.matchesProperty` callback shorthand @@ -7376,7 +7379,7 @@ * @memberOf _ * @category Function * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. + * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options] The options object. * @param {boolean} [options.leading=false] Specify invoking on the leading * edge of the timeout. @@ -7434,7 +7437,7 @@ if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - wait = wait < 0 ? 0 : wait; + wait = wait < 0 ? 0 : (+wait || 0); if (options === true) { var leading = true; trailing = false; @@ -7955,7 +7958,7 @@ * @memberOf _ * @category Function * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle invocations to. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options] The options object. * @param {boolean} [options.leading=true] Specify invoking on the leading * edge of the timeout. @@ -10312,10 +10315,10 @@ * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); * compiled.source; * // => function(data) { - * var __t, __p = ''; - * __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; - * return __p; - * } + * // var __t, __p = ''; + * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; + * // return __p; + * // } * * // using the `source` property to inline compiled templates for meaningful * // line numbers in error messages and a stack trace @@ -11429,15 +11432,13 @@ // Add `LazyWrapper` methods that accept an `iteratee` value. arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { - var isFilter = index == LAZY_FILTER_FLAG, - isWhile = index == LAZY_WHILE_FLAG; + var isFilter = index == LAZY_FILTER_FLAG || index == LAZY_WHILE_FLAG; LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { var result = this.clone(), - filtered = result.__filtered__, iteratees = result.__iteratees__ || (result.__iteratees__ = []); - result.__filtered__ = filtered || isFilter || (isWhile && result.__dir__ < 0); + result.__filtered__ = result.__filtered__ || isFilter; iteratees.push({ 'iteratee': getCallback(iteratee, thisArg, 3), 'type': index }); return result; }; @@ -11504,9 +11505,14 @@ }; LazyWrapper.prototype.dropWhile = function(predicate, thisArg) { - var done; + var done, + lastIndex, + isRight = this.__dir__ < 0; + predicate = getCallback(predicate, thisArg, 3); return this.filter(function(value, index, array) { + done = done && (isRight ? index < lastIndex : index > lastIndex); + lastIndex = index; return done || (done = !predicate(value, index, array)); }); }; diff --git a/package.json b/package.json index 75eefc4aa8..14d4ee3248 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "3.3.0", + "version": "3.3.1", "main": "lodash.src.js", "private": true, "devDependencies": { diff --git a/test/test.js b/test/test.js index 805e6307c8..26c611115f 100644 --- a/test/test.js +++ b/test/test.js @@ -833,6 +833,18 @@ } }); + test('should return `false` for non-iteratee calls', 4, function() { + if (func) { + strictEqual(func(2, 0, array), false); + strictEqual(func(1, 1.1, array), false); + strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false); + strictEqual(func(1, 'b', object), false); + } + else { + skipTest(4); + } + }); + test('should work with `NaN` values', 2, function() { if (func) { strictEqual(func(NaN, 0, [NaN]), true); @@ -843,15 +855,17 @@ } }); - test('should return `false` for non-iteratee calls', 4, function() { + test('should not error when `index` is an object without a `toString` method', 1, function() { if (func) { - strictEqual(func(2, 0, array), false); - strictEqual(func(1, 1.1, array), false); - strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false); - strictEqual(func(1, 'b', object), false); + try { + var actual = func(1, { 'toString': null }, [1]); + } catch(e) { + var message = e.message; + } + strictEqual(actual, false, message || ''); } else { - skipTest(4); + skipTest(); } }); }()); @@ -1758,7 +1772,7 @@ .concat([2, 1]) .unshift(5) .tap(function(value) { value.pop(); }) - .map(function(n) { return n * n; }) + .map(square) .value(); deepEqual(actual,[25, 16, 9, 4]); @@ -3212,17 +3226,17 @@ (function() { asyncTest('should debounce a function', 2, function() { if (!(isRhino && isModularize)) { - var count = 0, - debounced = _.debounce(function() { count++; }, 32); + var callCount = 0, + debounced = _.debounce(function() { callCount++; }, 32); debounced(); debounced(); debounced(); - strictEqual(count, 0); + strictEqual(callCount, 0); setTimeout(function() { - strictEqual(count, 1); + strictEqual(callCount, 1); QUnit.start(); }, 96); } @@ -3273,17 +3287,17 @@ asyncTest('should apply default options correctly', 2, function() { if (!(isRhino && isModularize)) { - var count = 0; + var callCount = 0; var debounced = _.debounce(function(value) { - count++; + callCount++; return value; }, 32, {}); strictEqual(debounced('x'), undefined); setTimeout(function() { - strictEqual(count, 1); + strictEqual(callCount, 1); QUnit.start(); }, 64); } @@ -3296,11 +3310,11 @@ asyncTest('should support a `leading` option', 7, function() { if (!(isRhino && isModularize)) { var withLeading, - counts = [0, 0, 0]; + callCounts = [0, 0, 0]; _.each([true, { 'leading': true }], function(options, index) { var debounced = _.debounce(function(value) { - counts[index]++; + callCounts[index]++; return value; }, 32, options); @@ -3316,19 +3330,19 @@ }); var withLeadingAndTrailing = _.debounce(function() { - counts[2]++; + callCounts[2]++; }, 32, { 'leading': true }); withLeadingAndTrailing(); withLeadingAndTrailing(); - strictEqual(counts[2], 1); + strictEqual(callCounts[2], 1); setTimeout(function() { - deepEqual(counts, [1, 1, 2]); + deepEqual(callCounts, [1, 1, 2]); withLeading('x'); - strictEqual(counts[1], 2); + strictEqual(callCounts[1], 2); QUnit.start(); }, 64); @@ -3403,16 +3417,16 @@ asyncTest('should cancel `maxDelayed` when `delayed` is invoked', 1, function() { if (!(isRhino && isModularize)) { - var count = 0; + var callCount = 0; var debounced = _.debounce(function() { - count++; + callCount++; }, 32, { 'maxWait': 64 }); debounced(); setTimeout(function() { - strictEqual(count, 1); + strictEqual(callCount, 1); QUnit.start(); }, 128); } @@ -3425,13 +3439,13 @@ asyncTest('should invoke the `trailing` call with the correct arguments and `this` binding', 2, function() { if (!(isRhino && isModularize)) { var actual, - count = 0, + callCount = 0, object = {}; var debounced = _.debounce(function(value) { actual = [this]; push.apply(actual, arguments); - return ++count != 2; + return ++callCount != 2; }, 32, { 'leading': true, 'maxWait': 64 }); while (true) { @@ -3440,7 +3454,7 @@ } } setTimeout(function() { - strictEqual(count, 2); + strictEqual(callCount, 2); deepEqual(actual, [object, 'a']); QUnit.start(); }, 64); @@ -3908,7 +3922,7 @@ if (!isNpm) { var args; - _(array).map(function(n) { return n * n; }).dropRightWhile(function() { + _(array).map(square).dropRightWhile(function() { args = slice.call(arguments); }).value(); @@ -3971,17 +3985,18 @@ deepEqual(_.dropWhile(objects, 'b'), objects.slice(2)); }); - test('should return a wrapped value when chaining', 2, function() { + test('should work in a lazy chain sequence', 3, function() { if (!isNpm) { var wrapped = _(array).dropWhile(function(num) { return num < 3; }); - ok(wrapped instanceof _); deepEqual(wrapped.value(), [3, 4]); + deepEqual(wrapped.reverse().value(), [4, 3]); + strictEqual(wrapped.last(), 4); } else { - skipTest(2); + skipTest(3); } }); @@ -3989,7 +4004,7 @@ if (!isNpm) { var args; - _(array).map(function(n) { return n * n; }).dropWhile(function() { + _(array).map(square).dropWhile(function() { args = slice.call(arguments); }).value(); @@ -4794,7 +4809,7 @@ if (!isNpm) { var args; - _(array).map(function(n) { return n * n; }).takeRightWhile(function() { + _(array).map(square).takeRightWhile(function() { args = slice.call(arguments); }).value(); @@ -4856,17 +4871,18 @@ deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2)); }); - test('should return a wrapped value when chaining', 2, function() { + test('should work in a lazy chain sequence', 3, function() { if (!isNpm) { var wrapped = _(array).takeWhile(function(num) { return num < 3; }); - ok(wrapped instanceof _); deepEqual(wrapped.value(), [1, 2]); + deepEqual(wrapped.reverse().value(), [2, 1]); + strictEqual(wrapped.last(), 2); } else { - skipTest(2); + skipTest(3); } }); @@ -4874,7 +4890,7 @@ if (!isNpm) { var args; - _(array).map(function(n) { return n * n; }).takeWhile(function() { + _(array).map(square).takeWhile(function() { args = slice.call(arguments); }).value(); @@ -13636,18 +13652,18 @@ (function() { asyncTest('should throttle a function', 2, function() { if (!(isRhino && isModularize)) { - var count = 0; - var throttled = _.throttle(function() { count++; }, 32); + var callCount = 0, + throttled = _.throttle(function() { callCount++; }, 32); throttled(); throttled(); throttled(); - var lastCount = count; - ok(count > 0); + var lastCount = callCount; + ok(callCount > 0); setTimeout(function() { - ok(count > lastCount); + ok(callCount > lastCount); QUnit.start(); }, 64); } @@ -13716,14 +13732,14 @@ asyncTest('should not trigger a trailing call when invoked once', 2, function() { if (!(isRhino && isModularize)) { - var count = 0, - throttled = _.throttle(function() { count++; }, 32); + var callCount = 0, + throttled = _.throttle(function() { callCount++; }, 32); throttled(); - strictEqual(count, 1); + strictEqual(callCount, 1); setTimeout(function() { - strictEqual(count, 1); + strictEqual(callCount, 1); QUnit.start(); }, 64); } @@ -13736,19 +13752,19 @@ _.times(2, function(index) { asyncTest('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), 1, function() { if (!(isRhino && isModularize)) { - var count = 0, + var callCount = 0, limit = (argv || isPhantom) ? 1000 : 320, options = index ? { 'leading': false } : {}; var throttled = _.throttle(function() { - count++; + callCount++; }, 32, options); var start = +new Date; while ((new Date - start) < limit) { throttled(); } - var actual = count > 1; + var actual = callCount > 1; setTimeout(function() { ok(actual); @@ -13764,10 +13780,10 @@ asyncTest('should apply default options correctly', 3, function() { if (!(isRhino && isModularize)) { - var count = 0; + var callCount = 0; var throttled = _.throttle(function(value) { - count++; + callCount++; return value; }, 32, {}); @@ -13775,7 +13791,7 @@ strictEqual(throttled('b'), 'a'); setTimeout(function() { - strictEqual(count, 2); + strictEqual(callCount, 2); QUnit.start(); }, 256); } @@ -13842,10 +13858,10 @@ asyncTest('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', 1, function() { if (!(isRhino && isModularize)) { - var count = 0; + var callCount = 0; var throttled = _.throttle(function() { - count++; + callCount++; }, 64, { 'trailing': false }); throttled(); @@ -13857,7 +13873,7 @@ }, 96); setTimeout(function() { - ok(count > 1); + ok(callCount > 1); QUnit.start(); }, 192); } @@ -13887,6 +13903,28 @@ ok(pass); }); + asyncTest('_.' + methodName + ' should have a default `wait` of `0`', 1, function() { + if (!(isRhino && isModularize)) { + var callCount = 0; + + var funced = func(function() { + callCount++; + }); + + funced(); + + setTimeout(function() { + funced(); + strictEqual(callCount, isDebounce ? 1 : 2); + QUnit.start(); + }, 32); + } + else { + skipTest(); + QUnit.start(); + } + }); + asyncTest('_.' + methodName + ' should call `func` with the correct `this` binding', 1, function() { if (!(isRhino && isModularize)) { var object = { diff --git a/test/underscore.html b/test/underscore.html index 43bdea2281..98e3032239 100644 --- a/test/underscore.html +++ b/test/underscore.html @@ -51,6 +51,7 @@ '0' ], 'flatten': [ + 'Flattens empty arrays', 'can flatten nested arrays', 'can shallowly flatten nested arrays', 'works on an arguments object', @@ -83,12 +84,9 @@ ] }, 'Chaining': { - 'select/reject/sortBy': [ - 'Died on test #1' - ], - 'select/reject/sortBy in functional style': [ - 'Died on test #1' - ], + 'pop': true, + 'shift': true, + 'splice': true, 'reverse/concat/unshift/pop/map': [ 'can chain together array functions.' ] @@ -97,21 +95,18 @@ 'filter': [ 'OO-filter' ], + 'invoke': [ + 'handles null & undefined' + ], 'map': [ 'OO-style doubled numbers' ], - 'reduce': [ - 'handles a null (without initial value) properly', - 'throws an error for empty arrays with no initial value' - ], - 'reduceRight': [ - 'handles a null (without initial value) properly', - 'throws an error for empty arrays with no initial value' + 'Resistant to collection length and properties changing while iterating': [ + 'Died on test #50' ] }, 'Functions': { 'bind': [ - 'can bind without specifying a context', 'Died on test #2' ], 'bindAll': [ @@ -127,14 +122,23 @@ 'debounce asap': true }, 'Objects': { - 'isEqual': [ - 'Died on test #60', - 'Died on test #63' + '#1929 Typed Array constructors are functions': true, + 'allKeys': true, + 'extendOwn': true, + 'mapObject': true, + 'matcher': true, + 'matcher ': true, + 'extend': [ + 'extend copies all properties from source' ], 'isFinite': [ 'Numeric strings are numbers', 'Number instances can be finite' ], + 'isMatch': [ + 'inherited and own properties are checked on the test object', + 'doesnt falsey match constructor on undefined/null' + ], 'keys': [ 'is not fooled by sparse arrays; see issue #95', '[]' @@ -145,33 +149,21 @@ ] }, 'Utility': { - 'now': [ - 'Produces the correct time in milliseconds' - ], '_.templateSettings.variable': [ '"x"' ], 'times': [ - 'Died on test #1', 'works as a wrapper' - ], - 'uniqueId': [ - 'Died on test #1' ] } }; // only excuse in Sauce Labs (buggy Safari and timers) if (!ui.isSauceLabs) { - QUnit.config.excused.Utility.times.shift(); - delete QUnit.config.excused.Chaining['select/reject/sortBy']; - delete QUnit.config.excused.Chaining['select/reject/sortBy in functional style']; delete QUnit.config.excused.Functions['throttle repeatedly with results']; delete QUnit.config.excused.Functions['more throttle does not trigger leading call when leading is set to false']; delete QUnit.config.excused.Functions['throttle does not trigger trailing call when trailing is set to false']; delete QUnit.config.excused.Functions['debounce asap']; - delete QUnit.config.excused.Objects.isEqual; - delete QUnit.config.excused.Utility.uniqueId; } // load test scripts document.write(ui.urlParams.loader != 'none' diff --git a/vendor/benchmark.js/benchmark.js b/vendor/benchmark.js/benchmark.js index a8fc9be762..4ba5ddf245 100644 --- a/vendor/benchmark.js/benchmark.js +++ b/vendor/benchmark.js/benchmark.js @@ -8,56 +8,56 @@ ;(function() { 'use strict'; - /** Used as a safe reference for `undefined` in pre ES5 environments */ + /** Used as a safe reference for `undefined` in pre ES5 environments. */ var undefined; - /** Used to determine if values are of the language type Object */ + /** Used to determine if values are of the language type Object. */ var objectTypes = { 'function': true, 'object': true }; - /** Used as a reference to the global object */ + /** Used as a reference to the global object. */ var root = (objectTypes[typeof window] && window) || this; - /** Detect free variable `define` */ + /** Detect free variable `define`. */ var freeDefine = typeof define == 'function' && typeof define.amd == 'object' && define.amd && define; - /** Detect free variable `exports` */ + /** Detect free variable `exports`. */ var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - /** Detect free variable `module` */ + /** Detect free variable `module`. */ var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { root = freeGlobal; } - /** Detect free variable `require` */ + /** Detect free variable `require`. */ var freeRequire = typeof require == 'function' && require; - /** Used to assign each benchmark an incrimented id */ + /** Used to assign each benchmark an incrimented id. */ var counter = 0; - /** Detect the popular CommonJS extension `module.exports` */ + /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - /** Used to detect primitive types */ + /** Used to detect primitive types. */ var rePrimitive = /^(?:boolean|number|string|undefined)$/; - /** Used to make every compiled test unique */ + /** Used to make every compiled test unique. */ var uidCounter = 0; - /** Used to assign default `context` object properties */ + /** Used to assign default `context` object properties. */ var contextProps = [ 'Array', 'Date', 'Function', 'Math', 'Object', 'RegExp', 'String', '_', 'clearTimeout', 'chrome', 'chromium', 'document', 'java', 'navigator', 'phantom', 'platform', 'process', 'runtime', 'setTimeout' ]; - /** Used to avoid hz of Infinity */ + /** Used to avoid hz of Infinity. */ var divisors = { '1': 4096, '2': 512, @@ -67,8 +67,8 @@ }; /** - * T-Distribution two-tailed critical values for 95% confidence - * http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm + * T-Distribution two-tailed critical values for 95% confidence. + * For more info see http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm. */ var tTable = { '1': 12.706, '2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447, @@ -80,8 +80,8 @@ }; /** - * Critical Mann-Whitney U-values for 95% confidence - * http://www.saburchill.com/IBbiology/stats/003.html + * Critical Mann-Whitney U-values for 95% confidence. + * For more info see http://www.saburchill.com/IBbiology/stats/003.html. */ var uTable = { '5': [0, 1, 2], @@ -123,7 +123,7 @@ * @returns {Function} Returns a new `Benchmark` function. */ function runInContext(context) { - // exit early if unable to acquire lodash + // Exit early if unable to acquire lodash. var _ = context && context._ || req('lodash') || root._; if (!_) { Benchmark.runInContext = runInContext; @@ -135,7 +135,7 @@ // See http://es5.github.io/#x11.1.5. context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - /** Native constructor references */ + /** Native constructor references. */ var Array = context.Array, Date = context.Date, Function = context.Function, @@ -144,11 +144,11 @@ RegExp = context.RegExp, String = context.String; - /** Used for `Array` and `Object` method references */ + /** Used for `Array` and `Object` method references. */ var arrayRef = [], objectProto = Object.prototype; - /** Native method shortcuts */ + /** Native method shortcuts. */ var abs = Math.abs, clearTimeout = context.clearTimeout, floor = Math.floor, @@ -164,22 +164,22 @@ toString = objectProto.toString, unshift = arrayRef.unshift; - /** Detect DOM document object */ + /** Detect DOM document object. */ var doc = isHostType(context, 'document') && context.document; - /** Used to access Wade Simmons' Node.js `microtime` module */ + /** Used to access Wade Simmons' Node.js `microtime` module. */ var microtimeObject = req('microtime'); - /** Used to access Node.js's high resolution timer */ + /** Used to access Node.js's high resolution timer. */ var processObject = isHostType(context, 'process') && context.process; - /** Used to prevent a `removeChild` memory leak in IE < 9 */ + /** Used to prevent a `removeChild` memory leak in IE < 9. */ var trash = doc && doc.createElement('div'); - /** Used to integrity check compiled tests */ + /** Used to integrity check compiled tests. */ var uid = 'uid' + _.now(); - /** Used to avoid infinite recursion when methods call each other */ + /** Used to avoid infinite recursion when methods call each other. */ var calledBy = {}; /** @@ -233,15 +233,13 @@ * @type boolean */ try { - // Safari 2.x removes commas in object literals - // from `Function#toString` results - // http://webk.it/11609 - // Firefox 3.6 and Opera 9.25 strip grouping - // parentheses from `Function#toString` results - // http://bugzil.la/559438 + // Safari 2.x removes commas in object literals from `Function#toString` results. + // See http://webk.it/11609 for more details. + // Firefox 3.6 and Opera 9.25 strip grouping parentheses from `Function#toString` results. + // See http://bugzil.la/559438 for more details. support.decompilation = Function( ('return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')') - // avoid issues with code added by Istanbul + // Avoid issues with code added by Istanbul. .replace(/__cov__[^;]+;/g, '') )()(0).x === '1'; } catch(e) { @@ -273,7 +271,7 @@ * @memberOf timer * @param {Object} deferred The deferred instance. */ - 'start': null, // lazy defined in `clock()` + 'start': null, // Lazy defined in `clock()`. /** * Stops the deferred timer. @@ -282,7 +280,7 @@ * @memberOf timer * @param {Object} deferred The deferred instance. */ - 'stop': null // lazy defined in `clock()` + 'stop': null // Lazy defined in `clock()`. }; /*------------------------------------------------------------------------*/ @@ -372,28 +370,28 @@ function Benchmark(name, fn, options) { var bench = this; - // allow instance creation without the `new` operator + // Allow instance creation without the `new` operator. if (bench == null || bench.constructor != Benchmark) { return new Benchmark(name, fn, options); } - // juggle arguments + // Juggle arguments. if (_.isPlainObject(name)) { - // 1 argument (options) + // 1 argument (options). options = name; } else if (_.isFunction(name)) { - // 2 arguments (fn, options) + // 2 arguments (fn, options). options = fn; fn = name; } else if (_.isPlainObject(fn)) { - // 2 arguments (name, options) + // 2 arguments (name, options). options = fn; fn = null; bench.name = name; } else { - // 3 arguments (name, fn [, options]) + // 3 arguments (name, fn [, options]). bench.name = name; } setOptions(bench, options); @@ -484,16 +482,16 @@ function Suite(name, options) { var suite = this; - // allow instance creation without the `new` operator + // Allow instance creation without the `new` operator. if (suite == null || suite.constructor != Suite) { return new Suite(name, options); } - // juggle arguments + // Juggle arguments. if (_.isPlainObject(name)) { - // 1 argument (options) + // 1 argument (options). options = name; } else { - // 2 arguments (name [, options]) + // 2 arguments (name [, options]). suite.name = name; } setOptions(suite, options); @@ -509,7 +507,7 @@ * @returns {*} The cloned value. */ var cloneDeep = _.partial(_.cloneDeep, _, function(value) { - // only clone primitives, arrays, and plain objects + // Only clone primitives, arrays, and plain objects. return (_.isObject(value) && !_.isArray(value) && !_.isPlainObject(value)) ? value : undefined; @@ -524,7 +522,7 @@ * @returns {Function} The new function. */ function createFunction() { - // lazy define + // Lazy define. createFunction = function(args, body) { var result, anchor = freeDefine ? freeDefine.amd : Benchmark, @@ -535,8 +533,8 @@ delete anchor[prop]; return result; }; - // fix JaegerMonkey bug - // http://bugzil.la/639720 + // Fix JaegerMonkey bug. + // For more information see http://bugzil.la/639720. createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || _.noop)() == uid ? createFunction : Function; return createFunction.apply(null, arguments); } @@ -600,13 +598,13 @@ if (isStringable(fn)) { result = String(fn); } else if (support.decompilation) { - // escape the `{` for Firefox 1 + // Escape the `{` for Firefox 1. result = _.result(/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn), 1); } - // trim string + // Trim string. result = (result || '').replace(/^\s+|\s+$/g, ''); - // detect strings containing only the "use strict" directive + // Detect strings containing only the "use strict" directive. return /^(?:\/\*+[\w\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result) ? '' : result; @@ -685,7 +683,7 @@ // asynchronously, but that's OK because script injection is only used to avoid // the previously commented JaegerMonkey bug. try { - // remove the inserted script *before* running the code to avoid differences + // Remove the inserted script *before* running the code to avoid differences // in the expected script element count/order of the document. script.appendChild(doc.createTextNode(prefix + code)); anchor[prop] = function() { destroyElement(script); }; @@ -710,7 +708,7 @@ _.forOwn(options, function(value, key) { if (value != null) { - // add event listeners + // Add event listeners. if (/^on[A-Z]/.test(key)) { _.each(key.split(' '), function(key) { object.on(key.slice(2).toLowerCase(), value); @@ -735,7 +733,7 @@ bench = clone._original; if (bench.aborted) { - // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete + // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete. deferred.teardown(); clone.running = false; cycle(deferred); @@ -779,13 +777,13 @@ */ function filter(array, callback, thisArg) { if (callback === 'successful') { - // callback to exclude those that are errored, unrun, or have hz of Infinity + // Callback to exclude those that are errored, unrun, or have hz of Infinity. callback = function(bench) { return bench.cycles && _.isFinite(bench.hz); }; } else if (callback === 'fastest' || callback === 'slowest') { - // get successful, sort by period + margin of error, and filter fastest/slowest + // Get successful, sort by period + margin of error, and filter fastest/slowest. var result = filter(array, 'successful').sort(function(a, b) { a = a.stats; b = b.stats; return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback === 'fastest' ? 1 : -1); @@ -868,14 +866,14 @@ async = isAsync(bench); if (async) { - // use `getNext` as the first listener + // Use `getNext` as the first listener. bench.on('complete', getNext); listeners = bench.events.complete; listeners.splice(0, 0, listeners.pop()); } - // execute method + // Execute method. result[index] = _.isFunction(bench && bench[name]) ? bench[name].apply(bench, args) : undefined; - // if synchronous return `true` until finished + // If synchronous return `true` until finished. return !async && getNext(); } @@ -891,28 +889,28 @@ last.off('complete', getNext); last.emit('complete'); } - // emit "cycle" event + // Emit "cycle" event. eventProps.type = 'cycle'; eventProps.target = last; cycleEvent = Event(eventProps); options.onCycle.call(benches, cycleEvent); - // choose next benchmark if not exiting early + // Choose next benchmark if not exiting early. if (!cycleEvent.aborted && raiseIndex() !== false) { bench = queued ? benches[0] : result[index]; if (isAsync(bench)) { delay(bench, execute); } else if (async) { - // resume execution if previously asynchronous but now synchronous + // Resume execution if previously asynchronous but now synchronous. while (execute()) {} } else { - // continue synchronous execution + // Continue synchronous execution. return true; } } else { - // emit "complete" event + // Emit "complete" event. eventProps.type = 'complete'; options.onComplete.call(benches, Event(eventProps)); } @@ -930,7 +928,7 @@ * Checks if invoking `Benchmark#run` with asynchronous cycles. */ function isAsync(object) { - // avoid using `instanceof` here because of IE memory leak issues with host objects + // Avoid using `instanceof` here because of IE memory leak issues with host objects. var async = args[0] && args[0].async; return Object(object).constructor == Benchmark && name == 'run' && ((async == null ? object.options.async : async) && support.timeout || object.defer); @@ -942,46 +940,46 @@ function raiseIndex() { index++; - // if queued remove the previous bench + // If queued remove the previous bench. if (queued && index > 0) { shift.call(benches); } - // if we reached the last index then return `false` + // If we reached the last index then return `false`. return (queued ? benches.length : index < result.length) ? index : (index = false); } - // juggle arguments + // Juggle arguments. if (_.isString(name)) { - // 2 arguments (array, name) + // 2 arguments (array, name). args = slice.call(arguments, 2); } else { - // 2 arguments (array, options) + // 2 arguments (array, options). options = _.assign(options, name); name = options.name; args = _.isArray(args = 'args' in options ? options.args : []) ? args : [args]; queued = options.queued; } - // start iterating over the array + // Start iterating over the array. if (raiseIndex() !== false) { - // emit "start" event + // Emit "start" event. bench = result[index]; eventProps.type = 'start'; eventProps.target = bench; options.onStart.call(benches, Event(eventProps)); - // end early if the suite was aborted in an "onStart" listener + // End early if the suite was aborted in an "onStart" listener. if (benches.aborted && benches.constructor == Suite && name == 'run') { - // emit "cycle" event + // Emit "cycle" event. eventProps.type = 'cycle'; options.onCycle.call(benches, Event(eventProps)); - // emit "complete" event + // Emit "complete" event. eventProps.type = 'complete'; options.onComplete.call(benches, Event(eventProps)); } - // else start + // Start method execution. else { if (isAsync(bench)) { delay(bench, execute); @@ -1033,7 +1031,7 @@ event = Event('abort'); suite.emit(event); if (!event.cancelled || resetting) { - // avoid infinite recursion + // Avoid infinite recursion. calledBy.abortSuite = true; suite.reset(); delete calledBy.abortSuite; @@ -1107,7 +1105,7 @@ var suite = this, result = new suite.constructor(_.assign({}, suite.options, options)); - // copy own properties + // Copy own properties. _.forOwn(suite, function(value, key) { if (!_.has(result, key)) { result[key] = value && _.isFunction(value.clone) @@ -1147,12 +1145,12 @@ aborting = calledBy.abortSuite; if (suite.running && !aborting) { - // no worries, `resetSuite()` is called within `abortSuite()` + // No worries, `resetSuite()` is called within `abortSuite()`. calledBy.resetSuite = true; suite.abort(); delete calledBy.resetSuite; } - // reset if the state has changed + // Reset if the state has changed. else if ((suite.aborted || suite.running) && (suite.emit(event = Event('reset')), !event.cancelled)) { suite.aborted = suite.running = false; @@ -1353,7 +1351,7 @@ event = Event('abort'); bench.emit(event); if (!event.cancelled || resetting) { - // avoid infinite recursion + // Avoid infinite recursion. calledBy.abort = true; bench.reset(); delete calledBy.abort; @@ -1387,10 +1385,10 @@ var bench = this, result = new bench.constructor(_.assign({}, bench, options)); - // correct the `options` object + // Correct the `options` object. result.options = _.assign({}, cloneDeep(bench.options), cloneDeep(options)); - // copy own custom properties + // Copy own custom properties. _.forOwn(bench, function(value, key) { if (!_.has(result, key)) { result[key] = cloneDeep(value); @@ -1410,7 +1408,7 @@ function compare(other) { var bench = this; - // exit early if comparing the same benchmark + // Exit early if comparing the same benchmark. if (bench == other) { return 0; } @@ -1441,7 +1439,7 @@ function getZ(u) { return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12); } - // reject the null hyphothesis the two samples come from the + // Reject the null hyphothesis the two samples come from the // same population (i.e. have the same median) if... if (size1 + size2 > 30) { // ...the z-stat is greater than 1.96 or less than -1.96 @@ -1449,7 +1447,7 @@ zStat = getZ(u); return abs(zStat) > 1.96 ? (u == u1 ? 1 : -1) : 0; } - // ...the U value is less than or equal the critical U value + // ...the U value is less than or equal the critical U value. critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3]; return u <= critical ? (u == u1 ? 1 : -1) : 0; } @@ -1463,7 +1461,7 @@ function reset() { var bench = this; if (bench.running && !calledBy.abort) { - // no worries, `reset()` is called within `abort()` + // No worries, `reset()` is called within `abort()`. calledBy.reset = true; bench.abort(); delete calledBy.reset; @@ -1474,8 +1472,8 @@ changes = [], queue = []; - // a non-recursive solution to check if properties have changed - // http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4 + // A non-recursive solution to check if properties have changed. + // For more information see http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4. var data = { 'destination': bench, 'source': _.assign({}, cloneDeep(bench.constructor.prototype), cloneDeep(bench.options)) @@ -1487,34 +1485,34 @@ destination = data.destination, currValue = destination[key]; - // skip pseudo private properties like `_timerId` which could be a - // Java object in environments like RingoJS + // Skip pseudo private properties like `_timerId` which could be a + // Java object in environments like RingoJS. if (key.charAt(0) == '_') { return; } if (value && typeof value == 'object') { if (_.isArray(value)) { - // check if an array value has changed to a non-array value + // Check if an array value has changed to a non-array value. if (!_.isArray(currValue)) { changed = currValue = []; } - // or has changed its length + // Check if an array has changed its length. if (currValue.length != value.length) { changed = currValue = currValue.slice(0, value.length); currValue.length = value.length; } } - // check if an object has changed to a non-object value + // Check if an object has changed to a non-object value. else if (!currValue || typeof currValue != 'object') { changed = currValue = {}; } - // register a changed object + // Register a changed object. if (changed) { changes.push({ 'destination': destination, 'key': key, 'value': currValue }); } queue.push({ 'destination': currValue, 'source': value }); } - // register a changed primitive + // Register a changed primitive. else if (value !== currValue && !(value == null || _.isFunction(value))) { changes.push({ 'destination': destination, 'key': key, 'value': value }); } @@ -1522,7 +1520,7 @@ } while ((data = queue[index++])); - // if changed emit the `reset` event and if it isn't cancelled reset the benchmark + // If changed emit the `reset` event and if it isn't cancelled reset the benchmark. if (changes.length && (bench.emit(event = Event('reset')), !event.cancelled)) { _.each(changes, function(data) { data.destination[data.key] = data.value; @@ -1572,7 +1570,7 @@ templateData = {}, timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }]; - // lazy define for hi-res timers + // Lazy define for hi-res timers. clock = function(clone) { var deferred; @@ -1588,16 +1586,16 @@ name = bench.name || (typeof id == 'number' ? '' : id), result = 0; - // init `minTime` if needed + // Init `minTime` if needed. clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime); - // repair nanosecond timer - // (some Chrome builds erase the `ns` variable after millions of executions) + // Repair nanosecond timer. + // Some Chrome builds erase the `ns` variable after millions of executions. if (applet) { try { timer.ns.nanoTime(); } catch(e) { - // use non-element to avoid issues with libs that augment them + // Use non-element to avoid issues with libs that augment them. timer.ns = new applet.Packages.nano; } } @@ -1606,17 +1604,17 @@ // to avoid potential engine optimizations enabled over the life of the test. var funcBody = deferred ? 'var d#=this,${fnArg}=d#,m#=d#.benchmark._original,f#=m#.fn,su#=m#.setup,td#=m#.teardown;' + - // when `deferred.cycles` is `0` then... + // When `deferred.cycles` is `0` then... 'if(!d#.cycles){' + - // set `deferred.fn` + // set `deferred.fn`, 'd#.fn=function(){var ${fnArg}=d#;if(typeof f#=="function"){try{${fn}\n}catch(e#){f#(d#)}}else{${fn}\n}};' + - // set `deferred.teardown` + // set `deferred.teardown`, 'd#.teardown=function(){d#.cycles=0;if(typeof td#=="function"){try{${teardown}\n}catch(e#){td#()}}else{${teardown}\n}};' + - // execute the benchmark's `setup` + // execute the benchmark's `setup`, 'if(typeof su#=="function"){try{${setup}\n}catch(e#){su#()}}else{${setup}\n};' + - // start timer + // start timer, 't#.start(d#);' + - // execute `deferred.fn` and return a dummy object + // and then execute `deferred.fn` and return a dummy object. '}d#.fn();return{uid:"${uid}"}' : 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count,n#=t#.ns;${setup}\n${begin};' + @@ -1627,13 +1625,13 @@ try { if (isEmpty) { - // Firefox may remove dead code from `Function#toString` results - // http://bugzil.la/536085 + // Firefox may remove dead code from `Function#toString` results. + // For more information see http://bugzil.la/536085. throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.'); } else if (!deferred) { - // pretest to determine if compiled code exits early, usually by a - // rogue `return` statement, by checking for a return object with the uid + // Pretest to determine if compiled code exits early, usually by a + // rogue `return` statement, by checking for a return object with the uid. bench.count = 1; compiled = decompilable && (compiled.call(bench, context, timer) || {}).uid == templateData.uid && compiled; bench.count = count; @@ -1643,7 +1641,7 @@ clone.error = e || new Error(String(e)); bench.count = count; } - // fallback when a test exits early or errors during pretest + // Fallback when a test exits early or errors during pretest. if (!compiled && !deferred && !isEmpty) { funcBody = ( stringable || (decompilable && !clone.error) @@ -1656,7 +1654,7 @@ compiled = createCompiled(bench, decompilable, deferred, funcBody); try { - // pretest one more time to check for errors + // Pretest one more time to check for errors. bench.count = 1; compiled.call(bench, context, timer); bench.count = count; @@ -1669,7 +1667,7 @@ } } } - // if no errors run the full test loop + // If no errors run the full test loop. if (!clone.error) { compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody); result = compiled.call(deferred || bench, context, timer).elapsed; @@ -1695,7 +1693,7 @@ 'teardown': decompilable ? getSource(bench.teardown) : interpolate('m#.teardown()') }); - // use API of chosen timer + // Use API of chosen timer. if (timer.unit == 'ns') { if (timer.ns.nanoTime) { _.assign(templateData, { @@ -1734,7 +1732,7 @@ 'end': interpolate('r#=(new n#().getTime()-s#)/1e3') }); } - // define `timer` methods + // Define `timer` methods. timer.start = createFunction( interpolate('o#'), interpolate('var n#=this.ns,${begin};o#.elapsed=0;o#.timeStamp=s#') @@ -1745,7 +1743,7 @@ interpolate('var n#=this.ns,s#=o#.timeStamp,${end};o#.elapsed=r#') ); - // create compiled test + // Create compiled test. return createFunction( interpolate('window,t#'), 'var global = window, clearTimeout = global.clearTimeout, setTimeout = global.setTimeout;\n' + @@ -1764,7 +1762,7 @@ ns = timer.ns, sample = []; - // get average smallest measurable time + // Get average smallest measurable time. while (count--) { if (unit == 'us') { divisor = 1e6; @@ -1795,8 +1793,8 @@ begin = new ns().getTime(); while (!(measured = new ns().getTime() - begin)) {} } - // check for broken timers (`nanoTime` may have issues) - // http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/ + // Check for broken timers (`nanoTime` may have issues). + // For more information see http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/. if (measured > 0) { sample.push(measured); } else { @@ -1804,7 +1802,7 @@ break; } } - // convert to seconds + // Convert to seconds. return getMean(sample) / divisor; } @@ -1812,25 +1810,25 @@ * Interpolates a given template string. */ function interpolate(string) { - // replaces all occurrences of `#` with a unique number and template tokens with content + // Replaces all occurrences of `#` with a unique number and template tokens with content. return _.template(string.replace(/\#/g, /\d+/.exec(templateData.uid)))(templateData); } /*----------------------------------------------------------------------*/ - // detect nanosecond support from a Java applet + // Detect nanosecond support from a Java applet. _.each(doc && doc.applets || [], function(element) { return !(timer.ns = applet = 'nanoTime' in element && element); }); - // check type in case Safari returns an object instead of a number + // Check type in case Safari returns an object instead of a number. try { if (typeof timer.ns.nanoTime() == 'number') { timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); } } catch(e) {} - // detect Chrome's microsecond timer: + // Detect Chrome's microsecond timer: // enable benchmarking via the --enable-benchmarking command // line switch in at least Chrome 7 to use chrome.Interval try { @@ -1839,27 +1837,27 @@ } } catch(e) {} - // detect Node.js's nanosecond resolution timer available in Node.js >= 0.8 + // Detect Node.js's nanosecond resolution timer available in Node.js >= 0.8. if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') { timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); } - // detect Wade Simmons' Node.js `microtime` module + // Detect Wade Simmons' Node.js `microtime` module. if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') { timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); } - // pick timer with highest resolution + // Pick timer with highest resolution. timer = _.min(timers, 'res'); - // remove unused applet + // Remove unused applet. if (timer.unit != 'ns' && applet) { applet = destroyElement(applet); } - // error if there are no working timers + // Error if there are no working timers. if (timer.res == Infinity) { throw new Error('Benchmark.js was unable to find a working timer.'); } - // resolve time span required to achieve a percent uncertainty of at most 1% - // http://spiff.rit.edu/classes/phys273/uncert/uncert.html + // Resolve time span required to achieve a percent uncertainty of at most 1%. + // For more information see http://spiff.rit.edu/classes/phys273/uncert/uncert.html. options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05)); return clock.apply(null, arguments); } @@ -1907,7 +1905,7 @@ if (bench.running) { if (type == 'start') { - // Note: `clone.minTime` prop is inited in `clock()` + // Note: `clone.minTime` prop is inited in `clock()`. clone.count = bench.initCount; } else { @@ -1923,7 +1921,7 @@ } } } else if (bench.aborted) { - // clear abort listeners to avoid triggering bench's abort/cycle again + // Clear abort listeners to avoid triggering bench's abort/cycle again. clone.events.abort.length = 0; clone.abort(); } @@ -1949,27 +1947,27 @@ times = bench.times, varOf = function(sum, x) { return sum + pow(x - mean, 2); }; - // exit early for aborted or unclockable tests + // Exit early for aborted or unclockable tests. if (done || clone.hz == Infinity) { maxedOut = !(size = sample.length = queue.length = 0); } if (!done) { - // sample mean (estimate of the population mean) + // Compute the sample mean (estimate of the population mean). mean = getMean(sample); - // sample variance (estimate of the population variance) + // Compute the sample variance (estimate of the population variance). variance = _.reduce(sample, varOf, 0) / (size - 1) || 0; - // sample standard deviation (estimate of the population standard deviation) + // Compute the sample standard deviation (estimate of the population standard deviation). sd = sqrt(variance); - // standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean) + // Compute the standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean). sem = sd / sqrt(size); - // degrees of freedom + // Compute the degrees of freedom. df = size - 1; - // critical value + // Compute the critical value. critical = tTable[Math.round(df) || 1] || tTable.infinity; - // margin of error + // Compute the margin of error. moe = sem * critical; - // relative margin of error + // Compute the relative margin of error. rme = (moe / mean) * 100 || 0; _.assign(bench.stats, { @@ -1984,10 +1982,10 @@ // Abort the cycle loop when the minimum sample size has been collected // and the elapsed time exceeds the maximum time allowed per benchmark. // We don't count cycle delays toward the max time because delays may be - // increased by browsers that clamp timeouts for inactive tabs. - // https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs + // increased by browsers that clamp timeouts for inactive tabs. For more + // information see https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs. if (maxedOut) { - // reset the `initCount` in case the benchmark is rerun + // Reset the `initCount` in case the benchmark is rerun. bench.initCount = initCount; bench.running = false; done = true; @@ -1999,15 +1997,15 @@ times.period = mean; } } - // if time permits, increase sample size to reduce the margin of error + // If time permits, increase sample size to reduce the margin of error. if (queue.length < 2 && !maxedOut) { enqueue(); } - // abort the `invoke` cycle when done + // Abort the `invoke` cycle when done. event.aborted = done; } - // init queue and begin + // Init queue and begin. enqueue(); invoke(queue, { 'name': 'run', @@ -2047,9 +2045,9 @@ count = clone.count, times = clone.times; - // continue, if not aborted between cycles + // Continue, if not aborted between cycles. if (clone.running) { - // `minTime` is set to `Benchmark.options.minTime` in `clock()` + // `minTime` is set to `Benchmark.options.minTime` in `clock()`. cycles = ++clone.cycles; clocked = deferred ? deferred.elapsed : clock(clone); minTime = clone.minTime; @@ -2067,41 +2065,41 @@ } } - // continue, if not errored + // Continue, if not errored. if (clone.running) { - // time taken to complete last test cycle + // Compute the time taken to complete last test cycle. bench.times.cycle = times.cycle = clocked; - // seconds per operation + // Compute the seconds per operation. period = bench.times.period = times.period = clocked / count; - // ops per second + // Compute the ops per second. bench.hz = clone.hz = 1 / period; - // avoid working our way up to this next time + // Avoid working our way up to this next time. bench.initCount = clone.initCount = count; - // do we need to do another cycle? + // Do we need to do another cycle? clone.running = clocked < minTime; if (clone.running) { - // tests may clock at `0` when `initCount` is a small number, - // to avoid that we set its count to something a bit higher + // Tests may clock at `0` when `initCount` is a small number, + // to avoid that we set its count to something a bit higher. if (!clocked && (divisor = divisors[clone.cycles]) != null) { count = floor(4e6 / divisor); } - // calculate how many more iterations it will take to achive the `minTime` + // Calculate how many more iterations it will take to achive the `minTime`. if (count <= clone.count) { count += Math.ceil((minTime - clocked) / period); } clone.running = count != Infinity; } } - // should we exit early? + // Should we exit early? event = Event('cycle'); clone.emit(event); if (event.aborted) { clone.abort(); } - // figure out what to do next + // Figure out what to do next. if (clone.running) { - // start a new cycle + // Start a new cycle. clone.count = count; if (deferred) { clone.compiled.call(deferred, context, timer); @@ -2112,12 +2110,12 @@ } } else { - // fix TraceMonkey bug associated with clock fallbacks - // http://bugzil.la/509069 + // Fix TraceMonkey bug associated with clock fallbacks. + // For more information see http://bugzil.la/509069. if (support.browser) { runScript(uid + '=1;delete ' + uid); } - // done + // We're done. clone.emit('complete'); } } @@ -2142,7 +2140,7 @@ var bench = this, event = Event('start'); - // set `running` to `false` so `reset()` won't call `abort()` + // Set `running` to `false` so `reset()` won't call `abort()`. bench.running = false; bench.reset(); bench.running = true; @@ -2154,7 +2152,7 @@ if (!event.cancelled) { options = { 'async': ((options = options && options.async) == null ? bench.async : options) && support.timeout }; - // for clones created within `compute()` + // For clones created within `compute()`. if (bench._original) { if (bench.defer) { Deferred(bench); @@ -2162,7 +2160,7 @@ cycle(bench, options); } } - // for original benchmarks + // For original benchmarks. else { compute(bench, options); } @@ -2354,7 +2352,7 @@ 'support': support }); - // Add lodash methods to Benchmark + // Add lodash methods to Benchmark. _.each(['each', 'forEach', 'forOwn', 'has', 'indexOf', 'map', 'pluck', 'reduce'], function(methodName) { Benchmark[methodName] = _[methodName]; }); @@ -2793,7 +2791,7 @@ /*------------------------------------------------------------------------*/ - // expose Deferred, Event, and Suite + // Expose Deferred, Event, and Suite. _.assign(Benchmark, { 'Deferred': Deferred, 'Event': Event, @@ -2802,7 +2800,7 @@ /*------------------------------------------------------------------------*/ - // add lodash methods as Suite methods + // Add lodash methods as Suite methods. _.each(['each', 'forEach', 'indexOf', 'map', 'pluck', 'reduce'], function(methodName) { var func = _[methodName]; Suite.prototype[methodName] = function() { @@ -2812,8 +2810,8 @@ }; }); - // avoid array-like object bugs with `Array#shift` and `Array#splice` - // in Firefox < 10 and IE < 9 + // Avoid array-like object bugs with `Array#shift` and `Array#splice` + // in Firefox < 10 and IE < 9. if (!_.support.spliceObjects) { _.each(['pop', 'shift', 'splice'], function(methodName) { var func = arrayRef[methodName]; @@ -2829,8 +2827,8 @@ }; }); } - // avoid buggy `Array#unshift` in IE < 8 which doesn't return the new - // length of the array + // Avoid buggy `Array#unshift` in IE < 8 which doesn't return the new + // length of the array. if (!support.unshiftResult) { Suite.prototype.unshift = function() { var value = this; @@ -2843,10 +2841,10 @@ /*--------------------------------------------------------------------------*/ - // export Benchmark - // some AMD build optimizers, like r.js, check for condition patterns like the following: + // Export Benchmark. + // Some AMD build optimizers, like r.js, check for condition patterns like the following: if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // define as an anonymous module so, through path mapping, it can be aliased + // Define as an anonymous module so, through path mapping, it can be aliased. define(['lodash', 'platform'], function(_, platform) { return runInContext({ '_': _, @@ -2857,19 +2855,19 @@ else { var Benchmark = runInContext(); - // check for `exports` after `define` in case a build optimizer adds an `exports` object + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. if (freeExports && freeModule) { - // in Node.js or RingoJS + // Export for Node.js or RingoJS. if (moduleExports) { (freeModule.exports = Benchmark).Benchmark = Benchmark; } - // in Narwhal or Rhino -require + // Export for Narwhal or Rhino -require. else { freeExports.Benchmark = Benchmark; } } else { - // in a browser or Rhino + // Export for a browser or Rhino. root.Benchmark = Benchmark; } } diff --git a/vendor/underscore/LICENSE b/vendor/underscore/LICENSE index 0d6b8739d9..ad0e71bc4b 100644 --- a/vendor/underscore/LICENSE +++ b/vendor/underscore/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative +Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors Permission is hereby granted, free of charge, to any person diff --git a/vendor/underscore/test/arrays.js b/vendor/underscore/test/arrays.js index 975015f807..de8ac607dc 100644 --- a/vendor/underscore/test/arrays.js +++ b/vendor/underscore/test/arrays.js @@ -1,6 +1,7 @@ (function() { + var _ = typeof require == 'function' ? require('..') : window._; - module('Arrays'); + QUnit.module('Arrays'); test('first', function() { equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array'); @@ -79,6 +80,12 @@ }); test('flatten', function() { + deepEqual(_.flatten(null), [], 'Flattens supports null'); + deepEqual(_.flatten(void 0), [], 'Flattens supports undefined'); + + deepEqual(_.flatten([[], [[]], []]), [], 'Flattens empty arrays'); + deepEqual(_.flatten([[], [[]], []], true), [[]], 'Flattens empty arrays'); + var list = [1, [2], [3, [[[4]]]]]; deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays'); deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays'); @@ -86,6 +93,11 @@ deepEqual(result, [1, 2, 3, 4], 'works on an arguments object'); list = [[1], [2], [3], [[4]]]; deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays'); + + equal(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23); + equal(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23); + equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'Flatten can handle massive collections'); + equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'Flatten can handle massive collections'); }); test('without', function() { @@ -99,6 +111,32 @@ equal(_.without(list, list[0]).length, 1, 'ditto.'); }); + test('sortedIndex', function() { + var numbers = [10, 20, 30, 40, 50], num = 35; + var indexForNum = _.sortedIndex(numbers, num); + equal(indexForNum, 3, '35 should be inserted at index 3'); + + var indexFor30 = _.sortedIndex(numbers, 30); + equal(indexFor30, 2, '30 should be inserted at index 2'); + + var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; + var iterator = function(obj){ return obj.x; }; + strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); + strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); + + var context = {1: 2, 2: 3, 3: 4}; + iterator = function(obj){ return this[obj]; }; + strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); + + var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647]; + var array = Array(Math.pow(2, 32) - 1); + var length = values.length; + while (length--) { + array[values[length]] = values[length]; + } + equal(_.sortedIndex(array, 2147483648), 2147483648, 'should work with large indexes'); + }); + test('uniq', function() { var list = [1, 2, 1, 3, 1, 4]; deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array'); @@ -116,6 +154,20 @@ list = [1, 2, 2, 3, 4, 4]; deepEqual(_.uniq(list, true, iterator), [1, 2, 3, 4], 'iterator works with sorted array'); + var kittens = [ + {kitten: 'Celery', cuteness: 8}, + {kitten: 'Juniper', cuteness: 10}, + {kitten: 'Spottis', cuteness: 10} + ]; + + var expected = [ + {kitten: 'Celery', cuteness: 8}, + {kitten: 'Juniper', cuteness: 10} + ]; + + deepEqual(_.uniq(kittens, true, 'cuteness'), expected, 'string iterator works with sorted array'); + + var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4)); deepEqual(result, [1, 2, 3, 4], 'works on an arguments object'); @@ -209,6 +261,19 @@ deepEqual(_.zip(), [], '_.zip() returns []'); }); + test('unzip', function() { + deepEqual(_.unzip(null), [], 'handles null'); + + deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]); + + // complements zip + var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]); + + zipped = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']); + deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array'); + }); + test('object', function() { var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); var shouldBe = {moe: 30, larry: 40, curly: 50}; @@ -229,7 +294,14 @@ equal(_.indexOf(numbers, 2), 1, 'can compute indexOf'); var result = (function(){ return _.indexOf(arguments, 2); }(1, 2, 3)); equal(result, 1, 'works on an arguments object'); - equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + _.each([null, void 0, [], false], function(val) { + var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val); + equal(_.indexOf(val, 2), -1, msg); + equal(_.indexOf(val, 2, -1), -1, msg); + equal(_.indexOf(val, 2, -20), -1, msg); + equal(_.indexOf(val, 2, 15), -1, msg); + }); var num = 35; numbers = [10, 20, 30, 40, 50]; @@ -263,6 +335,25 @@ strictEqual(_.indexOf(array, 1, fromIndex), 0); }); strictEqual(_.indexOf([1, 2, 3], 1, true), 0); + + index = _.indexOf([], undefined, true); + equal(index, -1, 'empty array with truthy `isSorted` returns -1'); + }); + + test('indexOf with NaN', function() { + strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN'); + strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN'); + + (function() { + strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN'); + }(1, 2, NaN, NaN)); + }); + + test('indexOf with +- 0', function() { + _.each([-0, +0], function(val) { + strictEqual(_.indexOf([1, 2, val, val], val), 2); + strictEqual(_.indexOf([1, 2, val, val], -val), 2); + }); }); test('lastIndexOf', function() { @@ -276,7 +367,14 @@ equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); var result = (function(){ return _.lastIndexOf(arguments, 1); }(1, 0, 1, 0, 0, 1, 0, 0, 0)); equal(result, 5, 'works on an arguments object'); - equal(_.lastIndexOf(null, 2), -1, 'handles nulls properly'); + + _.each([null, void 0, [], false], function(val) { + var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val); + equal(_.lastIndexOf(val, 2), -1, msg); + equal(_.lastIndexOf(val, 2, -1), -1, msg); + equal(_.lastIndexOf(val, 2, -20), -1, msg); + equal(_.lastIndexOf(val, 2, 15), -1, msg); + }); numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; var index = _.lastIndexOf(numbers, 2, 2); @@ -316,6 +414,109 @@ }), [0, -1, -1]); }); + test('lastIndexOf with NaN', function() { + strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN'); + strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN'); + + (function() { + strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN'); + }(1, 2, NaN, NaN)); + }); + + test('lastIndexOf with +- 0', function() { + _.each([-0, +0], function(val) { + strictEqual(_.lastIndexOf([1, 2, val, val], val), 3); + strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3); + strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1); + }); + }); + + test('findIndex', function() { + var objects = [ + {'a': 0, 'b': 0}, + {'a': 1, 'b': 1}, + {'a': 2, 'b': 2}, + {'a': 0, 'b': 0} + ]; + + equal(_.findIndex(objects, function(obj) { + return obj.a === 0; + }), 0); + + equal(_.findIndex(objects, function(obj) { + return obj.b * obj.a === 4; + }), 2); + + equal(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator'); + + equal(_.findIndex(objects, function(obj) { + return obj.b * obj.a === 5; + }), -1); + + equal(_.findIndex(null, _.noop), -1); + strictEqual(_.findIndex(objects, function(a) { + return a.foo === null; + }), -1); + _.findIndex([{a: 1}], function(a, key, obj) { + equal(key, 0); + deepEqual(obj, [{a: 1}]); + strictEqual(this, objects, 'called with context'); + }, objects); + + var sparse = []; + sparse[20] = {'a': 2, 'b': 2}; + equal(_.findIndex(sparse, function(obj) { + return obj && obj.b * obj.a === 4; + }), 20, 'Works with sparse arrays'); + + var array = [1, 2, 3, 4]; + array.match = 55; + strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys'); + }); + + test('findLastIndex', function() { + var objects = [ + {'a': 0, 'b': 0}, + {'a': 1, 'b': 1}, + {'a': 2, 'b': 2}, + {'a': 0, 'b': 0} + ]; + + equal(_.findLastIndex(objects, function(obj) { + return obj.a === 0; + }), 3); + + equal(_.findLastIndex(objects, function(obj) { + return obj.b * obj.a === 4; + }), 2); + + equal(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator'); + + equal(_.findLastIndex(objects, function(obj) { + return obj.b * obj.a === 5; + }), -1); + + equal(_.findLastIndex(null, _.noop), -1); + strictEqual(_.findLastIndex(objects, function(a) { + return a.foo === null; + }), -1); + _.findLastIndex([{a: 1}], function(a, key, obj) { + equal(key, 0); + deepEqual(obj, [{a: 1}]); + strictEqual(this, objects, 'called with context'); + }, objects); + + var sparse = []; + sparse[20] = {'a': 2, 'b': 2}; + equal(_.findLastIndex(sparse, function(obj) { + return obj && obj.b * obj.a === 4; + }), 20, 'Works with sparse arrays'); + + var array = [1, 2, 3, 4]; + array.match = 55; + strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys'); + }); + test('range', function() { deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array'); deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); diff --git a/vendor/underscore/test/chaining.js b/vendor/underscore/test/chaining.js index 770b88406a..34fd73c360 100644 --- a/vendor/underscore/test/chaining.js +++ b/vendor/underscore/test/chaining.js @@ -1,6 +1,7 @@ (function() { + var _ = typeof require == 'function' ? require('..') : window._; - module('Chaining'); + QUnit.module('Chaining'); test('map/flatten/reduce', function() { var lyrics = [ @@ -57,10 +58,41 @@ deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.'); }); + test('splice', function() { + var instance = _([1, 2, 3, 4, 5]).chain(); + deepEqual(instance.splice(1, 3).value(), [1, 5]); + deepEqual(instance.splice(1, 0).value(), [1, 5]); + deepEqual(instance.splice(1, 1).value(), [1]); + deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array'); + }); + + test('shift', function() { + var instance = _([1, 2, 3]).chain(); + deepEqual(instance.shift().value(), [2, 3]); + deepEqual(instance.shift().value(), [3]); + deepEqual(instance.shift().value(), [], '#397 Can create empty array'); + }); + + test('pop', function() { + var instance = _([1, 2, 3]).chain(); + deepEqual(instance.pop().value(), [1, 2]); + deepEqual(instance.pop().value(), [1]); + deepEqual(instance.pop().value(), [], '#397 Can create empty array'); + }); + test('chaining works in small stages', function() { var o = _([1, 2, 3, 4]).chain(); deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]); deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]); }); + test('#1562: Engine proxies for chained functions', function() { + var wrapped = _(512); + strictEqual(wrapped.toJSON(), 512); + strictEqual(wrapped.valueOf(), 512); + strictEqual(+wrapped, 512); + strictEqual(wrapped.toString(), '512'); + strictEqual('' + wrapped, '512'); + }); + }()); diff --git a/vendor/underscore/test/collections.js b/vendor/underscore/test/collections.js index c74e5ea630..af43064824 100644 --- a/vendor/underscore/test/collections.js +++ b/vendor/underscore/test/collections.js @@ -1,6 +1,7 @@ (function() { + var _ = typeof require == 'function' ? require('..') : window._; - module('Collections'); + QUnit.module('Collections'); test('each', function() { _.each([1, 2, 3], function(num, i) { @@ -35,12 +36,6 @@ var a = [1, 2, 3]; strictEqual(_.each(a, function(){}), a); strictEqual(_.each(null, function(){}), null); - - var b = [1, 2, 3]; - b.length = 100; - answers = 0; - _.each(b, function(){ ++answers; }); - equal(answers, 100, 'enumerates [0, length)'); }); test('forEach', function() { @@ -55,6 +50,94 @@ }); }); + test('Iterating objects with sketchy length properties', function() { + var functions = [ + 'each', 'map', 'filter', 'find', + 'some', 'every', 'max', 'min', + 'groupBy', 'countBy', 'partition', 'indexBy' + ]; + var reducers = ['reduce', 'reduceRight']; + + var tricks = [ + {length: '5'}, + { + length: { + valueOf: _.constant(5) + } + }, + {length: Math.pow(2, 53) + 1}, + {length: Math.pow(2, 53)}, + {length: null}, + {length: -2}, + {length: new Number(15)} + ]; + + expect(tricks.length * (functions.length + reducers.length + 4)); + + _.each(tricks, function(trick) { + var length = trick.length; + strictEqual(_.size(trick), 1, 'size on obj with length: ' + length); + deepEqual(_.toArray(trick), [length], 'toArray on obj with length: ' + length); + deepEqual(_.shuffle(trick), [length], 'shuffle on obj with length: ' + length); + deepEqual(_.sample(trick), length, 'sample on obj with length: ' + length); + + + _.each(functions, function(method) { + _[method](trick, function(val, key) { + strictEqual(key, 'length', method + ': ran with length = ' + val); + }); + }); + + _.each(reducers, function(method) { + strictEqual(_[method](trick), trick.length, method); + }); + }); + }); + + test('Resistant to collection length and properties changing while iterating', function() { + + var collection = [ + 'each', 'map', 'filter', 'find', + 'some', 'every', 'max', 'min', 'reject', + 'groupBy', 'countBy', 'partition', 'indexBy', + 'reduce', 'reduceRight' + ]; + var array = [ + 'findIndex', 'findLastIndex' + ]; + var object = [ + 'mapObject', 'findKey', 'pick', 'omit' + ]; + + _.each(collection.concat(array), function(method) { + var sparseArray = [1, 2, 3]; + sparseArray.length = 100; + var answers = 0; + _[method](sparseArray, function(){ + ++answers; + return method === 'every' ? true : null; + }, {}); + equal(answers, 100, method + ' enumerates [0, length)'); + + var growingCollection = [1, 2, 3], count = 0; + _[method](growingCollection, function() { + if (count < 10) growingCollection.push(count++); + return method === 'every' ? true : null; + }, {}); + equal(count, 3, method + ' is resistant to length changes'); + }); + + _.each(collection.concat(object), function(method) { + var changingObject = {0: 0, 1: 1}, count = 0; + _[method](changingObject, function(val) { + if (count < 10) changingObject[++count] = val + 1; + return method === 'every' ? true : null; + }, {}); + + equal(count, 2, method + ' is resistant to property changes'); + }); + }); + test('map', function() { var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); deepEqual(doubled, [2, 4, 6], 'doubled numbers'); @@ -65,12 +148,7 @@ doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); deepEqual(doubled, [2, 4, 6], 'OO-style doubled numbers'); - if (document.querySelectorAll) { - var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); - } - - ids = _.map({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){ + var ids = _.map({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){ return n.id; }); deepEqual(ids, ['1', '2'], 'Can use collection methods on Array-likes.'); @@ -113,9 +191,7 @@ ok(_.reduce(null, _.noop, 138) === 138, 'handles a null (with initial value) properly'); equal(_.reduce([], _.noop, undefined), undefined, 'undefined can be passed as a special case'); equal(_.reduce([_], _.noop), _, 'collection of length one with no initial value returns the first item'); - - raises(function() { _.reduce([], _.noop); }, TypeError, 'throws an error for empty arrays with no initial value'); - raises(function() {_.reduce(null, _.noop);}, TypeError, 'handles a null (without initial value) properly'); + equal(_.reduce([], _.noop), undefined, 'returns undefined when collection is empty and no initial value'); }); test('foldl', function() { @@ -136,9 +212,7 @@ equal(_.reduceRight([_], _.noop), _, 'collection of length one with no initial value returns the first item'); equal(_.reduceRight([], _.noop, undefined), undefined, 'undefined can be passed as a special case'); - - raises(function() { _.reduceRight([], _.noop); }, TypeError, 'throws an error for empty arrays with no initial value'); - raises(function() {_.reduceRight(null, _.noop);}, TypeError, 'handles a null (without initial value) properly'); + equal(_.reduceRight([], _.noop), undefined, 'returns undefined when collection is empty and no initial value'); // Assert that the correct arguments are being passed. @@ -183,6 +257,9 @@ strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); + array.dontmatch = 55; + strictEqual(_.find(array, function(x) { return x === 55; }), void 0, 'iterates array-likes correctly'); + // Matching an object like _.findWhere. var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}]; deepEqual(_.find(list, {a: 1}), {a: 1, b: 2}, 'can be used as findWhere'); @@ -192,6 +269,25 @@ var result = _.find([1, 2, 3], function(num){ return num * 2 === 4; }); equal(result, 2, 'found the first "2" and broke the loop'); + + var obj = { + a: {x: 1, z: 3}, + b: {x: 2, z: 2}, + c: {x: 3, z: 4}, + d: {x: 4, z: 1} + }; + + deepEqual(_.find(obj, {x: 2}), {x: 2, z: 2}, 'works on objects'); + deepEqual(_.find(obj, {x: 2, z: 1}), void 0); + deepEqual(_.find(obj, function(x) { + return x.x === 4; + }), {x: 4, z: 1}); + + _.findIndex([{a: 1}], function(a, key, obj) { + equal(key, 0); + deepEqual(obj, [{a: 1}]); + strictEqual(this, _, 'called with context'); + }, _); }); test('detect', function() { @@ -303,22 +399,66 @@ strictEqual(_.any, _.some, 'alias for any'); }); - test('contains', function() { - ok(_.contains([1, 2, 3], 2), 'two is in the array'); - ok(!_.contains([1, 3, 9], 2), 'two is not in the array'); - ok(_.contains({moe: 1, larry: 3, curly: 9}, 3) === true, '_.contains on objects checks their values'); - ok(_([1, 2, 3]).contains(2), 'OO-style contains'); + test('includes', function() { + _.each([null, void 0, 0, 1, NaN, {}, []], function(val) { + strictEqual(_.includes(val, 'hasOwnProperty'), false); + }); + strictEqual(_.includes([1, 2, 3], 2), true, 'two is in the array'); + ok(!_.includes([1, 3, 9], 2), 'two is not in the array'); + + strictEqual(_.includes([5, 4, 3, 2, 1], 5, true), true, 'doesn\'t delegate to binary search'); + + ok(_.includes({moe: 1, larry: 3, curly: 9}, 3) === true, '_.includes on objects checks their values'); + ok(_([1, 2, 3]).includes(2), 'OO-style includes'); }); test('include', function() { - strictEqual(_.contains, _.include, 'alias for contains'); + strictEqual(_.includes, _.include, 'alias for includes'); + }); + + test('contains', function() { + strictEqual(_.includes, _.contains, 'alias for includes'); + + var numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + strictEqual(_.includes(numbers, 1, 1), true); + strictEqual(_.includes(numbers, 1, -1), false); + strictEqual(_.includes(numbers, 1, -2), false); + strictEqual(_.includes(numbers, 1, -3), true); + strictEqual(_.includes(numbers, 1, 6), true); + strictEqual(_.includes(numbers, 1, 7), false); + }); + + test('includes with NaN', function() { + strictEqual(_.includes([1, 2, NaN, NaN], NaN), true, 'Expected [1, 2, NaN] to contain NaN'); + strictEqual(_.includes([1, 2, Infinity], NaN), false, 'Expected [1, 2, NaN] to contain NaN'); + }); + + test('includes with +- 0', function() { + _.each([-0, +0], function(val) { + strictEqual(_.includes([1, 2, val, val], val), true); + strictEqual(_.includes([1, 2, val, val], -val), true); + strictEqual(_.includes([-1, 1, 2], -val), false); + }); }); - test('invoke', function() { + + test('invoke', 5, function() { var list = [[5, 1, 7], [3, 2, 1]]; var result = _.invoke(list, 'sort'); deepEqual(result[0], [1, 5, 7], 'first array sorted'); deepEqual(result[1], [1, 2, 3], 'second array sorted'); + + _.invoke([{ + method: function() { + deepEqual(_.toArray(arguments), [1, 2, 3], 'called with arguments'); + } + }], 'method', 1, 2, 3); + + deepEqual(_.invoke([{a: null}, {}, {a: _.constant(1)}], 'a'), [null, void 0, 1], 'handles null & undefined'); + + throws(function() { + _.invoke([{a: 1}], 'a'); + }, TypeError, 'throws for non-functions'); }); test('invoke w/ function reference', function() { @@ -326,6 +466,10 @@ var result = _.invoke(list, Array.prototype.sort); deepEqual(result[0], [1, 5, 7], 'first array sorted'); deepEqual(result[1], [1, 2, 3], 'second array sorted'); + + deepEqual(_.invoke([1, 2, 3], function(a) { + return a + this; + }, 5), [6, 7, 8], 'receives params from invoke'); }); // Relevant when using ClojureScript @@ -346,6 +490,7 @@ test('pluck', function() { var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}]; deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'pulls names out of objects'); + deepEqual(_.pluck(people, 'address'), [undefined, undefined], 'missing properties are returned as undefined'); //compat: most flexible handling of edge cases deepEqual(_.pluck([{'[object Object]': 1}], {}), [1]); }); @@ -582,24 +727,6 @@ equal(grouped['3'], 1); }); - test('sortedIndex', function() { - var numbers = [10, 20, 30, 40, 50], num = 35; - var indexForNum = _.sortedIndex(numbers, num); - equal(indexForNum, 3, '35 should be inserted at index 3'); - - var indexFor30 = _.sortedIndex(numbers, 30); - equal(indexFor30, 2, '30 should be inserted at index 2'); - - var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; - var iterator = function(obj){ return obj.x; }; - strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); - strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); - - var context = {1: 2, 2: 3, 3: 4}; - iterator = function(obj){ return this[obj]; }; - strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); - }); - test('shuffle', function() { var numbers = _.range(10); var shuffled = _.shuffle(numbers); @@ -637,12 +764,14 @@ var numbers = _.toArray({one : 1, two : 2, three : 3}); deepEqual(numbers, [1, 2, 3], 'object flattened into array'); - // test in IE < 9 - try { - var actual = _.toArray(document.childNodes); - } catch(ex) { } - - ok(_.isArray(actual), 'should not throw converting a node list'); + if (typeof document != 'undefined') { + // test in IE < 9 + var actual; + try { + actual = _.toArray(document.childNodes); + } catch(ex) { } + deepEqual(actual, _.map(document.childNodes, _.identity), 'works on NodeList'); + } }); test('size', function() { @@ -693,4 +822,26 @@ }, predicate); }); + if (typeof document != 'undefined') { + test('Can use various collection methods on NodeLists', function() { + var parent = document.createElement('div'); + parent.innerHTML = 'textnode'; + + var elementChildren = _.filter(parent.childNodes, _.isElement); + equal(elementChildren.length, 2); + + deepEqual(_.map(elementChildren, 'id'), ['id1', 'id2']); + deepEqual(_.map(parent.childNodes, 'nodeType'), [1, 3, 1]); + + ok(!_.every(parent.childNodes, _.isElement)); + ok(_.some(parent.childNodes, _.isElement)); + + function compareNode(node) { + return _.isElement(node) ? node.id.charAt(2) : void 0; + } + equal(_.max(parent.childNodes, compareNode), _.last(parent.childNodes)); + equal(_.min(parent.childNodes, compareNode), _.first(parent.childNodes)); + }); + } + }()); diff --git a/vendor/underscore/test/functions.js b/vendor/underscore/test/functions.js index 37511b62d2..0fded5c407 100644 --- a/vendor/underscore/test/functions.js +++ b/vendor/underscore/test/functions.js @@ -1,6 +1,8 @@ (function() { + var _ = typeof require == 'function' ? require('..') : window._; - module('Functions'); + QUnit.module('Functions'); + QUnit.config.asyncRetries = 3; test('bind', function() { var context = {name : 'moe'}; @@ -12,7 +14,9 @@ equal(bound(), 'name: moe', 'can do OO-style binding'); bound = _.bind(func, null, 'curly'); - equal(bound(), 'name: curly', 'can bind without specifying a context'); + var result = bound(); + // Work around a PhantomJS bug when applying a function with null|undefined. + ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context'); func = function(salutation, name) { return salutation + ': ' + name; }; func = _.bind(func, this, 'hello'); @@ -40,7 +44,7 @@ equal(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context"); ok(newBoundf instanceof F, 'a bound instance is an instance of the original function'); - raises(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function'); + throws(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function'); }); test('partial', function() { @@ -59,6 +63,20 @@ func = _.partial(function() { return typeof arguments[2]; }, _, 'b', _, 'd'); equal(func('a'), 'undefined', 'unfilled placeholders are undefined'); + + // passes context + function MyWidget(name, options) { + this.name = name; + this.options = options; + } + MyWidget.prototype.get = function() { + return this.name; + }; + var MyWidgetWithCoolOpts = _.partial(MyWidget, _, {a: 1}); + var widget = new MyWidgetWithCoolOpts('foo'); + ok(widget instanceof MyWidget, 'Can partially bind a constructor'); + equal(widget.get(), 'foo', 'keeps prototype'); + deepEqual(widget.options, {a: 1}); }); test('bindAll', function() { @@ -81,9 +99,9 @@ sayLast : function() { return this.sayHi(_.last(arguments)); } }; - raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named'); - raises(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined'); - raises(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function'); + throws(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named'); + throws(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined'); + throws(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function'); _.bindAll(moe, 'sayHi', 'sayLast'); curly.sayHi = moe.sayHi; @@ -548,6 +566,16 @@ test('iteratee', function() { var identity = _.iteratee(); equal(identity, _.identity, '_.iteratee is exposed as an external function.'); + + function fn() { + return arguments; + } + _.each([_.iteratee(fn), _.iteratee(fn, {})], function(cb) { + equal(cb().length, 0); + deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4)); + deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11)); + }); + }); }()); diff --git a/vendor/underscore/test/objects.js b/vendor/underscore/test/objects.js index 76e55982f8..70270dc698 100644 --- a/vendor/underscore/test/objects.js +++ b/vendor/underscore/test/objects.js @@ -1,7 +1,9 @@ (function() { + var _ = typeof require == 'function' ? require('..') : window._; - module('Objects'); - /* global iObject, iElement, iArguments, iFunction, iArray, iString, iNumber, iBoolean, iDate, iRegExp, iNaN, iNull, iUndefined, ActiveXObject */ + QUnit.module('Objects'); + + var testElement = typeof document === 'object' ? document.createElement('div') : void 0; test('keys', function() { deepEqual(_.keys({one : 1, two : 2}), ['one', 'two'], 'can extract the keys from an object'); @@ -13,6 +15,62 @@ deepEqual(_.keys(1), []); deepEqual(_.keys('a'), []); deepEqual(_.keys(true), []); + + // keys that may be missed if the implementation isn't careful + var trouble = { + 'constructor': Object, + 'valueOf': _.noop, + 'hasOwnProperty': null, + 'toString': 5, + 'toLocaleString': undefined, + 'propertyIsEnumerable': /a/, + 'isPrototypeOf': this, + '__defineGetter__': Boolean, + '__defineSetter__': {}, + '__lookupSetter__': false, + '__lookupGetter__': [] + }; + var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable', + 'isPrototypeOf', '__defineGetter__', '__defineSetter__', '__lookupSetter__', '__lookupGetter__'].sort(); + deepEqual(_.keys(trouble).sort(), troubleKeys, 'matches non-enumerable properties'); + }); + + test('allKeys', function() { + deepEqual(_.allKeys({one : 1, two : 2}), ['one', 'two'], 'can extract the allKeys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + deepEqual(_.allKeys(a), ['1'], 'is not fooled by sparse arrays; see issue #95'); + + a.a = a; + deepEqual(_.allKeys(a), ['1', 'a'], 'is not fooled by sparse arrays with additional properties'); + + _.each([null, void 0, 1, 'a', true, NaN, {}, [], new Number(5), new Date(0)], function(val) { + deepEqual(_.allKeys(val), []); + }); + + // allKeys that may be missed if the implementation isn't careful + var trouble = { + constructor: Object, + valueOf: _.noop, + hasOwnProperty: null, + toString: 5, + toLocaleString: undefined, + propertyIsEnumerable: /a/, + isPrototypeOf: this + }; + var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable', + 'isPrototypeOf'].sort(); + deepEqual(_.allKeys(trouble).sort(), troubleKeys, 'matches non-enumerable properties'); + + function A() {} + A.prototype.foo = 'foo'; + var b = new A(); + b.bar = 'bar'; + deepEqual(_.allKeys(b).sort(), ['bar', 'foo'], 'should include inherited keys'); + + function y() {} + y.x = 'z'; + deepEqual(_.allKeys(y), ['x'], 'should get keys from constructor'); }); test('values', function() { @@ -63,7 +121,9 @@ F.prototype = {a: 'b'}; var subObj = new F(); subObj.c = 'd'; - deepEqual(_.extend({}, subObj), {c: 'd'}, 'extend ignores any properties but own from source'); + deepEqual(_.extend({}, subObj), {a: 'b', c: 'd'}, 'extend copies all properties from source'); + _.extend(subObj, {}); + ok(!subObj.hasOwnProperty('a'), "extend does not convert destination object's 'in' properties to 'own' properties"); try { result = {}; @@ -76,6 +136,36 @@ strictEqual(_.extend(undefined, {a: 1}), undefined, 'extending undefined results in undefined'); }); + test('extendOwn', function() { + var result; + equal(_.extendOwn({}, {a: 'b'}).a, 'b', 'can assign an object with the attributes of another'); + equal(_.extendOwn({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination'); + equal(_.extendOwn({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overriden"); + result = _.extendOwn({x: 'x'}, {a: 'a'}, {b: 'b'}); + deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can assign from multiple source objects'); + result = _.assign({x: 'x'}, {a: 'a', x: 2}, {a: 'b'}); + deepEqual(result, {x: 2, a: 'b'}, 'assigning from multiple source objects last property trumps'); + deepEqual(_.extendOwn({}, {a: void 0, b: null}), {a: void 0, b: null}, 'assign copies undefined values'); + + var F = function() {}; + F.prototype = {a: 'b'}; + var subObj = new F(); + subObj.c = 'd'; + deepEqual(_.extendOwn({}, subObj), {c: 'd'}, 'assign copies own properties from source'); + + result = {}; + deepEqual(_.assign(result, null, undefined, {a: 1}), {a: 1}, 'should not error on `null` or `undefined` sources'); + + _.each(['a', 5, null, false], function(val) { + strictEqual(_.assign(val, {a: 1}), val, 'assigning non-objects results in returning the non-object value'); + }); + + strictEqual(_.extendOwn(undefined, {a: 1}), undefined, 'assigning undefined results in undefined'); + + result = _.extendOwn({a: 1, 0: 2, 1: '5', length: 6}, {0: 1, 1: 2, length: 2}); + deepEqual(result, {a: 1, 0: 1, 1: 2, length: 2}, 'assign should treat array-like objects like normal objects'); + }); + test('pick', function() { var result; result = _.pick({a: 1, b: 2, c: 3}, 'a', 'c'); @@ -87,8 +177,10 @@ result = _.pick(['a', 'b'], 1); deepEqual(result, {1: 'b'}, 'can pick numeric properties'); - deepEqual(_.pick(null, 'a', 'b'), {}, 'non objects return empty object'); - deepEqual(_.pick(undefined, 'toString'), {}, 'null/undefined return empty object'); + _.each([null, void 0], function(val) { + deepEqual(_.pick(val, 'hasOwnProperty'), {}, 'Called with null/undefined'); + deepEqual(_.pick(val, _.constant(true)), {}); + }); deepEqual(_.pick(5, 'toString', 'b'), {toString: Number.prototype.toString}, 'can iterate primitives'); var data = {a: 1, b: 2, c: 3}; @@ -108,6 +200,11 @@ deepEqual(_.pick(data, function(val, key) { return this[key] === 3 && this === instance; }, instance), {c: 3}, 'function is given context'); + + ok(!_.has(_.pick({}, 'foo'), 'foo'), 'does not set own property if property not in object'); + _.pick(data, function(value, key, obj) { + equal(obj, data, 'passes same object as third parameter of iteratee'); + }); }); test('omit', function() { @@ -419,9 +516,6 @@ b = _({x: 1, y: 2}).chain(); equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained'); - // Objects from another frame. - ok(_.isEqual({}, iObject)); - // Objects without a `constructor` property if (Object.create) { a = Object.create(null, {x: {value: 1, enumerable: true}}); @@ -454,38 +548,19 @@ var args = function(){ return arguments; }; ok(_.isEmpty(args()), 'empty arguments object is empty'); ok(!_.isEmpty(args('')), 'non-empty arguments object is not empty'); - }); - // Setup remote variables for iFrame tests. - var iframe = document.createElement('iframe'); - iframe.frameBorder = iframe.height = iframe.width = 0; - document.body.appendChild(iframe); - var iDoc = (iDoc = iframe.contentDocument || iframe.contentWindow).document || iDoc; - iDoc.write( - '' - ); - iDoc.close(); - - test('isElement', function() { - ok(!_.isElement('div'), 'strings are not dom elements'); - ok(_.isElement(document.body), 'the body tag is a DOM element'); - ok(_.isElement(iElement), 'even from another frame'); + // covers collecting non-enumerable properties in IE < 9 + var nonEnumProp = {'toString': 5}; + ok(!_.isEmpty(nonEnumProp), 'non-enumerable property is not empty'); }); + if (typeof document === 'object') { + test('isElement', function() { + ok(!_.isElement('div'), 'strings are not dom elements'); + ok(_.isElement(testElement), 'an element is a DOM element'); + }); + } + test('isArguments', function() { var args = (function(){ return arguments; }(1, 2, 3)); ok(!_.isArguments('string'), 'a string is not an arguments object'); @@ -493,16 +568,15 @@ ok(_.isArguments(args), 'but the arguments object is an arguments object'); ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); ok(!_.isArguments([1, 2, 3]), 'and not vanilla arrays.'); - ok(_.isArguments(iArguments), 'even from another frame'); }); test('isObject', function() { ok(_.isObject(arguments), 'the arguments object is object'); ok(_.isObject([1, 2, 3]), 'and arrays'); - ok(_.isObject(document.body), 'and DOM element'); - ok(_.isObject(iElement), 'even from another frame'); + if (testElement) { + ok(_.isObject(testElement), 'and DOM element'); + } ok(_.isObject(function () {}), 'and functions'); - ok(_.isObject(iFunction), 'even from another frame'); ok(!_.isObject(null), 'but not null'); ok(!_.isObject(undefined), 'and not undefined'); ok(!_.isObject('string'), 'and not string'); @@ -515,16 +589,17 @@ ok(!_.isArray(undefined), 'undefined vars are not arrays'); ok(!_.isArray(arguments), 'the arguments object is not an array'); ok(_.isArray([1, 2, 3]), 'but arrays are'); - ok(_.isArray(iArray), 'even from another frame'); }); test('isString', function() { var obj = new String('I am a string object'); - ok(!_.isString(document.body), 'the document body is not a string'); + if (testElement) { + ok(!_.isString(testElement), 'an element is not a string'); + } ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); - ok(_.isString(iString), 'even from another frame'); - ok(_.isString('I am a string literal'), 'string literals are'); + strictEqual(_.isString('I am a string literal'), true, 'string literals are'); ok(_.isString(obj), 'so are String objects'); + strictEqual(_.isString(1), false); }); test('isNumber', function() { @@ -534,7 +609,6 @@ ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); ok(_.isNumber(NaN), 'NaN *is* a number'); ok(_.isNumber(Infinity), 'Infinity is a number'); - ok(_.isNumber(iNumber), 'even from another frame'); ok(!_.isNumber('1'), 'numeric strings are not numbers'); }); @@ -549,7 +623,6 @@ ok(!_.isBoolean(null), 'null is not a boolean'); ok(_.isBoolean(true), 'but true is'); ok(_.isBoolean(false), 'and so is false'); - ok(_.isBoolean(iBoolean), 'even from another frame'); }); test('isFunction', function() { @@ -557,21 +630,35 @@ ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); ok(!_.isFunction('moe'), 'strings are not functions'); ok(_.isFunction(_.isFunction), 'but functions are'); - ok(_.isFunction(iFunction), 'even from another frame'); ok(_.isFunction(function(){}), 'even anonymous ones'); + + if (testElement) { + ok(!_.isFunction(testElement), 'elements are not functions'); + } }); + if (typeof Int8Array !== 'undefined') { + test('#1929 Typed Array constructors are functions', function() { + _.chain(['Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array']) + .map(_.propertyOf(typeof GLOBAL != 'undefined' ? GLOBAL : window)) + .compact() + .each(function(TypedArray) { + // PhantomJS reports `typeof UInt8Array == 'object'` and doesn't report toString TypeArray + // as a function + strictEqual(_.isFunction(TypedArray), Object.prototype.toString.call(TypedArray) === '[object Function]'); + }); + }); + } + test('isDate', function() { ok(!_.isDate(100), 'numbers are not dates'); ok(!_.isDate({}), 'objects are not dates'); ok(_.isDate(new Date()), 'but dates are'); - ok(_.isDate(iDate), 'even from another frame'); }); test('isRegExp', function() { ok(!_.isRegExp(_.identity), 'functions are not RegExps'); ok(_.isRegExp(/identity/), 'but RegExps are'); - ok(_.isRegExp(iRegExp), 'even from another frame'); }); test('isFinite', function() { @@ -595,7 +682,6 @@ ok(!_.isNaN(null), 'null is not NaN'); ok(!_.isNaN(0), '0 is not NaN'); ok(_.isNaN(NaN), 'but NaN is'); - ok(_.isNaN(iNaN), 'even from another frame'); ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); }); @@ -603,7 +689,6 @@ ok(!_.isNull(undefined), 'undefined is not null'); ok(!_.isNull(NaN), 'NaN is not null'); ok(_.isNull(null), 'but null is'); - ok(_.isNull(iNull), 'even from another frame'); }); test('isUndefined', function() { @@ -613,20 +698,20 @@ ok(!_.isUndefined(NaN), 'NaN is defined'); ok(_.isUndefined(), 'nothing is undefined'); ok(_.isUndefined(undefined), 'undefined is undefined'); - ok(_.isUndefined(iUndefined), 'even from another frame'); - }); - - if (window.ActiveXObject) { - test('IE host objects', function() { - var xml = new ActiveXObject('Msxml2.DOMDocument.3.0'); - ok(!_.isNumber(xml)); - ok(!_.isBoolean(xml)); - ok(!_.isNaN(xml)); - ok(!_.isFunction(xml)); - ok(!_.isNull(xml)); - ok(!_.isUndefined(xml)); - }); - } + }); + + test('isError', function() { + ok(!_.isError(1), 'numbers are not Errors'); + ok(!_.isError(null), 'null is not an Error'); + ok(!_.isError(Error), 'functions are not Errors'); + ok(_.isError(new Error()), 'Errors are Errors'); + ok(_.isError(new EvalError()), 'EvalErrors are Errors'); + ok(_.isError(new RangeError()), 'RangeErrors are Errors'); + ok(_.isError(new ReferenceError()), 'ReferenceErrors are Errors'); + ok(_.isError(new SyntaxError()), 'SyntaxErrors are Errors'); + ok(_.isError(new TypeError()), 'TypeErrors are Errors'); + ok(_.isError(new URIError()), 'URIErrors are Errors'); + }); test('tap', function() { var intercepted = null; @@ -658,22 +743,62 @@ strictEqual(_.has(undefined, 'foo'), false, 'has() returns false for undefined'); }); - test('matches', function() { + test('isMatch', function() { + var moe = {name: 'Moe Howard', hair: true}; + var curly = {name: 'Curly Howard', hair: false}; + + equal(_.isMatch(moe, {hair: true}), true, 'Returns a boolean'); + equal(_.isMatch(curly, {hair: true}), false, 'Returns a boolean'); + + equal(_.isMatch(5, {__x__: undefined}), false, 'can match undefined props on primitives'); + equal(_.isMatch({__x__: undefined}, {__x__: undefined}), true, 'can match undefined props'); + + equal(_.isMatch(null, {}), true, 'Empty spec called with null object returns true'); + equal(_.isMatch(null, {a: 1}), false, 'Non-empty spec called with null object returns false'); + + _.each([null, undefined], function(item) { strictEqual(_.isMatch(item, null), true, 'null matches null'); }); + _.each([null, undefined], function(item) { strictEqual(_.isMatch(item, null), true, 'null matches {}'); }); + strictEqual(_.isMatch({b: 1}, {a: undefined}), false, 'handles undefined values (1683)'); + + _.each([true, 5, NaN, null, undefined], function(item) { + strictEqual(_.isMatch({a: 1}, item), true, 'treats primitives as empty'); + }); + + function Prototest() {} + Prototest.prototype.x = 1; + var specObj = new Prototest; + equal(_.isMatch({x: 2}, specObj), true, 'spec is restricted to own properties'); + + specObj.y = 5; + equal(_.isMatch({x: 1, y: 5}, specObj), true); + equal(_.isMatch({x: 1, y: 4}, specObj), false); + + ok(_.isMatch(specObj, {x: 1, y: 5}), 'inherited and own properties are checked on the test object'); + + Prototest.x = 5; + ok(_.isMatch({x: 5, y: 1}, Prototest), 'spec can be a function'); + + //null edge cases + var oCon = {'constructor': Object}; + deepEqual(_.map([null, undefined, 5, {}], _.partial(_.isMatch, _, oCon)), [false, false, false, true], 'doesnt falsey match constructor on undefined/null'); + }); + + test('matcher', function() { var moe = {name: 'Moe Howard', hair: true}; var curly = {name: 'Curly Howard', hair: false}; var stooges = [moe, curly]; - equal(_.matches({hair: true})(moe), true, 'Returns a boolean'); - equal(_.matches({hair: true})(curly), false, 'Returns a boolean'); + equal(_.matcher({hair: true})(moe), true, 'Returns a boolean'); + equal(_.matcher({hair: true})(curly), false, 'Returns a boolean'); - equal(_.matches({__x__: undefined})(5), false, 'can match undefined props on primitives'); - equal(_.matches({__x__: undefined})({__x__: undefined}), true, 'can match undefined props'); + equal(_.matcher({__x__: undefined})(5), false, 'can match undefined props on primitives'); + equal(_.matcher({__x__: undefined})({__x__: undefined}), true, 'can match undefined props'); - equal(_.matches({})(null), true, 'Empty spec called with null object returns true'); - equal(_.matches({a: 1})(null), false, 'Non-empty spec called with null object returns false'); + equal(_.matcher({})(null), true, 'Empty spec called with null object returns true'); + equal(_.matcher({a: 1})(null), false, 'Non-empty spec called with null object returns false'); - ok(_.find(stooges, _.matches({hair: false})) === curly, 'returns a predicate that can be used by finding functions.'); - ok(_.find(stooges, _.matches(moe)) === moe, 'can be used to locate an object exists in a collection.'); + ok(_.find(stooges, _.matcher({hair: false})) === curly, 'returns a predicate that can be used by finding functions.'); + ok(_.find(stooges, _.matcher(moe)) === moe, 'can be used to locate an object exists in a collection.'); deepEqual(_.where([null, undefined], {a: 1}), [], 'Do not throw on null values.'); deepEqual(_.where([null, undefined], null), [null, undefined], 'null matches null'); @@ -687,22 +812,22 @@ function Prototest() {} Prototest.prototype.x = 1; var specObj = new Prototest; - var protospec = _.matches(specObj); + var protospec = _.matcher(specObj); equal(protospec({x: 2}), true, 'spec is restricted to own properties'); specObj.y = 5; - protospec = _.matches(specObj); + protospec = _.matcher(specObj); equal(protospec({x: 1, y: 5}), true); equal(protospec({x: 1, y: 4}), false); - ok(_.matches({x: 1, y: 5})(specObj), 'inherited and own properties are checked on the test object'); + ok(_.matcher({x: 1, y: 5})(specObj), 'inherited and own properties are checked on the test object'); Prototest.x = 5; - ok(_.matches(Prototest)({x: 5, y: 1}), 'spec can be a function'); + ok(_.matcher(Prototest)({x: 5, y: 1}), 'spec can be a function'); // #1729 var o = {'b': 1}; - var m = _.matches(o); + var m = _.matcher(o); equal(m({'b': 1}), true); o.b = 2; @@ -711,8 +836,159 @@ //null edge cases - var oCon = _.matches({'constructor': Object}); - deepEqual(_.map([null, undefined, 5, {}], oCon), [false, false, false, true], 'doesnt fasley match constructor on undefined/null'); + var oCon = _.matcher({'constructor': Object}); + deepEqual(_.map([null, undefined, 5, {}], oCon), [false, false, false, true], 'doesnt falsey match constructor on undefined/null'); }); + test('matcher', function() { + var moe = {name: 'Moe Howard', hair: true}; + var curly = {name: 'Curly Howard', hair: false}; + var stooges = [moe, curly]; + + equal(_.matcher({hair: true})(moe), true, 'Returns a boolean'); + equal(_.matcher({hair: true})(curly), false, 'Returns a boolean'); + + equal(_.matcher({__x__: undefined})(5), false, 'can match undefined props on primitives'); + equal(_.matcher({__x__: undefined})({__x__: undefined}), true, 'can match undefined props'); + + equal(_.matcher({})(null), true, 'Empty spec called with null object returns true'); + equal(_.matcher({a: 1})(null), false, 'Non-empty spec called with null object returns false'); + + ok(_.find(stooges, _.matcher({hair: false})) === curly, 'returns a predicate that can be used by finding functions.'); + ok(_.find(stooges, _.matcher(moe)) === moe, 'can be used to locate an object exists in a collection.'); + deepEqual(_.where([null, undefined], {a: 1}), [], 'Do not throw on null values.'); + + deepEqual(_.where([null, undefined], null), [null, undefined], 'null matches null'); + deepEqual(_.where([null, undefined], {}), [null, undefined], 'null matches {}'); + deepEqual(_.where([{b: 1}], {a: undefined}), [], 'handles undefined values (1683)'); + + _.each([true, 5, NaN, null, undefined], function(item) { + deepEqual(_.where([{a: 1}], item), [{a: 1}], 'treats primitives as empty'); + }); + + function Prototest() {} + Prototest.prototype.x = 1; + var specObj = new Prototest; + var protospec = _.matcher(specObj); + equal(protospec({x: 2}), true, 'spec is restricted to own properties'); + + specObj.y = 5; + protospec = _.matcher(specObj); + equal(protospec({x: 1, y: 5}), true); + equal(protospec({x: 1, y: 4}), false); + + ok(_.matcher({x: 1, y: 5})(specObj), 'inherited and own properties are checked on the test object'); + + Prototest.x = 5; + ok(_.matcher(Prototest)({x: 5, y: 1}), 'spec can be a function'); + + // #1729 + var o = {'b': 1}; + var m = _.matcher(o); + + equal(m({'b': 1}), true); + o.b = 2; + o.a = 1; + equal(m({'b': 1}), true, 'changing spec object doesnt change matches result'); + + + //null edge cases + var oCon = _.matcher({'constructor': Object}); + deepEqual(_.map([null, undefined, 5, {}], oCon), [false, false, false, true], 'doesnt falsey match constructor on undefined/null'); + }); + + test('findKey', function() { + var objects = { + a: {'a': 0, 'b': 0}, + b: {'a': 1, 'b': 1}, + c: {'a': 2, 'b': 2} + }; + + equal(_.findKey(objects, function(obj) { + return obj.a === 0; + }), 'a'); + + equal(_.findKey(objects, function(obj) { + return obj.b * obj.a === 4; + }), 'c'); + + equal(_.findKey(objects, 'a'), 'b', 'Uses lookupIterator'); + + equal(_.findKey(objects, function(obj) { + return obj.b * obj.a === 5; + }), undefined); + + strictEqual(_.findKey([1, 2, 3, 4, 5, 6], function(obj) { + return obj === 3; + }), '2', 'Keys are strings'); + + strictEqual(_.findKey(objects, function(a) { + return a.foo === null; + }), undefined); + + _.findKey({a: {a: 1}}, function(a, key, obj) { + equal(key, 'a'); + deepEqual(obj, {a: {a: 1}}); + strictEqual(this, objects, 'called with context'); + }, objects); + + var array = [1, 2, 3, 4]; + array.match = 55; + strictEqual(_.findKey(array, function(x) { return x === 55; }), 'match', 'matches array-likes keys'); + }); + + + test('mapObject', function() { + var obj = {'a': 1, 'b': 2}; + var objects = { + a: {'a': 0, 'b': 0}, + b: {'a': 1, 'b': 1}, + c: {'a': 2, 'b': 2} + }; + + deepEqual(_.mapObject(obj, function(val) { + return val * 2; + }), {'a': 2, 'b': 4}, 'simple objects'); + + deepEqual(_.mapObject(objects, function(val) { + return _.reduce(val, function(memo,v){ + return memo + v; + },0); + }), {'a': 0, 'b': 2, 'c': 4}, 'nested objects'); + + deepEqual(_.mapObject(obj, function(val,key,obj) { + return obj[key] * 2; + }), {'a': 2, 'b': 4}, 'correct keys'); + + deepEqual(_.mapObject([1,2], function(val) { + return val * 2; + }), {'0': 2, '1': 4}, 'check behavior for arrays'); + + deepEqual(_.mapObject(obj, function(val) { + return val * this.multiplier; + }, {multiplier : 3}), {'a': 3, 'b': 6}, 'keep context'); + + deepEqual(_.mapObject({a: 1}, function() { + return this.length; + }, [1,2]), {'a': 2}, 'called with context'); + + var ids = _.mapObject({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){ + return n.id; + }); + deepEqual(ids, {'length': undefined, '0': '1', '1': '2'}, 'Check with array-like objects'); + + // Passing a property name like _.pluck. + var people = {'a': {name : 'moe', age : 30}, 'b': {name : 'curly', age : 50}}; + deepEqual(_.mapObject(people, 'name'), {'a': 'moe', 'b': 'curly'}, 'predicate string map to object properties'); + + _.each([null, void 0, 1, 'abc', [], {}, undefined], function(val){ + deepEqual(_.mapObject(val, _.identity), {}, 'mapValue identity'); + }); + + var Proto = function(){this.a = 1;}; + Proto.prototype.b = 1; + var protoObj = new Proto(); + deepEqual(_.mapObject(protoObj, _.identity), {a: 1}, 'ignore inherited values from prototypes'); + + }); }()); diff --git a/vendor/underscore/test/utility.js b/vendor/underscore/test/utility.js index 9c54ea0be9..83b76a0e36 100644 --- a/vendor/underscore/test/utility.js +++ b/vendor/underscore/test/utility.js @@ -1,8 +1,8 @@ (function() { - + var _ = typeof require == 'function' ? require('..') : window._; var templateSettings; - module('Utility', { + QUnit.module('Utility', { setup: function() { templateSettings = _.clone(_.templateSettings); @@ -21,13 +21,13 @@ }); test('identity', function() { - var moe = {name : 'moe'}; - equal(_.identity(moe), moe, 'moe is the same as his identity'); + var stooge = {name : 'moe'}; + equal(_.identity(stooge), stooge, 'stooge is the same as his identity'); }); test('constant', function() { - var moe = {name : 'moe'}; - equal(_.constant(moe)(), moe, 'should create a function that returns moe'); + var stooge = {name : 'moe'}; + equal(_.constant(stooge)(), stooge, 'should create a function that returns stooge'); }); test('noop', function() { @@ -35,8 +35,28 @@ }); test('property', function() { - var moe = {name : 'moe'}; - equal(_.property('name')(moe), 'moe', 'should return the property with the given name'); + var stooge = {name : 'moe'}; + equal(_.property('name')(stooge), 'moe', 'should return the property with the given name'); + equal(_.property('name')(null), undefined, 'should return undefined for null values'); + equal(_.property('name')(undefined), undefined, 'should return undefined for undefined values'); + }); + + test('propertyOf', function() { + var stoogeRanks = _.propertyOf({curly: 2, moe: 1, larry: 3}); + equal(stoogeRanks('curly'), 2, 'should return the property with the given name'); + equal(stoogeRanks(null), undefined, 'should return undefined for null values'); + equal(stoogeRanks(undefined), undefined, 'should return undefined for undefined values'); + + function MoreStooges() { this.shemp = 87; } + MoreStooges.prototype = {curly: 2, moe: 1, larry: 3}; + var moreStoogeRanks = _.propertyOf(new MoreStooges()); + equal(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain'); + + var nullPropertyOf = _.propertyOf(null); + equal(nullPropertyOf('curly'), undefined, 'should return undefined when obj is null'); + + var undefPropertyOf = _.propertyOf(undefined); + equal(undefPropertyOf('curly'), undefined, 'should return undefined when obj is undefined'); }); test('random', function() { @@ -268,6 +288,41 @@ strictEqual(_.result(null, 'x'), undefined); }); + test('result returns a default value if object is null or undefined', function() { + strictEqual(_.result(null, 'b', 'default'), 'default'); + strictEqual(_.result(undefined, 'c', 'default'), 'default'); + strictEqual(_.result(''.match('missing'), 1, 'default'), 'default'); + }); + + test('result returns a default value if property of object is missing', function() { + strictEqual(_.result({d: null}, 'd', 'default'), null); + strictEqual(_.result({e: false}, 'e', 'default'), false); + }); + + test('result only returns the default value if the object does not have the property or is undefined', function() { + strictEqual(_.result({}, 'b', 'default'), 'default'); + strictEqual(_.result({d: undefined}, 'd', 'default'), 'default'); + }); + + test('result does not return the default if the property of an object is found in the prototype', function() { + var Foo = function(){}; + Foo.prototype.bar = 1; + strictEqual(_.result(new Foo, 'bar', 2), 1); + }); + + test('result does use the fallback when the result of invoking the property is undefined', function() { + var obj = {a: function() {}}; + strictEqual(_.result(obj, 'a', 'failed'), undefined); + }); + + test('result fallback can use a function', function() { + var obj = {a: [1, 2, 3]}; + strictEqual(_.result(obj, 'b', _.constant(5)), 5); + strictEqual(_.result(obj, 'b', function() { + return this.a; + }), obj.a, 'called with context'); + }); + test('_.templateSettings.variable', function() { var s = '<%=data.x%>'; var data = {x: 'x'}; diff --git a/vendor/underscore/underscore-min.js b/vendor/underscore/underscore-min.js index 11f1d96f53..bc54314036 100644 --- a/vendor/underscore/underscore-min.js +++ b/vendor/underscore/underscore-min.js @@ -1,6 +1,6 @@ -// Underscore.js 1.7.0 +// Underscore.js 1.8.2 // http://underscorejs.org -// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. -(function(){var n=this,t=n._,r=Array.prototype,e=Object.prototype,u=Function.prototype,i=r.push,a=r.slice,o=r.concat,l=e.toString,c=e.hasOwnProperty,f=Array.isArray,s=Object.keys,p=u.bind,h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=h),exports._=h):n._=h,h.VERSION="1.7.0";var g=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}};h.iteratee=function(n,t,r){return null==n?h.identity:h.isFunction(n)?g(n,t,r):h.isObject(n)?h.matches(n):h.property(n)},h.each=h.forEach=function(n,t,r){if(null==n)return n;t=g(t,r);var e,u=n.length;if(u===+u)for(e=0;u>e;e++)t(n[e],e,n);else{var i=h.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},h.map=h.collect=function(n,t,r){if(null==n)return[];t=h.iteratee(t,r);for(var e,u=n.length!==+n.length&&h.keys(n),i=(u||n).length,a=Array(i),o=0;i>o;o++)e=u?u[o]:o,a[o]=t(n[e],e,n);return a};var v="Reduce of empty array with no initial value";h.reduce=h.foldl=h.inject=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length,o=0;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[o++]:o++]}for(;a>o;o++)u=i?i[o]:o,r=t(r,n[u],u,n);return r},h.reduceRight=h.foldr=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[--a]:--a]}for(;a--;)u=i?i[a]:a,r=t(r,n[u],u,n);return r},h.find=h.detect=function(n,t,r){var e;return t=h.iteratee(t,r),h.some(n,function(n,r,u){return t(n,r,u)?(e=n,!0):void 0}),e},h.filter=h.select=function(n,t,r){var e=[];return null==n?e:(t=h.iteratee(t,r),h.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e)},h.reject=function(n,t,r){return h.filter(n,h.negate(h.iteratee(t)),r)},h.every=h.all=function(n,t,r){if(null==n)return!0;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,!t(n[u],u,n))return!1;return!0},h.some=h.any=function(n,t,r){if(null==n)return!1;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,t(n[u],u,n))return!0;return!1},h.contains=h.include=function(n,t){return null==n?!1:(n.length!==+n.length&&(n=h.values(n)),h.indexOf(n,t)>=0)},h.invoke=function(n,t){var r=a.call(arguments,2),e=h.isFunction(t);return h.map(n,function(n){return(e?t:n[t]).apply(n,r)})},h.pluck=function(n,t){return h.map(n,h.property(t))},h.where=function(n,t){return h.filter(n,h.matches(t))},h.findWhere=function(n,t){return h.find(n,h.matches(t))},h.max=function(n,t,r){var e,u,i=-1/0,a=-1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],e>i&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(u>a||u===-1/0&&i===-1/0)&&(i=n,a=u)});return i},h.min=function(n,t,r){var e,u,i=1/0,a=1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],i>e&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(a>u||1/0===u&&1/0===i)&&(i=n,a=u)});return i},h.shuffle=function(n){for(var t,r=n&&n.length===+n.length?n:h.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=h.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},h.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=h.values(n)),n[h.random(n.length-1)]):h.shuffle(n).slice(0,Math.max(0,t))},h.sortBy=function(n,t,r){return t=h.iteratee(t,r),h.pluck(h.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var m=function(n){return function(t,r,e){var u={};return r=h.iteratee(r,e),h.each(t,function(e,i){var a=r(e,i,t);n(u,e,a)}),u}};h.groupBy=m(function(n,t,r){h.has(n,r)?n[r].push(t):n[r]=[t]}),h.indexBy=m(function(n,t,r){n[r]=t}),h.countBy=m(function(n,t,r){h.has(n,r)?n[r]++:n[r]=1}),h.sortedIndex=function(n,t,r,e){r=h.iteratee(r,e,1);for(var u=r(t),i=0,a=n.length;a>i;){var o=i+a>>>1;r(n[o])t?[]:a.call(n,0,t)},h.initial=function(n,t,r){return a.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},h.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:a.call(n,Math.max(n.length-t,0))},h.rest=h.tail=h.drop=function(n,t,r){return a.call(n,null==t||r?1:t)},h.compact=function(n){return h.filter(n,h.identity)};var y=function(n,t,r,e){if(t&&h.every(n,h.isArray))return o.apply(e,n);for(var u=0,a=n.length;a>u;u++){var l=n[u];h.isArray(l)||h.isArguments(l)?t?i.apply(e,l):y(l,t,r,e):r||e.push(l)}return e};h.flatten=function(n,t){return y(n,t,!1,[])},h.without=function(n){return h.difference(n,a.call(arguments,1))},h.uniq=h.unique=function(n,t,r,e){if(null==n)return[];h.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=h.iteratee(r,e));for(var u=[],i=[],a=0,o=n.length;o>a;a++){var l=n[a];if(t)a&&i===l||u.push(l),i=l;else if(r){var c=r(l,a,n);h.indexOf(i,c)<0&&(i.push(c),u.push(l))}else h.indexOf(u,l)<0&&u.push(l)}return u},h.union=function(){return h.uniq(y(arguments,!0,!0,[]))},h.intersection=function(n){if(null==n)return[];for(var t=[],r=arguments.length,e=0,u=n.length;u>e;e++){var i=n[e];if(!h.contains(t,i)){for(var a=1;r>a&&h.contains(arguments[a],i);a++);a===r&&t.push(i)}}return t},h.difference=function(n){var t=y(a.call(arguments,1),!0,!0,[]);return h.filter(n,function(n){return!h.contains(t,n)})},h.zip=function(n){if(null==n)return[];for(var t=h.max(arguments,"length").length,r=Array(t),e=0;t>e;e++)r[e]=h.pluck(arguments,e);return r},h.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},h.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=h.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}for(;u>e;e++)if(n[e]===t)return e;return-1},h.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=n.length;for("number"==typeof r&&(e=0>r?e+r+1:Math.min(e,r+1));--e>=0;)if(n[e]===t)return e;return-1},h.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var d=function(){};h.bind=function(n,t){var r,e;if(p&&n.bind===p)return p.apply(n,a.call(arguments,1));if(!h.isFunction(n))throw new TypeError("Bind must be called on a function");return r=a.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(a.call(arguments)));d.prototype=n.prototype;var u=new d;d.prototype=null;var i=n.apply(u,r.concat(a.call(arguments)));return h.isObject(i)?i:u}},h.partial=function(n){var t=a.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===h&&(e[u]=arguments[r++]);for(;r=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=h.bind(n[r],n);return n},h.memoize=function(n,t){var r=function(e){var u=r.cache,i=t?t.apply(this,arguments):e;return h.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},h.delay=function(n,t){var r=a.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},h.defer=function(n){return h.delay.apply(h,[n,1].concat(a.call(arguments,1)))},h.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var l=function(){o=r.leading===!1?0:h.now(),a=null,i=n.apply(e,u),a||(e=u=null)};return function(){var c=h.now();o||r.leading!==!1||(o=c);var f=t-(c-o);return e=this,u=arguments,0>=f||f>t?(clearTimeout(a),a=null,o=c,i=n.apply(e,u),a||(e=u=null)):a||r.trailing===!1||(a=setTimeout(l,f)),i}},h.debounce=function(n,t,r){var e,u,i,a,o,l=function(){var c=h.now()-a;t>c&&c>0?e=setTimeout(l,t-c):(e=null,r||(o=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,a=h.now();var c=r&&!e;return e||(e=setTimeout(l,t)),c&&(o=n.apply(i,u),i=u=null),o}},h.wrap=function(n,t){return h.partial(t,n)},h.negate=function(n){return function(){return!n.apply(this,arguments)}},h.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},h.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},h.before=function(n,t){var r;return function(){return--n>0?r=t.apply(this,arguments):t=null,r}},h.once=h.partial(h.before,2),h.keys=function(n){if(!h.isObject(n))return[];if(s)return s(n);var t=[];for(var r in n)h.has(n,r)&&t.push(r);return t},h.values=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},h.pairs=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},h.invert=function(n){for(var t={},r=h.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},h.functions=h.methods=function(n){var t=[];for(var r in n)h.isFunction(n[r])&&t.push(r);return t.sort()},h.extend=function(n){if(!h.isObject(n))return n;for(var t,r,e=1,u=arguments.length;u>e;e++){t=arguments[e];for(r in t)c.call(t,r)&&(n[r]=t[r])}return n},h.pick=function(n,t,r){var e,u={};if(null==n)return u;if(h.isFunction(t)){t=g(t,r);for(e in n){var i=n[e];t(i,e,n)&&(u[e]=i)}}else{var l=o.apply([],a.call(arguments,1));n=new Object(n);for(var c=0,f=l.length;f>c;c++)e=l[c],e in n&&(u[e]=n[e])}return u},h.omit=function(n,t,r){if(h.isFunction(t))t=h.negate(t);else{var e=h.map(o.apply([],a.call(arguments,1)),String);t=function(n,t){return!h.contains(e,t)}}return h.pick(n,t,r)},h.defaults=function(n){if(!h.isObject(n))return n;for(var t=1,r=arguments.length;r>t;t++){var e=arguments[t];for(var u in e)n[u]===void 0&&(n[u]=e[u])}return n},h.clone=function(n){return h.isObject(n)?h.isArray(n)?n.slice():h.extend({},n):n},h.tap=function(n,t){return t(n),n};var b=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof h&&(n=n._wrapped),t instanceof h&&(t=t._wrapped);var u=l.call(n);if(u!==l.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]===n)return e[i]===t;var a=n.constructor,o=t.constructor;if(a!==o&&"constructor"in n&&"constructor"in t&&!(h.isFunction(a)&&a instanceof a&&h.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c,f;if("[object Array]"===u){if(c=n.length,f=c===t.length)for(;c--&&(f=b(n[c],t[c],r,e)););}else{var s,p=h.keys(n);if(c=p.length,f=h.keys(t).length===c)for(;c--&&(s=p[c],f=h.has(t,s)&&b(n[s],t[s],r,e)););}return r.pop(),e.pop(),f};h.isEqual=function(n,t){return b(n,t,[],[])},h.isEmpty=function(n){if(null==n)return!0;if(h.isArray(n)||h.isString(n)||h.isArguments(n))return 0===n.length;for(var t in n)if(h.has(n,t))return!1;return!0},h.isElement=function(n){return!(!n||1!==n.nodeType)},h.isArray=f||function(n){return"[object Array]"===l.call(n)},h.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},h.each(["Arguments","Function","String","Number","Date","RegExp"],function(n){h["is"+n]=function(t){return l.call(t)==="[object "+n+"]"}}),h.isArguments(arguments)||(h.isArguments=function(n){return h.has(n,"callee")}),"function"!=typeof/./&&(h.isFunction=function(n){return"function"==typeof n||!1}),h.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},h.isNaN=function(n){return h.isNumber(n)&&n!==+n},h.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===l.call(n)},h.isNull=function(n){return null===n},h.isUndefined=function(n){return n===void 0},h.has=function(n,t){return null!=n&&c.call(n,t)},h.noConflict=function(){return n._=t,this},h.identity=function(n){return n},h.constant=function(n){return function(){return n}},h.noop=function(){},h.property=function(n){return function(t){return t[n]}},h.matches=function(n){var t=h.pairs(n),r=t.length;return function(n){if(null==n)return!r;n=new Object(n);for(var e=0;r>e;e++){var u=t[e],i=u[0];if(u[1]!==n[i]||!(i in n))return!1}return!0}},h.times=function(n,t,r){var e=Array(Math.max(0,n));t=g(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},h.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},h.now=Date.now||function(){return(new Date).getTime()};var _={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},w=h.invert(_),j=function(n){var t=function(t){return n[t]},r="(?:"+h.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};h.escape=j(_),h.unescape=j(w),h.result=function(n,t){if(null==n)return void 0;var r=n[t];return h.isFunction(r)?n[t]():r};var x=0;h.uniqueId=function(n){var t=++x+"";return n?n+t:t},h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/(.)^/,k={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},O=/\\|'|\r|\n|\u2028|\u2029/g,F=function(n){return"\\"+k[n]};h.template=function(n,t,r){!t&&r&&(t=r),t=h.defaults({},t,h.templateSettings);var e=RegExp([(t.escape||A).source,(t.interpolate||A).source,(t.evaluate||A).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){return i+=n.slice(u,o).replace(O,F),u=o+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":a&&(i+="';\n"+a+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var a=new Function(t.variable||"obj","_",i)}catch(o){throw o.source=i,o}var l=function(n){return a.call(this,n,h)},c=t.variable||"obj";return l.source="function("+c+"){\n"+i+"}",l},h.chain=function(n){var t=h(n);return t._chain=!0,t};var E=function(n){return this._chain?h(n).chain():n};h.mixin=function(n){h.each(h.functions(n),function(t){var r=h[t]=n[t];h.prototype[t]=function(){var n=[this._wrapped];return i.apply(n,arguments),E.call(this,r.apply(h,n))}})},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=r[n];h.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],E.call(this,r)}}),h.each(["concat","join","slice"],function(n){var t=r[n];h.prototype[n]=function(){return E.call(this,t.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}).call(this); +(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=d(e,i,4);var o=!w(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=b(r,e);for(var u=null!=t&&t.length,i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t){var r=S.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||o,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=S[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var e=this,u=e._,i=Array.prototype,o=Object.prototype,a=Function.prototype,c=i.push,l=i.slice,f=o.toString,s=o.hasOwnProperty,p=Array.isArray,h=Object.keys,v=a.bind,g=Object.create,y=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):e._=m,m.VERSION="1.8.2";var d=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},b=function(n,t,r){return null==n?m.identity:m.isFunction(n)?d(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return b(n,t,1/0)};var x=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var l=o[c];t&&r[l]!==void 0||(r[l]=i[l])}return r}},_=function(n){if(!m.isObject(n))return{};if(g)return g(n);y.prototype=n;var t=new y;return y.prototype=null,t},j=Math.pow(2,53)-1,w=function(n){var t=n&&n.length;return"number"==typeof t&&t>=0&&j>=t};m.each=m.forEach=function(n,t,r){t=d(t,r);var e,u;if(w(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=b(t,r);for(var e=!w(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=w(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=b(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(b(t)),r)},m.every=m.all=function(n,t,r){t=b(t,r);for(var e=!w(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=b(t,r);for(var e=!w(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r){return w(n)||(n=m.values(n)),m.indexOf(n,t,"number"==typeof r&&r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=w(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=b(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=w(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=b(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=w(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(w(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=b(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var A=function(n){return function(t,r,e){var u={};return r=b(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=A(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=A(function(n,t,r){n[r]=t}),m.countBy=A(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):w(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:w(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=b(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var k=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=n&&n.length;a>o;o++){var c=n[o];if(w(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=k(c,t,r));var l=0,f=c.length;for(u.length+=f;f>l;)u[i++]=c[l++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return k(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){if(null==n)return[];m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=b(r,e));for(var u=[],i=[],o=0,a=n.length;a>o;o++){var c=n[o],l=r?r(c,o,n):c;t?(o&&i===l||u.push(c),i=l):r?m.contains(i,l)||(i.push(l),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(k(arguments,!0,!0))},m.intersection=function(n){if(null==n)return[];for(var t=[],r=arguments.length,e=0,u=n.length;u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=k(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,"length").length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=n&&n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.indexOf=function(n,t,r){var e=0,u=n&&n.length;if("number"==typeof r)e=0>r?Math.max(0,u+r):r;else if(r&&u)return e=m.sortedIndex(n,t),n[e]===t?e:-1;if(t!==t)return m.findIndex(l.call(n,e),m.isNaN);for(;u>e;e++)if(n[e]===t)return e;return-1},m.lastIndexOf=function(n,t,r){var e=n?n.length:0;if("number"==typeof r&&(e=0>r?e+r+1:Math.min(e,r+1)),t!==t)return m.findLastIndex(l.call(n,0,e),m.isNaN);for(;--e>=0;)if(n[e]===t)return e;return-1},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=b(r,e,1);for(var u=r(t),i=0,o=n.length;o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var O=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=_(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(v&&n.bind===v)return v.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return O(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var l=m.now();a||r.leading!==!1||(a=l);var f=t-(l-a);return e=this,u=arguments,0>=f||f>t?(o&&(clearTimeout(o),o=null),a=l,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,f)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var l=m.now()-o;t>l&&l>=0?e=setTimeout(c,t-l):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var l=r&&!e;return e||(e=setTimeout(c,t)),l&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var F=!{toString:null}.propertyIsEnumerable("toString"),S=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(h)return h(n);var t=[];for(var e in n)m.has(n,e)&&t.push(e);return F&&r(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var e in n)t.push(e);return F&&r(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=b(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=x(m.allKeys),m.extendOwn=m.assign=x(m.keys),m.findKey=function(n,t,r){t=b(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=d(t,r)):(u=k(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var l=u[a],f=o[l];e(f,l,o)&&(i[l]=f)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(k(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=x(m.allKeys,!0),m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var E=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=f.call(n);if(u!==f.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!E(n[c],t[c],r,e))return!1}else{var l,s=m.keys(n);if(c=s.length,m.keys(t).length!==c)return!1;for(;c--;)if(l=s[c],!m.has(t,l)||!E(n[l],t[l],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return E(n,t)},m.isEmpty=function(n){return null==n?!0:w(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=p||function(n){return"[object Array]"===f.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return f.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===f.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&s.call(n,t)},m.noConflict=function(){return e._=u,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=function(n){return function(t){return null==t?void 0:t[n]}},m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=d(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var M={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},N=m.invert(M),I=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=I(M),m.unescape=I(N),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var B=0;m.uniqueId=function(n){var t=++B+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,R={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},q=/\\|'|\r|\n|\u2028|\u2029/g,K=function(n){return"\\"+R[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||T).source,(t.interpolate||T).source,(t.evaluate||T).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(q,K),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},l=t.variable||"obj";return c.source="function("+l+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var z=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return c.apply(n,arguments),z(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=i[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],z(this,r)}}),m.each(["concat","join","slice"],function(n){var t=i[n];m.prototype[n]=function(){return z(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); //# sourceMappingURL=underscore-min.map \ No newline at end of file diff --git a/vendor/underscore/underscore.js b/vendor/underscore/underscore.js index b4f49a0204..04cdc067a3 100644 --- a/vendor/underscore/underscore.js +++ b/vendor/underscore/underscore.js @@ -1,6 +1,6 @@ -// Underscore.js 1.7.0 +// Underscore.js 1.8.2 // http://underscorejs.org -// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. (function() { @@ -21,7 +21,6 @@ var push = ArrayProto.push, slice = ArrayProto.slice, - concat = ArrayProto.concat, toString = ObjProto.toString, hasOwnProperty = ObjProto.hasOwnProperty; @@ -30,7 +29,11 @@ var nativeIsArray = Array.isArray, nativeKeys = Object.keys, - nativeBind = FuncProto.bind; + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; // Create a safe reference to the Underscore object for use below. var _ = function(obj) { @@ -52,12 +55,12 @@ } // Current version. - _.VERSION = '1.7.0'; + _.VERSION = '1.8.2'; // Internal function that returns an efficient (for current engines) version // of the passed-in callback, to be repeatedly applied in other Underscore // functions. - var createCallback = function(func, context, argCount) { + var optimizeCb = function(func, context, argCount) { if (context === void 0) return func; switch (argCount == null ? 3 : argCount) { case 1: return function(value) { @@ -81,12 +84,52 @@ // A mostly-internal function to generate callbacks that can be applied // to each element in a collection, returning the desired result — either // identity, an arbitrary callback, a property matcher, or a property accessor. - _.iteratee = function(value, context, argCount) { + var cb = function(value, context, argCount) { if (value == null) return _.identity; - if (_.isFunction(value)) return createCallback(value, context, argCount); - if (_.isObject(value)) return _.matches(value); + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); return _.property(value); }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var isArrayLike = function(collection) { + var length = collection && collection.length; + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; // Collection Functions // -------------------- @@ -95,11 +138,10 @@ // Handles raw objects in addition to array-likes. Treats all // sparse array-likes as if they were dense. _.each = _.forEach = function(obj, iteratee, context) { - if (obj == null) return obj; - iteratee = createCallback(iteratee, context); - var i, length = obj.length; - if (length === +length) { - for (i = 0; i < length; i++) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { @@ -113,77 +155,66 @@ // Return the results of applying the iteratee to each element. _.map = _.collect = function(obj, iteratee, context) { - if (obj == null) return []; - iteratee = _.iteratee(iteratee, context); - var keys = obj.length !== +obj.length && _.keys(obj), + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), length = (keys || obj).length, - results = Array(length), - currentKey; + results = Array(length); for (var index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + var currentKey = keys ? keys[index] : index; results[index] = iteratee(obj[currentKey], currentKey, obj); } return results; }; - var reduceError = 'Reduce of empty array with no initial value'; + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } // **Reduce** builds up a single result from a list of values, aka `inject`, // or `foldl`. - _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index = 0, currentKey; - if (arguments.length < 3) { - if (!length) throw new TypeError(reduceError); - memo = obj[keys ? keys[index++] : index++]; - } - for (; index < length; index++) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; + _.reduce = _.foldl = _.inject = createReduce(1); // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== + obj.length && _.keys(obj), - index = (keys || obj).length, - currentKey; - if (arguments.length < 3) { - if (!index) throw new TypeError(reduceError); - memo = obj[keys ? keys[--index] : --index]; - } - while (index--) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; + _.reduceRight = _.foldr = createReduce(-1); // Return the first value which passes a truth test. Aliased as `detect`. _.find = _.detect = function(obj, predicate, context) { - var result; - predicate = _.iteratee(predicate, context); - _.some(obj, function(value, index, list) { - if (predicate(value, index, list)) { - result = value; - return true; - } - }); - return result; + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; }; // Return all the elements that pass a truth test. // Aliased as `select`. _.filter = _.select = function(obj, predicate, context) { var results = []; - if (obj == null) return results; - predicate = _.iteratee(predicate, context); + predicate = cb(predicate, context); _.each(obj, function(value, index, list) { if (predicate(value, index, list)) results.push(value); }); @@ -192,19 +223,17 @@ // Return all the elements for which a truth test fails. _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(_.iteratee(predicate)), context); + return _.filter(obj, _.negate(cb(predicate)), context); }; // Determine whether all of the elements match a truth test. // Aliased as `all`. _.every = _.all = function(obj, predicate, context) { - if (obj == null) return true; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; if (!predicate(obj[currentKey], currentKey, obj)) return false; } return true; @@ -213,24 +242,21 @@ // Determine if at least one element in the object matches a truth test. // Aliased as `any`. _.some = _.any = function(obj, predicate, context) { - if (obj == null) return false; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; if (predicate(obj[currentKey], currentKey, obj)) return true; } return false; }; // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (obj.length !== +obj.length) obj = _.values(obj); - return _.indexOf(obj, target) >= 0; + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, target, fromIndex) { + if (!isArrayLike(obj)) obj = _.values(obj); + return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0; }; // Invoke a method (with arguments) on every item in a collection. @@ -238,7 +264,8 @@ var args = slice.call(arguments, 2); var isFunc = _.isFunction(method); return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); }); }; @@ -250,13 +277,13 @@ // Convenience version of a common use case of `filter`: selecting only objects // containing specific `key:value` pairs. _.where = function(obj, attrs) { - return _.filter(obj, _.matches(attrs)); + return _.filter(obj, _.matcher(attrs)); }; // Convenience version of a common use case of `find`: getting the first object // containing specific `key:value` pairs. _.findWhere = function(obj, attrs) { - return _.find(obj, _.matches(attrs)); + return _.find(obj, _.matcher(attrs)); }; // Return the maximum element (or element-based computation). @@ -264,7 +291,7 @@ var result = -Infinity, lastComputed = -Infinity, value, computed; if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); + obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value > result) { @@ -272,7 +299,7 @@ } } } else { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed > lastComputed || computed === -Infinity && result === -Infinity) { @@ -289,7 +316,7 @@ var result = Infinity, lastComputed = Infinity, value, computed; if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); + obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value < result) { @@ -297,7 +324,7 @@ } } } else { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed < lastComputed || computed === Infinity && result === Infinity) { @@ -312,7 +339,7 @@ // Shuffle a collection, using the modern version of the // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). _.shuffle = function(obj) { - var set = obj && obj.length === +obj.length ? obj : _.values(obj); + var set = isArrayLike(obj) ? obj : _.values(obj); var length = set.length; var shuffled = Array(length); for (var index = 0, rand; index < length; index++) { @@ -328,7 +355,7 @@ // The internal `guard` argument allows it to work with `map`. _.sample = function(obj, n, guard) { if (n == null || guard) { - if (obj.length !== +obj.length) obj = _.values(obj); + if (!isArrayLike(obj)) obj = _.values(obj); return obj[_.random(obj.length - 1)]; } return _.shuffle(obj).slice(0, Math.max(0, n)); @@ -336,7 +363,7 @@ // Sort the object's values by a criterion produced by an iteratee. _.sortBy = function(obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); return _.pluck(_.map(obj, function(value, index, list) { return { value: value, @@ -358,7 +385,7 @@ var group = function(behavior) { return function(obj, iteratee, context) { var result = {}; - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index) { var key = iteratee(value, index, obj); behavior(result, value, key); @@ -386,37 +413,24 @@ if (_.has(result, key)) result[key]++; else result[key] = 1; }); - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = array.length; - while (low < high) { - var mid = low + high >>> 1; - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - // Safely create a real, live array from anything iterable. _.toArray = function(obj) { if (!obj) return []; if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); + if (isArrayLike(obj)) return _.map(obj, _.identity); return _.values(obj); }; // Return the number of elements in an object. _.size = function(obj) { if (obj == null) return 0; - return obj.length === +obj.length ? obj.length : _.keys(obj).length; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; }; // Split a collection into two arrays: one whose elements all satisfy the given // predicate, and one whose elements all do not satisfy the predicate. _.partition = function(obj, predicate, context) { - predicate = _.iteratee(predicate, context); + predicate = cb(predicate, context); var pass = [], fail = []; _.each(obj, function(value, key, obj) { (predicate(value, key, obj) ? pass : fail).push(value); @@ -433,30 +447,27 @@ _.first = _.head = _.take = function(array, n, guard) { if (array == null) return void 0; if (n == null || guard) return array[0]; - if (n < 0) return []; - return slice.call(array, 0, n); + return _.initial(array, array.length - n); }; // Returns everything but the last entry of the array. Especially useful on // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. + // the array, excluding the last N. _.initial = function(array, n, guard) { return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); }; // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. + // values in the array. _.last = function(array, n, guard) { if (array == null) return void 0; if (n == null || guard) return array[array.length - 1]; - return slice.call(array, Math.max(array.length - n, 0)); + return _.rest(array, Math.max(0, array.length - n)); }; // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. + // the rest N values in the array. _.rest = _.tail = _.drop = function(array, n, guard) { return slice.call(array, n == null || guard ? 1 : n); }; @@ -467,18 +478,20 @@ }; // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, output) { - if (shallow && _.every(input, _.isArray)) { - return concat.apply(output, input); - } - for (var i = 0, length = input.length; i < length; i++) { + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = input && input.length; i < length; i++) { var value = input[i]; - if (!_.isArray(value) && !_.isArguments(value)) { - if (!strict) output.push(value); - } else if (shallow) { - push.apply(output, value); - } else { - flatten(value, shallow, strict, output); + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; } } return output; @@ -486,7 +499,7 @@ // Flatten out an array, either recursively (by default), or just one level. _.flatten = function(array, shallow) { - return flatten(array, shallow, false, []); + return flatten(array, shallow, false); }; // Return a version of the array that does not contain the specified value(s). @@ -504,21 +517,21 @@ iteratee = isSorted; isSorted = false; } - if (iteratee != null) iteratee = _.iteratee(iteratee, context); + if (iteratee != null) iteratee = cb(iteratee, context); var result = []; var seen = []; for (var i = 0, length = array.length; i < length; i++) { - var value = array[i]; + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; if (isSorted) { - if (!i || seen !== value) result.push(value); - seen = value; + if (!i || seen !== computed) result.push(value); + seen = computed; } else if (iteratee) { - var computed = iteratee(value, i, array); - if (_.indexOf(seen, computed) < 0) { + if (!_.contains(seen, computed)) { seen.push(computed); result.push(value); } - } else if (_.indexOf(result, value) < 0) { + } else if (!_.contains(result, value)) { result.push(value); } } @@ -528,7 +541,7 @@ // Produce an array that contains the union: each distinct element from all of // the passed-in arrays. _.union = function() { - return _.uniq(flatten(arguments, true, true, [])); + return _.uniq(flatten(arguments, true, true)); }; // Produce an array that contains every item shared between all the @@ -551,7 +564,7 @@ // Take the difference between one array and a number of other arrays. // Only the elements present in just the first array will remain. _.difference = function(array) { - var rest = flatten(slice.call(arguments, 1), true, true, []); + var rest = flatten(arguments, true, true, 1); return _.filter(array, function(value){ return !_.contains(rest, value); }); @@ -559,23 +572,28 @@ // Zip together multiple lists into a single array -- elements that share // an index go together. - _.zip = function(array) { - if (array == null) return []; - var length = _.max(arguments, 'length').length; - var results = Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(arguments, i); + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, 'length').length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); } - return results; + return result; }; // Converts lists into objects. Pass either a single array of `[key, value]` // pairs, or two parallel arrays of the same length -- one of keys, and one of // the corresponding values. _.object = function(list, values) { - if (list == null) return {}; var result = {}; - for (var i = 0, length = list.length; i < length; i++) { + for (var i = 0, length = list && list.length; i < length; i++) { if (values) { result[list[i]] = values[i]; } else { @@ -590,30 +608,63 @@ // If the array is large and already in sort order, pass `true` // for **isSorted** to use binary search. _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, length = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } + var i = 0, length = array && array.length; + if (typeof isSorted == 'number') { + i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; + } else if (isSorted && length) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (item !== item) { + return _.findIndex(slice.call(array, i), _.isNaN); } for (; i < length; i++) if (array[i] === item) return i; return -1; }; _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var idx = array.length; + var idx = array ? array.length : 0; if (typeof from == 'number') { idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1); } + if (item !== item) { + return _.findLastIndex(slice.call(array, 0, idx), _.isNaN); + } while (--idx >= 0) if (array[idx] === item) return idx; return -1; }; + // Generator function to create the findIndex and findLastIndex functions + function createIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = array != null && array.length; + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createIndexFinder(1); + + _.findLastIndex = createIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = array.length; + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + // Generate an integer Array containing an arithmetic progression. A port of // the native Python `range()` function. See // [the Python documentation](http://docs.python.org/library/functions.html#range). @@ -637,25 +688,25 @@ // Function (ahem) Functions // ------------------ - // Reusable constructor function for prototype setting. - var Ctor = function(){}; + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; // Create a function bound to a given object (assigning `this`, and arguments, // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if // available. _.bind = function(func, context) { - var args, bound; if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - args = slice.call(arguments, 2); - bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - Ctor.prototype = func.prototype; - var self = new Ctor; - Ctor.prototype = null; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (_.isObject(result)) return result; - return self; + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); }; return bound; }; @@ -665,15 +716,16 @@ // as a placeholder, allowing any combination of arguments to be pre-filled. _.partial = function(func) { var boundArgs = slice.call(arguments, 1); - return function() { - var position = 0; - var args = boundArgs.slice(); - for (var i = 0, length = args.length; i < length; i++) { - if (args[i] === _) args[i] = arguments[position++]; + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; } while (position < arguments.length) args.push(arguments[position++]); - return func.apply(this, args); + return executeBound(func, bound, this, this, args); }; + return bound; }; // Bind a number of an object's methods to that object. Remaining arguments @@ -693,7 +745,7 @@ _.memoize = function(func, hasher) { var memoize = function(key) { var cache = memoize.cache; - var address = hasher ? hasher.apply(this, arguments) : key; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); return cache[address]; }; @@ -712,9 +764,7 @@ // Defers a function, scheduling it to run after the current call stack has // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; + _.defer = _.partial(_.delay, _, 1); // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. Normally, the throttled function will run @@ -739,8 +789,10 @@ context = this; args = arguments; if (remaining <= 0 || remaining > wait) { - clearTimeout(timeout); - timeout = null; + if (timeout) { + clearTimeout(timeout); + timeout = null; + } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; @@ -761,7 +813,7 @@ var later = function() { var last = _.now() - timestamp; - if (last < wait && last > 0) { + if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; @@ -814,7 +866,7 @@ }; }; - // Returns a function that will only be executed after being called N times. + // Returns a function that will only be executed on and after the Nth call. _.after = function(times, func) { return function() { if (--times < 1) { @@ -823,15 +875,14 @@ }; }; - // Returns a function that will only be executed before being called N times. + // Returns a function that will only be executed up to (but not including) the Nth call. _.before = function(times, func) { var memo; return function() { if (--times > 0) { memo = func.apply(this, arguments); - } else { - func = null; } + if (times <= 1) func = null; return memo; }; }; @@ -843,13 +894,47 @@ // Object Functions // ---------------- - // Retrieve the names of an object's properties. + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. // Delegates to **ECMAScript 5**'s native `Object.keys` _.keys = function(obj) { if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; }; @@ -864,6 +949,21 @@ return values; }; + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + // Convert an object into a list of `[key, value]` pairs. _.pairs = function(obj) { var keys = _.keys(obj); @@ -896,37 +996,38 @@ }; // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - if (!_.isObject(obj)) return obj; - var source, prop; - for (var i = 1, length = arguments.length; i < length; i++) { - source = arguments[i]; - for (prop in source) { - if (hasOwnProperty.call(source, prop)) { - obj[prop] = source[prop]; - } - } + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; } - return obj; }; // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj, iteratee, context) { - var result = {}, key; + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; if (obj == null) return result; - if (_.isFunction(iteratee)) { - iteratee = createCallback(iteratee, context); - for (key in obj) { - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); } else { - var keys = concat.apply([], slice.call(arguments, 1)); - obj = new Object(obj); - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (key in obj) result[key] = obj[key]; - } + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; } return result; }; @@ -936,7 +1037,7 @@ if (_.isFunction(iteratee)) { iteratee = _.negate(iteratee); } else { - var keys = _.map(concat.apply([], slice.call(arguments, 1)), String); + var keys = _.map(flatten(arguments, false, false, 1), String); iteratee = function(value, key) { return !_.contains(keys, key); }; @@ -945,16 +1046,7 @@ }; // Fill in a given object with default properties. - _.defaults = function(obj) { - if (!_.isObject(obj)) return obj; - for (var i = 1, length = arguments.length; i < length; i++) { - var source = arguments[i]; - for (var prop in source) { - if (obj[prop] === void 0) obj[prop] = source[prop]; - } - } - return obj; - }; + _.defaults = createAssigner(_.allKeys, true); // Create a (shallow-cloned) duplicate of an object. _.clone = function(obj) { @@ -970,6 +1062,19 @@ return obj; }; + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + // Internal recursive comparison function for `isEqual`. var eq = function(a, b, aStack, bStack) { // Identical objects are equal. `0 === -0`, but they aren't identical. @@ -1004,74 +1109,76 @@ // of `NaN` are not equivalent. return +a === +b; } - if (typeof a != 'object' || typeof b != 'object') return false; + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } // Assume equality for cyclic structures. The algorithm for detecting cyclic // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; var length = aStack.length; while (length--) { // Linear search. Performance is inversely proportional to the number of // unique nested structures. if (aStack[length] === a) return bStack[length] === b; } - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if ( - aCtor !== bCtor && - // Handle Object.create(x) cases - 'constructor' in a && 'constructor' in b && - !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - ) { - return false; - } + // Add the first object to the stack of traversed objects. aStack.push(a); bStack.push(b); - var size, result; + // Recursively compare objects and arrays. - if (className === '[object Array]') { + if (areArrays) { // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size === b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; } } else { // Deep compare objects. var keys = _.keys(a), key; - size = keys.length; + length = keys.length; // Ensure that both objects contain the same number of properties before comparing deep equality. - result = _.keys(b).length === size; - if (result) { - while (size--) { - // Deep compare each member - key = keys[size]; - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; } } // Remove the first object from the stack of traversed objects. aStack.pop(); bStack.pop(); - return result; + return true; }; // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { - return eq(a, b, [], []); + return eq(a, b); }; // Is a given array, string, or object empty? // An "empty" object has no enumerable own-properties. _.isEmpty = function(obj) { if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; }; // Is a given value a DOM element? @@ -1091,14 +1198,14 @@ return type === 'function' || type === 'object' && !!obj; }; - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { _['is' + name] = function(obj) { return toString.call(obj) === '[object ' + name + ']'; }; }); - // Define a fallback version of the method in browsers (ahem, IE), where + // Define a fallback version of the method in browsers (ahem, IE < 9), where // there isn't any inspectable "Arguments" type. if (!_.isArguments(arguments)) { _.isArguments = function(obj) { @@ -1106,8 +1213,9 @@ }; } - // Optimize `isFunction` if appropriate. Work around an IE 11 bug. - if (typeof /./ !== 'function') { + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { _.isFunction = function(obj) { return typeof obj == 'function' || false; }; @@ -1159,6 +1267,7 @@ return value; }; + // Predicate-generating functions. Often useful outside of Underscore. _.constant = function(value) { return function() { return value; @@ -1169,28 +1278,30 @@ _.property = function(key) { return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { return obj[key]; }; }; - // Returns a predicate for checking whether an object has a given set of `key:value` pairs. - _.matches = function(attrs) { - var pairs = _.pairs(attrs), length = pairs.length; + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); return function(obj) { - if (obj == null) return !length; - obj = new Object(obj); - for (var i = 0; i < length; i++) { - var pair = pairs[i], key = pair[0]; - if (pair[1] !== obj[key] || !(key in obj)) return false; - } - return true; + return _.isMatch(obj, attrs); }; }; // Run a function **n** times. _.times = function(n, iteratee, context) { var accum = Array(Math.max(0, n)); - iteratee = createCallback(iteratee, context, 1); + iteratee = optimizeCb(iteratee, context, 1); for (var i = 0; i < n; i++) accum[i] = iteratee(i); return accum; }; @@ -1239,10 +1350,12 @@ // If the value of the named `property` is a function then invoke it with the // `object` as context; otherwise, return it. - _.result = function(object, property) { - if (object == null) return void 0; - var value = object[property]; - return _.isFunction(value) ? object[property]() : value; + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; }; // Generate a unique integer id (unique within the entire client session). @@ -1357,8 +1470,8 @@ // underscore functions. Wrapped objects may be chained. // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; }; // Add your own custom functions to the Underscore object. @@ -1368,7 +1481,7 @@ _.prototype[name] = function() { var args = [this._wrapped]; push.apply(args, arguments); - return result.call(this, func.apply(_, args)); + return result(this, func.apply(_, args)); }; }); }; @@ -1383,7 +1496,7 @@ var obj = this._wrapped; method.apply(obj, arguments); if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); + return result(this, obj); }; }); @@ -1391,7 +1504,7 @@ _.each(['concat', 'join', 'slice'], function(name) { var method = ArrayProto[name]; _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); + return result(this, method.apply(this._wrapped, arguments)); }; }); @@ -1400,6 +1513,14 @@ return this._wrapped; }; + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + // AMD registration happens at the end for compatibility with AMD loaders // that may not enforce next-turn semantics on modules. Even though general // practice for AMD registration is to be anonymous, underscore registers