Compare commits

..

44 Commits
0.2.0 ... 0.2.2

Author SHA1 Message Date
John-David Dalton
548e9cac26 Update documentation.
Former-commit-id: 6d1aa50111b34e0548f96a55fe3dcca0b7e91b5e
2012-05-30 03:52:59 -04:00
John-David Dalton
0d2a1641c9 Add percent faster than to pref.js results and link to benchmarks in README.md.
Former-commit-id: 1c5fb820fe070599aba780f1765538d408105af3
2012-05-30 03:51:44 -04:00
John-David Dalton
a67281f8e7 Cleanup README.md.
Former-commit-id: b0d0a22ff427b6a5754e2850e2a420e764a1eb39
2012-05-30 01:48:28 -04:00
John-David Dalton
281475e6ef Bump to v0.2.2.
Former-commit-id: c4516d1e2dd2ab4359233121a7f86c356425cebf
2012-05-30 00:21:06 -04:00
John-David Dalton
a5712fc873 Cleanup build.js and fix regression in minified build. [closes #19]
Former-commit-id: 3b455cb277fa8c3fc70efca7b54c6746cde2ea6b
2012-05-29 15:52:02 -04:00
John-David Dalton
205ded45e2 Update submodules, minified build, and documentation.
Former-commit-id: 526a3d4e7b68da2072163a656566ff777b591b2d
2012-05-29 10:18:32 -04:00
John-David Dalton
8ef039b9db Update unit test with _.templateSettings.variable change.
Former-commit-id: e29718c70b0b0bcfeaf54909a32366d12663984d
2012-05-29 10:17:55 -04:00
John-David Dalton
3d2428b278 Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: a2b22208dc08b404bd1fbdde9f1d05253c0fc047
2012-05-29 10:14:54 -04:00
John-David Dalton
35d5704e3f Change the default value of _.templateSettings.variable to obj for Underscore.js compatibility. [closes #16]
Former-commit-id: da91e5c881e6b3f9e2108cc231e57c023884b251
2012-05-29 10:14:40 -04:00
Mathias Bynens
c1860d30d6 Optimize escape() by not needlessly escaping the / character
Ref. #18.


Former-commit-id: 82a29019daa15c83cb2159685ca5d575265cd902
2012-05-29 16:11:08 +02:00
Mathias Bynens
e0fba5cb51 Fix typo in build script
Former-commit-id: 1f5327ea167ba88c00c6fcff5bbad3d64be6049b
2012-05-29 14:40:03 +03:00
John-David Dalton
570ba189ed Update docs and minified build.
Former-commit-id: d07b191ef424d6dce31e690e4af5293eb1525313
2012-05-26 03:40:27 -04:00
John-David Dalton
e335e0fd72 Add mobile build support. [closes #14]
Former-commit-id: a73e3ea444f04027e28beeb9d007a19c169c4fa9
2012-05-26 03:40:06 -04:00
John-David Dalton
74a2d8dcb1 Update Backbone and Underscore submodules.
Former-commit-id: 13de1bae42bbbae7ca138bc5d26b83fd66367343
2012-05-26 00:12:43 -04:00
John-David Dalton
43ea0c9072 Reword unit test and add entry to README.md.
Former-commit-id: e5d68317bb8f2688c256de096c58e1b49014a68c
2012-05-26 00:09:41 -04:00
John-David Dalton
dde3eb2e36 Update _.find dependencies.
Former-commit-id: 88e6c8dec2cf62d348bc570c0f3f9bfa23a9dc5c
2012-05-26 00:09:11 -04:00
John-David Dalton
2008bf90af Tweak _.find to avoid using _.identity and add benchmark.
Former-commit-id: a881f90d00828ed6af5b2b0bc80c9ae6e2cb2da8
2012-05-26 00:07:50 -04:00
John-David Dalton
06ffa93bd0 Update minified build and docs.
Former-commit-id: f9c076e5254c563c714bccf7cd5d65b6716cd427
2012-05-25 15:46:29 -04:00
John-David Dalton
5da03cac79 Add pseudo private property in preparation for mobile builds.
Former-commit-id: d5812d968b7694c9778f1be7efa8d05f95789ec8
2012-05-25 15:16:39 -04:00
John-David Dalton
8a5eb89aa8 Ensure _.find returns undefinedwhen a value cannot be found. [closes #15]
Former-commit-id: e6dc89f98a1df81e1b1d67c5e8f5725e4df3bc5a
2012-05-25 15:15:16 -04:00
John-David Dalton
f81ede2fd6 Update changelog with intersect removal.
Former-commit-id: 5902c720c1403b856ac213e293619c31ea6834f5
2012-05-24 18:02:35 -04:00
John-David Dalton
6f7df67ded Cleanup README.md.
Former-commit-id: 6ad747a8ae56f32fd558bd141af6fe95847569ad
2012-05-24 17:50:20 -04:00
John-David Dalton
bb9ad69219 Bump to v0.2.1.
Former-commit-id: d433d39ac7269479f1b9ac3803e62c5021f41e11
2012-05-24 17:08:26 -04:00
John-David Dalton
8f7667a524 Simplify _.max, _.min, and _.bind.
Former-commit-id: 1da0b013d0c47748d757e90248eebe9ed51918ae
2012-05-24 10:02:32 -04:00
John-David Dalton
86e125a6f3 Update minified build and docs.
Former-commit-id: 8c96c3812064f93d404e6d6dda68ab7a865d4228
2012-05-24 02:24:40 -04:00
John-David Dalton
8b3ba13ff0 Cleanup perf.js.
Former-commit-id: 8799b7d384cc48bc1c8ea3289aa12e021be2b97b
2012-05-24 02:23:55 -04:00
John-David Dalton
82f062caf2 Sync with Underscore.
Former-commit-id: 2e3aacd53fef6d22d830dbc2d6c220808aea8739
2012-05-24 02:06:10 -04:00
John-David Dalton
67303eb9fb Update Backbone and Underscore submodules.
Former-commit-id: 43178330e273531286982e34acf96dadf9586f03
2012-05-24 01:43:54 -04:00
John-David Dalton
af3ded68c4 Cleanup _.bind.
Former-commit-id: d974cdfa52c3f6c175e57f0970380bcc9276c35d
2012-05-24 01:40:24 -04:00
John-David Dalton
b94eb44e18 Update minified build and docs.
Former-commit-id: 525d891914a86b1f7167c9dd82b9deaaad453058
2012-05-24 01:30:48 -04:00
John-David Dalton
c62b24b024 Make _.bind follow ES5 spec so it will work with a common Backbone pattern. [closes #11]
Former-commit-id: 8d5e399ca9727a32604601f81fffd9134104c8f4
2012-05-24 01:25:08 -04:00
John-David Dalton
baa37450cc Tweak export order for r.js.
Former-commit-id: 81f8f3feae9228e99978710c0193a9d26bb9b519
2012-05-23 17:06:21 -04:00
John-David Dalton
231fd46cd2 Ensure applet is hidden in perf/index.html.
Former-commit-id: ee23b966eca9148bbecd8d0826d954e755d232fe
2012-05-23 17:00:49 -04:00
John-David Dalton
b2728d9902 Update docs.
Former-commit-id: 462a64eeb8f8afb0951d8449f0f7b766abbcf5cc
2012-05-23 14:52:15 -04:00
John-David Dalton
451a33f526 Add _.difference, _.pick, and _.union benchmarks.
Former-commit-id: 1dd1e577520dfc1a69876eeccadce871f1f05916
2012-05-23 14:30:45 -04:00
John-David Dalton
3670bce918 Add _.flatten test to ensure consistent behavior with sparse arrays.
Former-commit-id: 5505f4d0542596e4c6469aa038fa1bfecaa79800
2012-05-23 14:28:51 -04:00
John-David Dalton
afb041b23c Update docs and minified build.
Former-commit-id: 8ece30dc91c7cd9fe9f936fdf09e6d673566eaef
2012-05-23 02:20:25 -04:00
John-David Dalton
5315058e2d Simplify _.flatten and add benchmarks.
Former-commit-id: f541328bf680a75abea68bce813820def375f4a0
2012-05-23 02:19:35 -04:00
John-David Dalton
26d9cc972e Add unit test to test to ensure _.groupBy only adds elements to own, not inherited, properties of the result object.
Former-commit-id: 61dcdd0f6172db66d62e97873c1bc3053e339342
2012-05-23 01:25:34 -04:00
John-David Dalton
52ae87812e Update docs and minified build.
Former-commit-id: f019b90d5e866bf2a6da1c003001d0e9345bb0b1
2012-05-23 01:01:35 -04:00
John-David Dalton
f8af24b383 Remove unneeded variable references.
Former-commit-id: ab2f5f4408db25dc63b5d85b4adf156f9f978711
2012-05-23 00:52:39 -04:00
John-David Dalton
b38947146e Move _.groupBy and _.size to the "Objects" category and shuffle method order to avoid extra private variables.
Former-commit-id: 8dc89136a3bf2ed94f594f5c1c1f97a0dd7291c4
2012-05-23 00:43:23 -04:00
John-David Dalton
5c48abff4b Add links to relevant sections in the description.
Former-commit-id: da9e65fadae73792cfb2ec885318bc073d4468c3
2012-05-22 13:10:43 -04:00
John-David Dalton
3994c7fc2b Update docdown submodule and README.md.
Former-commit-id: 745eccb03a7eed1f3f2ef696002c57d6fcc44d25
2012-05-22 13:01:14 -04:00
15 changed files with 908 additions and 895 deletions

View File

@@ -1,12 +1,12 @@
# Lo-Dash <sup>v0.2.0</sup>
# Lo-Dash <sup>v0.2.2</sup>
A drop-in replacement for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), that delivers [performance improvements](http://jsperf.com/lodash-underscore#filterby=family), bug fixes, and additional features.
A drop-in replacement for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), that delivers [performance improvements](http://jsperf.com/lodash-underscore#filterby=family), [bug fixes](https://github.com/bestiejs/lodash#closed-underscorejs-issues), and [additional features](https://github.com/bestiejs/lodash#features).
Lo-Dashs performance is gained by avoiding slower native methods, instead opting for simplified non-ES5 compliant methods optimized for common usage, and by leveraging function compilation to reduce the number of overall function calls.
## Dive in
Weve got [API docs](http://lodash.com/docs) and [unit tests](http://lodash.com/tests).
Weve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/lodash/wiki/Roadmap).
@@ -20,12 +20,12 @@ For more information check out these screencasts over Lo-Dash:
## Features
* AMD loader support
* [_.bind](http://lodash.com/docs#_bindfunc--arg1-arg2-) supports *"lazy"* binding
* [_.debounce](http://lodash.com/docs#_debouncefunc-wait-immediate)ed functions match [_.throttle](http://lodash.com/docs#_throttlefunc-wait)ed functions return value behavior
* [_.forEach](http://lodash.com/docs#_foreachcollection-callback--thisarg) is chainable
* [_.groupBy](http://lodash.com/docs#_groupbycollection-callback--thisarg) accepts a third `thisArg` argument
* [_.partial](http://lodash.com/docs#_partialfunc--arg1-arg2-) for more functional fun
* [_.size](http://lodash.com/docs#_sizecollection) returns the `length` of string values
* [_.bind](http://lodash.com/docs#bind) supports *"lazy"* binding
* [_.debounce](http://lodash.com/docs#debounce)ed functions match [_.throttle](http://lodash.com/docs#throttle)ed functions return value behavior
* [_.forEach](http://lodash.com/docs#forEach) is chainable
* [_.groupBy](http://lodash.com/docs#groupBy) accepts a third, `thisArg`, argument
* [_.partial](http://lodash.com/docs#partial) for more functional fun
* [_.size](http://lodash.com/docs#size) supports returning the `length` of string values
## Support
@@ -36,18 +36,26 @@ Lo-Dash has been tested in at least Chrome 5-19, Firefox 1.5-12, IE 6-9, Opera 9
Custom builds make it easy to create lightweight versions of Lo-Dash containing only the methods you need.
We handle all the method dependency and alias mapping for you.
Mobile builds, with IE bug fixes and method compilation removed, may be created by using the `mobile` argument.
~~~ bash
node build mobile
~~~
Custom builds may be created in two ways:
1. Use the`include` argument to pass the names of the methods to include in the build.
~~~ bash
node build include=each,filter,map,noConflict
node build include="each, filter, map, noConflict"
node build mobile include=each,filter,map,noConflict
~~~
2. Use the `exclude` argument to pass the names of the methods to exclude from the build.
~~~ bash
node build exclude=isNaN,isUndefined,union,zip
node build exclude="isNaN, isUndefined, union, zip"
node build mobile exclude=isNaN,isUndefined,union,zip
~~~
Custom builds are saved to `lodash.custom.js` and `lodash.custom.min.js`.
@@ -116,14 +124,17 @@ git submodule update --init
## Closed Underscore.js issues
* Fix Firefox, IE, Opera, and Safari object iteration bugs [#376](https://github.com/documentcloud/underscore/issues/376)
* Handle arrays with `undefined` values correctly in IE < 9 [#601](https://github.com/documentcloud/underscore/issues/601)
* Methods should work on pages with incorrectly shimmed native methods [#7](https://github.com/documentcloud/underscore/issues/7)
* Register as AMD module, but still export to global [#431](https://github.com/documentcloud/underscore/pull/431)
* `_.forEach` should be chainable [#142](https://github.com/documentcloud/underscore/issues/142)
* `_isNaN(new Number(NaN))` should return `true`
* `_.reduceRight` should pass correct callback arguments when iterating objects
* `_.size` should return the `length` of string values
* Ensure `_(...)` returns passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L95-98)]
* Ensure `_.groupBy` adds values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L229-236)]
* Ensure `_.throttle` works when called in tight loops [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L436-446)]
* Fix Firefox, IE, Opera, and Safari object iteration bugs [[#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L152-172), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L206-213), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L255-257), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L265-267), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L285-292), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L386-388)]
* Handle arrays with `undefined` values correctly in IE < 9 [[#601](https://github.com/documentcloud/underscore/issues/601)]
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L77-83)]
* Register as AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L61-75)]
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L74-77)]
* `_isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L95-99)]
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L106-116)]
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L121-127)]
## Optimized methods <sup>(50+)</sup>
@@ -146,7 +157,7 @@ git submodule update --init
* `_.functions`, `_.methods`
* `_.groupBy`
* `_.indexOf`
* `_.intersection`, `_.intersect`
* `_.intersection`
* `_.invoke`
* `_.isEmpty`
* `_.isEqual`
@@ -182,6 +193,22 @@ git submodule update --init
## Changelog
### <sup>v0.2.2</sup>
* Added mobile build option
* Ensured `_.find` returns `undefined` for unmatched values
* Ensured `_.templateSettings.variable` is compatible with Underscore.js
* Optimized `_.escape`
* Reduced dependencies in `_.find`
### <sup>v0.2.1</sup>
* Adjusted the Lo-Dash export order for r.js
* Ensured `_.groupBy` values are added to own, not inherited, properties
* Made `_.bind` follow ES5 spec to support a popular Backbone.js pattern
* Removed the alias `intersect`
* Simplified `_.bind`, `_.flatten`, `_.groupBy`, `_.max`, and `_.min`
### <sup>v0.2.0</sup>
* Added custom build options
@@ -189,11 +216,13 @@ git submodule update --init
* Added *"lazy bind"* support to `_.bind`
* Added native method overwrite detection to avoid bad native shims
* Added support for more AMD build optimizers and aliasing as the *"underscore"* module
* Added `thisArg` to `_.groupBy`
* Added `thisArg` argument to `_.groupBy`
* Added whitespace to compiled strings
* Added `_.partial`
* Added `_.partial` method
* Commented the `iterationFactory` options object
* Ensured `_(...)` returns passed wrapper instances
* Ensured `_.max` and `_.min` support extremely large arrays
* Ensured `_.throttle` works in tight loops
* Fixed IE < 9 `[DontEnum]` bug and Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1s prototype property iteration bug
* Inlined `_.isFunction` calls.
* Made `_.debounce`ed functions match `_.throttle`ed functions return value behavior

163
build.js
View File

@@ -10,8 +10,8 @@
var lodash = require(path.join(__dirname, 'lodash')),
minify = require(path.join(__dirname, 'build', 'minify'));
/** Flag used to specify a custom build */
var isCustom = false;
/** Flag used to specify a mobile build */
var isMobile = process.argv.indexOf('mobile') > -1;
/** Shortcut used to convert array-like objects to arrays */
var slice = [].slice;
@@ -31,7 +31,6 @@
'head': 'first',
'include': 'contains',
'inject': 'reduce',
'intersect': 'intersection',
'methods': 'functions',
'select': 'filter',
'tail': 'rest',
@@ -48,7 +47,6 @@
'first': ['head', 'take'],
'forEach': ['each'],
'functions': ['methods'],
'intersection': ['intersect'],
'map': ['collect'],
'reduce': ['foldl', 'inject'],
'reduceRight': ['foldr'],
@@ -77,7 +75,7 @@
'every': ['bind', 'createIterator', 'identity'],
'extend': ['createIterator'],
'filter': ['bind', 'createIterator', 'identity'],
'find': ['createIterator'],
'find': ['bind', 'createIterator'],
'first': [],
'flatten': ['isArray'],
'forEach': ['bind', 'createIterator'],
@@ -143,6 +141,20 @@
'zip': ['max', 'pluck']
};
/** Names of methods to filter for the build */
var filterMethods = Object.keys(dependencyMap);
/** Used to specify if `filterMethods` should be used for exclusion or inclusion */
var filterType = process.argv.reduce(function(result, value) {
if (!result) {
var pair = value.match(/^(exclude|include)=(.*)$/);
if (pair) {
filterMethods = lodash.intersection(filterMethods, pair[2].split(/, */).map(getRealName));
return pair[1];
}
}
}, '');
/*--------------------------------------------------------------------------*/
/**
@@ -330,56 +342,30 @@
return removeFromCreateIterator(source, varName);
}
/*--------------------------------------------------------------------------*/
// inline `iteratorTemplate`
(function() {
var iteratorTemplate = lodash._iteratorTemplate,
code = /^function[^{]+{([\s\S]+?)}$/.exec(iteratorTemplate)[1];
// remove whitespace from template
code = code.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |var |\\\\n|\\n|\s+/g, function(match) {
/**
* Removes non-syntax critical whitespace from a string.
*
* @private
* @param {String} source The source to process.
* @returns {String} Returns the source with whitespace removed.
*/
function removeWhitespace(source) {
return source.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |var |\\\\n|\\n|\s+/g, function(match) {
return match == false || match == '\\n' ? '' : match;
});
// remove unnecessary code
code = code
.replace(/\|\|\{\}|,__t,__j=Array.prototype.join|function print[^}]+}|\+''/g, '')
.replace(/(\{);|;(\})/g, '$1$2')
.replace(/\(\(__t=\(([^)]+)\)\)==null\?'':__t\)/g, '$1');
// ensure escaped characters are interpreted correctly inside the `Function()` string
code = code.replace(/\\/g, '\\\\');
// add `code` to `Function()`
code = '$1Function(\'object\',\n$2 "' + code + '"\n$2);\n';
// replace `template()` with `Function()`
source = source.replace(/(( +)var iteratorTemplate *= *)([\s\S]+?\n\2.+?);\n/, code);
// remove pseudo private property `_iteratorTemplate`
source = source.replace(/(?:\s*\/\/.*)*\s*lodash\._iteratorTemplate\b.+\n/, '\n');
}());
}
/*--------------------------------------------------------------------------*/
// custom build
process.argv.some(function(arg) {
// exit early if not the "exclude" or "include" command option
var pair = arg.match(/^(exclude|include)=(.*)$/);
if (!pair) {
return false;
(function() {
// exit early if "exclude" or "include" options aren't specified
if (!filterType) {
return;
}
var filterType = pair[1],
filterNames = lodash.intersection(Object.keys(dependencyMap), pair[2].split(/, */).map(getRealName));
// set custom build flag
isCustom = true;
// remove the specified functions and their dependants
if (filterType == 'exclude') {
filterNames.forEach(function(funcName) {
filterMethods.forEach(function(funcName) {
getDependants(funcName).concat(funcName).forEach(function(otherName) {
source = removeFunction(source, otherName);
});
@@ -387,13 +373,13 @@
}
// else remove all but the specified functions and their dependencies
else {
filterNames = lodash.uniq(filterNames.reduce(function(result, funcName) {
filterMethods = lodash.uniq(filterMethods.reduce(function(result, funcName) {
result.push.apply(result, getDependencies(funcName).concat(funcName));
return result;
}, []));
lodash.each(dependencyMap, function(dependencies, otherName) {
if (filterNames.indexOf(otherName) < 0) {
if (filterMethods.indexOf(otherName) < 0) {
source = removeFunction(source, otherName);
}
});
@@ -416,21 +402,28 @@
// remove `templateSettings` assignment
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *lodash\.templateSettings[\s\S]+?};\n/, '');
}
if (isRemoved(source, 'max', 'min')) {
source = removeVar(source, 'argsLimit');
// remove `argsLimit` try-catch
source = source.replace(/\n *try\s*\{[\s\S]+?argsLimit *=[\s\S]+?catch[^}]+}\n/, '');
}
if (isRemoved(source, 'isArray', 'isEmpty', 'isEqual', 'size')) {
source = removeVar(source, 'arrayClass');
}
if (isRemoved(source, 'bind', 'functions', 'groupBy', 'invoke', 'isEqual', 'isFunction', 'result', 'sortBy', 'toArray')) {
source = removeVar(source, 'funcClass');
}
if (isRemoved(source, 'bind')) {
source = removeVar(source, 'nativeBind');
}
if (isRemoved(source, 'isArray')) {
source = removeVar(source, 'nativeIsArray');
}
if (isRemoved(source, 'keys')) {
source = removeVar(source, 'nativeKeys');
}
if (isRemoved(source, 'clone', 'isObject', 'keys')) {
source = removeVar(source, 'objectTypes');
source = removeFromCreateIterator(source, 'objectTypes');
}
if (isRemoved(source, 'bind', 'isArray', 'keys')) {
source = removeVar(source, 'reNative');
}
if (isRemoved(source, 'isEmpty', 'isEqual', 'isString', 'size')) {
source = removeVar(source, 'stringClass');
}
@@ -439,12 +432,70 @@
source = source.replace(/(?:\s*\/\*-+\*\/\s*){2,}/g, function(separators) {
return separators.match(/^\s*/)[0] + separators.slice(separators.lastIndexOf('/*'));
});
}());
return true;
});
/*--------------------------------------------------------------------------*/
if (isMobile) {
// inline functions defined with `createIterator`
lodash.functions(lodash).forEach(function(funcName) {
var reFunc = RegExp('( +var ' + funcName + ' *= *)((?:[a-zA-Z]+ *\\|\\| *)?)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n'),
parts = source.match(reFunc);
// skip if not defined with `createIterator`
if (!parts) {
return;
}
// extract function's code
var code = funcName == 'keys'
? '$1$2' + lodash._createIterator(Function('return ' + parts[3])())
: '$1' + lodash[funcName];
// format code
code = code.replace(/\n(?:.*)/g, function(match) {
match = match.slice(1);
return (match == '}' ? '\n ' : '\n ') + match;
}) + ';\n';
source = source.replace(reFunc, code);
});
// remove `iteratorTemplate`
source = removeVar(source, 'iteratorTemplate');
// remove JScript [[DontEnum]] fix from `isEqual`
source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}\n/, '\n');
// remove IE `shift` and `splice` fix
source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(value.length *=== *0[\s\S]+?\n\1}\n/, '\n');
}
else {
// inline `iteratorTemplate` template
source = source.replace(/(( +)var iteratorTemplate *= *)([\s\S]+?\n\2.+?);\n/, (function() {
// extract `iteratorTemplate` code
var code = /^function[^{]+{([\s\S]+?)}$/.exec(lodash._iteratorTemplate)[1];
code = removeWhitespace(code)
// remove unnecessary code
.replace(/\|\|\{\}|,__t,__j=Array.prototype.join|function print[^}]+}|\+''/g, '')
.replace(/(\{);|;(\})/g, '$1$2')
.replace(/\(\(__t=\(([^)]+)\)\)==null\?'':__t\)/g, '$1')
// ensure escaped characters are interpreted correctly in the string literal
.replace(/\\/g, '\\\\');
// add `code` to `Function()` as a string literal to avoid strict mode
// errors caused by the required with-statement
return '$1Function(\'obj\',\n$2 "' + code + '"\n$2);\n';
}()));
}
// remove pseudo private properties
source = source.replace(/(?:\s*\/\/.*)*\s*lodash\._(?:createIterator|iteratorTemplate)\b.+\n/g, '\n');
/*--------------------------------------------------------------------------*/
// begin the minification process
if (isCustom) {
if (filterType || isMobile) {
fs.writeFileSync(path.join(__dirname, 'lodash.custom.js'), source);
minify(source, 'lodash.custom.min', function(result) {
fs.writeFileSync(path.join(__dirname, 'lodash.custom.min.js'), result);

View File

@@ -8,33 +8,24 @@
/** Used to minify variables embedded in compiled strings */
var compiledVars = [
'accumulator',
'args',
'array',
'arrayClass',
'bind',
'callback',
'className',
'collection',
'concat',
'ctor',
'false',
'funcClass',
'hasOwnProperty',
'identity',
'index',
'indexOf',
'isArray',
'isEmpty',
'isFunc',
'length',
'object',
'objectTypes',
'noaccum',
'prop',
'property',
'result',
'skipProto',
'slice',
'source',
'sourceIndex',
'stringClass',
@@ -71,9 +62,10 @@
/** Used to minify variables and string values to a single character */
var minNames = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
/** Used protect the specified properties from getting minified */
/** Used to protect the specified properties from getting minified */
var propWhitelist = [
'_',
'_chain',
'_wrapped',
'after',
'all',
@@ -119,7 +111,6 @@
'initial',
'inject',
'interpolate',
'intersect',
'intersection',
'invoke',
'isArguments',
@@ -177,7 +168,6 @@
'throttle',
'times',
'toArray',
'toArray',
'union',
'uniq',
'unique',

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
// generate Markdown
$markdown = docdown(array(
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.2.0</sup>',
'title' => 'Lo-Dash <sup>v0.2.2</sup>',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
));

701
lodash.js
View File

@@ -1,5 +1,5 @@
/*!
* Lo-Dash v0.2.0 <http://lodash.com>
* Lo-Dash v0.2.2 <http://lodash.com>
* Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
* Based on Underscore.js 1.3.3, copyright 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
* <http://documentcloud.github.com/underscore>
@@ -12,30 +12,6 @@
var freeExports = typeof exports == 'object' && exports &&
(typeof global == 'object' && global && global == global.global && (window = global), exports);
/**
* Used to detect the JavaScript engine's argument length limit.
*
* The initial value of `argsLimit` is low enough not to cause uncatchable
* errors in Java and avoid locking up older browsers like Safari 3.
*
* Some engines have a limit on the number of arguments functions can accept
* before clipping the argument length or throwing an error.
* https://bugs.webkit.org/show_bug.cgi?id=80797
*
* For example Firefox's limits have been observed to be at least:
* Firefox 2 - 35,535
* Firefox 3.6 - 16,777,215
* Firefox 4-7 - 523,264
* Firefox >= 8 - Throws error
*/
var argsLimit = 5e4;
try {
(function() {
argsLimit = arguments.length;
}).apply(null, Array(argsLimit));
} catch(e) { }
/** Used to escape characters in templates */
var escapes = {
'\\': '\\',
@@ -70,15 +46,6 @@
/** Used to restore the original `_` reference in `noConflict` */
var oldDash = window._;
/** Used to match the "escape" template delimiters */
var reEscapeDelimiter = /<%-([\s\S]+?)%>/g;
/** Used to match the "evaluate" template delimiters */
var reEvaluateDelimiter = /<%([\s\S]+?)%>/g;
/** Used to match the "interpolate" template delimiters */
var reInterpolateDelimiter = /<%=([\s\S]+?)%>/g;
/** Used to detect if a method is native */
var reNative = RegExp('^' + ({}.valueOf + '')
.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&')
@@ -137,6 +104,83 @@
/*--------------------------------------------------------------------------*/
/**
* The `lodash` function.
*
* @name _
* @constructor
* @param {Mixed} value The value to wrap in a `LoDash` instance.
* @returns {Object} Returns a `LoDash` instance.
*/
function lodash(value) {
// allow invoking `lodash` without the `new` operator
return new LoDash(value);
}
/**
* Creates a `LoDash` instance that wraps a value to allow chaining.
*
* @private
* @constructor
* @param {Mixed} value The value to wrap.
*/
function LoDash(value) {
// exit early if already wrapped
if (value && value._wrapped) {
return value;
}
this._wrapped = value;
}
/**
* By default, Lo-Dash uses ERB-style template delimiters, change the
* following template settings to use alternative delimiters.
*
* @static
* @memberOf _
* @type Object
*/
lodash.templateSettings = {
/**
* Used to detect `data` property values to be HTML-escaped.
*
* @static
* @memberOf _.templateSettings
* @type RegExp
*/
'escape': /<%-([\s\S]+?)%>/g,
/**
* Used to detect code to be evaluated.
*
* @static
* @memberOf _.templateSettings
* @type RegExp
*/
'evaluate': /<%([\s\S]+?)%>/g,
/**
* Used to detect `data` property values to inject.
*
* @static
* @memberOf _.templateSettings
* @type RegExp
*/
'interpolate': /<%=([\s\S]+?)%>/g,
/**
* Used to reference the data object in the template text.
*
* @static
* @memberOf _.templateSettings
* @type String
*/
'variable': 'obj'
};
/*--------------------------------------------------------------------------*/
/**
* The template used to create iterator functions.
*
@@ -213,11 +257,7 @@
'<%= bottom %>;\n' +
// finally, return the `result`
'return result'
, null, {
'evaluate': reEvaluateDelimiter,
'interpolate': reInterpolateDelimiter
});
);
/**
* Reusable iterator options shared by
@@ -262,6 +302,11 @@
'inLoop': 'callback(collection[index], index, collection) && result.push(collection[index])'
};
/** Reusable iterator options for `find` and `forEach` */
var forEachIteratorOptions = {
'top': 'if (thisArg) callback = bind(callback, thisArg)'
};
/** Reusable iterator options for `map`, `pluck`, and `values` */
var mapIteratorOptions = {
'init': '',
@@ -278,86 +323,6 @@
/*--------------------------------------------------------------------------*/
/**
* The `lodash` function.
*
* @name _
* @constructor
* @param {Mixed} value The value to wrap in a `LoDash` instance.
* @returns {Object} Returns a `LoDash` instance.
*/
function lodash(value) {
// allow invoking `lodash` without the `new` operator
return new LoDash(value);
}
/**
* Creates a `LoDash` instance that wraps a value to allow chaining.
*
* @private
* @constructor
* @param {Mixed} value The value to wrap.
*/
function LoDash(value) {
// exit early if already wrapped
if (value && value._wrapped) {
return value;
}
this._wrapped = value;
}
/*--------------------------------------------------------------------------*/
/**
* Checks if a `value` is an array.
*
* @static
* @memberOf _
* @category Objects
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
* @example
*
* (function() { return _.isArray(arguments); })();
* // => false
*
* _.isArray([1, 2, 3]);
* // => true
*/
var isArray = nativeIsArray || function(value) {
return toString.call(value) == arrayClass;
};
/**
* Checks if a `value` is empty. Arrays or strings with a length of `0` and
* objects with no enumerable own properties are considered "empty".
*
* @static
* @memberOf _
* @category Objects
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if the `value` is empty, else `false`.
* @example
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty({});
* // => true
*/
var isEmpty = createIterator({
'args': 'value',
'init': 'true',
'top':
'var className = toString.call(value);\n' +
'if (className == arrayClass || className == stringClass) return !value.length',
'inLoop': {
'object': 'return false'
}
});
/*--------------------------------------------------------------------------*/
/**
* Creates compiled iteration functions. The iteration function will be created
* to iterate over only objects if the first argument of `options.args` is
@@ -407,8 +372,8 @@
'exit': '',
'init': '',
'top': '',
'arrayBranch': { 'loopExp': '++index < length' },
'objectBranch': {}
'arrayBranch': { 'beforeLoop': '', 'loopExp': '++index < length' },
'objectBranch': { 'beforeLoop': '' }
};
while (++index < length) {
@@ -443,7 +408,7 @@
data.useHas = data.useHas !== false;
if (!data.exit) {
data.exit = 'if (' + firstArg + ' == null) return result';
data.exit = 'if (!' + firstArg + ') return result';
}
if (firstArg == 'object' || !arrayBranch.inLoop) {
data.arrayBranch = null;
@@ -453,14 +418,14 @@
}
// create the function factory
var factory = Function(
'arrayClass, bind, concat, funcClass, hasOwnProperty, identity, indexOf, ' +
'isArray, isEmpty, objectTypes, slice, stringClass, toString, undefined',
'arrayClass, bind, funcClass, hasOwnProperty, identity, objectTypes, ' +
'stringClass, toString, undefined',
'"use strict"; return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
);
// return the compiled function
return factory(
arrayClass, bind, concat, funcClass, hasOwnProperty, identity, indexOf,
isArray, isEmpty, objectTypes, slice, stringClass, toString
arrayClass, bind, funcClass, hasOwnProperty, identity, objectTypes,
stringClass, toString
);
}
@@ -488,6 +453,15 @@
return '\\' + escapes[match];
}
/**
* A no-operation function.
*
* @private
*/
function noop() {
// no operation performed
}
/**
* Used by `template()` to replace "escape" template delimiters with tokens.
*
@@ -615,7 +589,8 @@
* var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
* // => 2
*/
var find = createIterator(baseIteratorOptions, {
var find = createIterator(baseIteratorOptions, forEachIteratorOptions, {
'init': '',
'inLoop': 'if (callback(collection[index], index, collection)) return collection[index]'
});
@@ -641,46 +616,7 @@
* _([1, 2, 3]).forEach(function(num) { alert(num); }).join(',');
* // => alerts each number in turn and returns '1,2,3'
*/
var forEach = createIterator(baseIteratorOptions, {
'top': 'if (thisArg) callback = bind(callback, thisArg)'
});
/**
* Splits a `collection` into sets, grouped by the result of running each value
* through `callback`. The `callback` is invoked with 3 arguments; for arrays
* they are (value, index, array) and for objects they are (value, key, object).
* The `callback` argument may also be the name of a property to group by.
*
* @static
* @memberOf _
* @category Collections
* @param {Array|Object} collection The collection to iterate over.
* @param {Function|String} callback The function called per iteration or
* property name to group by.
* @param {Mixed} [thisArg] The `this` binding for the callback.
* @returns {Object} Returns an object of grouped values.
* @example
*
* _.groupBy([1.3, 2.1, 2.4], function(num) { return Math.floor(num); });
* // => { '1': [1.3], '2': [2.1, 2.4] }
*
* _.groupBy([1.3, 2.1, 2.4], function(num) { return this.floor(num); }, Math);
* // => { '1': [1.3], '2': [2.1, 2.4] }
*
* _.groupBy(['one', 'two', 'three'], 'length');
* // => { '3': ['one', 'two'], '5': ['three'] }
*/
var groupBy = createIterator(baseIteratorOptions, {
'init': '{}',
'top':
'var prop, isFunc = toString.call(callback) == funcClass;\n' +
'if (isFunc && thisArg) callback = bind(callback, thisArg)',
'inLoop':
'prop = isFunc\n' +
' ? callback(collection[index], index, collection)\n' +
' : collection[index][callback];\n' +
'(result[prop] || (result[prop] = [])).push(collection[index])'
});
var forEach = createIterator(baseIteratorOptions, forEachIteratorOptions);
/**
* Produces a new array of values by mapping each value in the `collection`
@@ -853,81 +789,6 @@
'inLoop': '!' + filterIteratorOptions.inLoop
});
/**
* Gets the number of values in the `collection` or the `length` of a string value.
*
* @static
* @memberOf _
* @category Collections
* @param {Array|Object} collection The collection inspect.
* @returns {Number} Returns the number of values in the collection.
* @example
*
* _.size([1, 2]);
* // => 2
*
* _.size({ 'one': 1, 'two': 2, 'three': 3 });
* // => 3
*
* _.size('curly');
* // => 5
*/
function size(collection) {
var className = toString.call(collection);
return className == arrayClass || className == stringClass
? collection.length
: keys(collection).length;
}
/**
* Produces a new sorted array, ranked in ascending order by the results of
* running each value of a `collection` through `callback`. The `callback` is
* invoked with 3 arguments; for arrays they are (value, index, array) and for
* objects they are (value, key, object). The `callback` argument may also be
* the name of a property to sort by (e.g. 'length').
*
* @static
* @memberOf _
* @category Collections
* @param {Array|Object} collection The collection to iterate over.
* @param {Function|String} callback The function called per iteration or
* property name to sort by.
* @param {Mixed} [thisArg] The `this` binding for the callback.
* @returns {Array} Returns a new array of sorted values.
* @example
*
* _.sortBy([1, 2, 3, 4, 5, 6], function(num) { return Math.sin(num); });
* // => [5, 4, 6, 3, 1, 2]
*
* _.sortBy([1, 2, 3, 4, 5, 6], function(num) { return this.sin(num); }, Math);
* // => [5, 4, 6, 3, 1, 2]
*/
function sortBy(collection, callback, thisArg) {
if (toString.call(callback) != funcClass) {
var prop = callback;
callback = function(collection) { return collection[prop]; };
} else if (thisArg) {
callback = bind(callback, thisArg);
}
return pluck(map(collection, function(value, index) {
return {
'criteria': callback(value, index, collection),
'value': value
};
}).sort(function(left, right) {
var a = left.criteria,
b = right.criteria;
if (a === undefined) {
return 1;
}
if (b === undefined) {
return -1;
}
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
}
/**
* Checks if the `callback` returns a truthy value for **any** element of a
* `collection`. The function returns as soon as it finds passing value, and
@@ -1104,9 +965,6 @@
* // => [1, 2, 3, [[4]]];
*/
function flatten(array, shallow) {
if (shallow) {
return concat.apply(ArrayProto, array);
}
var value,
index = -1,
length = array.length,
@@ -1115,7 +973,7 @@
while (++index < length) {
value = array[index];
if (isArray(value)) {
push.apply(result, flatten(value));
push.apply(result, shallow ? value : flatten(value));
} else {
result.push(value);
}
@@ -1123,6 +981,99 @@
return result;
}
/**
* Splits a `collection` into sets, grouped by the result of running each value
* through `callback`. The `callback` is invoked with 3 arguments;
* (value, index, array). The `callback` argument may also be the name of a
* property to group by.
*
* @static
* @memberOf _
* @category Arrays
* @param {Array} array The array to iterate over.
* @param {Function|String} callback The function called per iteration or
* property name to group by.
* @param {Mixed} [thisArg] The `this` binding for the callback.
* @returns {Object} Returns an object of grouped values.
* @example
*
* _.groupBy([1.3, 2.1, 2.4], function(num) { return Math.floor(num); });
* // => { '1': [1.3], '2': [2.1, 2.4] }
*
* _.groupBy([1.3, 2.1, 2.4], function(num) { return this.floor(num); }, Math);
* // => { '1': [1.3], '2': [2.1, 2.4] }
*
* _.groupBy(['one', 'two', 'three'], 'length');
* // => { '3': ['one', 'two'], '5': ['three'] }
*/
function groupBy(array, callback, thisArg) {
var prop,
value,
index = -1,
isFunc = toString.call(callback) == funcClass,
length = array.length,
result = {};
if (isFunc && thisArg) {
callback = bind(callback, thisArg);
}
while (++index < length) {
value = array[index];
prop = isFunc ? callback(value, index, array) : value[callback];
(hasOwnProperty.call(result, prop) ? result[prop] : result[prop] = []).push(value);
}
return result
}
/**
* Produces a new sorted array, ranked in ascending order by the results of
* running each value of a `collection` through `callback`. The `callback` is
* invoked with 3 arguments; for arrays they are (value, index, array) and for
* objects they are (value, key, object). The `callback` argument may also be
* the name of a property to sort by (e.g. 'length').
*
* @static
* @memberOf _
* @category Arrays
* @param {Array} array The array to iterate over.
* @param {Function|String} callback The function called per iteration or
* property name to sort by.
* @param {Mixed} [thisArg] The `this` binding for the callback.
* @returns {Array} Returns a new array of sorted values.
* @example
*
* _.sortBy([1, 2, 3, 4, 5, 6], function(num) { return Math.sin(num); });
* // => [5, 4, 6, 3, 1, 2]
*
* _.sortBy([1, 2, 3, 4, 5, 6], function(num) { return this.sin(num); }, Math);
* // => [5, 4, 6, 3, 1, 2]
*/
function sortBy(array, callback, thisArg) {
if (toString.call(callback) != funcClass) {
var prop = callback;
callback = function(array) { return array[prop]; };
} else if (thisArg) {
callback = bind(callback, thisArg);
}
return pluck(map(array, function(value, index) {
return {
'criteria': callback(value, index, array),
'value': value
};
}).sort(function(left, right) {
var a = left.criteria,
b = right.criteria;
if (a === undefined) {
return 1;
}
if (b === undefined) {
return -1;
}
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
}
/**
* Gets the index at which the first occurrence of `value` is found using
* strict equality for comparisons, i.e. `===`. If the `array` is already
@@ -1183,7 +1134,6 @@
*
* @static
* @memberOf _
* @alias intersect
* @category Arrays
* @param {Array} [array1, array2, ...] Arrays to process.
* @returns {Array} Returns a new array of unique values, in order, that are
@@ -1321,22 +1271,18 @@
result = computed;
if (!callback) {
// fast path for arrays of numbers
if (array[0] === +array[0] && length <= argsLimit) {
// some JavaScript engines have a limit on the number of arguments functions
// can accept before clipping the argument length or throwing an error
try {
return Math.max.apply(Math, array);
} catch(e) { }
while (++index < length) {
if (array[index] > result) {
result = array[index];
}
}
if (!array.length) {
return result;
}
} else if (thisArg) {
return result;
}
if (thisArg) {
callback = bind(callback, thisArg);
}
while (++index < length) {
current = callback ? callback(array[index], index, array) : array[index];
current = callback(array[index], index, array);
if (current > computed) {
computed = current;
result = array[index];
@@ -1371,19 +1317,18 @@
result = computed;
if (!callback) {
if (array[0] === +array[0] && length <= argsLimit) {
try {
return Math.min.apply(Math, array);
} catch(e) { }
while (++index < length) {
if (array[index] < result) {
result = array[index];
}
}
if (!array.length) {
return result;
}
} else if (thisArg) {
return result;
}
if (thisArg) {
callback = bind(callback, thisArg);
}
while (++index < length) {
current = callback ? callback(array[index], index, array) : array[index];
current = callback(array[index], index, array);
if (current < computed) {
computed = current;
result = array[index];
@@ -1584,9 +1529,6 @@
result = [],
seen = [];
if (length < 3) {
isSorted = true;
}
while (++index < length) {
computed = callback ? callback(array[index]) : array[index];
if (isSorted
@@ -1739,33 +1681,41 @@
}
// use if `Function#bind` is faster
else if (nativeBind) {
func = nativeBind.call.apply(nativeBind, arguments);
return function() {
return arguments.length ? func.apply(undefined, arguments) : func();
};
return nativeBind.call.apply(nativeBind, arguments);
}
var partialArgs = slice.call(arguments, 2),
partialArgsLength = partialArgs.length;
var partialArgs = slice.call(arguments, 2);
return function() {
var result,
args = arguments;
function bound() {
// `Function#bind` spec
// http://es5.github.com/#x15.3.4.5
var args = arguments,
thisBinding = thisArg;
if (!isFunc) {
func = thisArg[methodName];
}
if (partialArgsLength) {
if (args.length) {
partialArgs.length = partialArgsLength;
push.apply(partialArgs, args);
}
args = partialArgs;
if (partialArgs.length) {
args = args.length
? concat.apply(partialArgs, args)
: partialArgs;
}
result = args.length ? func.apply(thisArg, args) : func.call(thisArg);
partialArgs.length = partialArgsLength;
return result;
};
if (this instanceof bound) {
// get `func` instance if `bound` is invoked in a `new` expression
noop.prototype = func.prototype;
thisBinding = new noop;
// mimic the constructor's `return` behavior
// http://es5.github.com/#x13.2.2
var result = func.apply(thisBinding, args);
return objectTypes[typeof result] && result !== null
? result
: thisBinding
}
return func.apply(thisBinding, args);
}
return bound;
}
/**
@@ -2229,6 +2179,26 @@
};
}
/**
* Checks if a `value` is an array.
*
* @static
* @memberOf _
* @category Objects
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
* @example
*
* (function() { return _.isArray(arguments); })();
* // => false
*
* _.isArray([1, 2, 3]);
* // => true
*/
var isArray = nativeIsArray || function(value) {
return toString.call(value) == arrayClass;
};
/**
* Checks if a `value` is a boolean (`true` or `false`) value.
*
@@ -2280,6 +2250,34 @@
return !!(value && value.nodeType == 1);
}
/**
* Checks if a `value` is empty. Arrays or strings with a length of `0` and
* objects with no enumerable own properties are considered "empty".
*
* @static
* @memberOf _
* @category Objects
* @param {Array|Object|String} value The value to inspect.
* @returns {Boolean} Returns `true` if the `value` is empty, else `false`.
* @example
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty({});
* // => true
*/
var isEmpty = createIterator({
'args': 'value',
'init': 'true',
'top':
'var className = toString.call(value);\n' +
'if (className == arrayClass || className == stringClass) return !value.length',
'inLoop': {
'object': 'return false'
}
});
/**
* Performs a deep comparison between two values to determine if they are
* equivalent to each other.
@@ -2669,6 +2667,35 @@
return result;
}
/**
* Gets the size of a `value` by returning `value.length` if `value` is a
* string or array, or the number of own enumerable properties if `value` is
* an object.
*
* @static
* @memberOf _
* @category Objects
* @param {Array|Object|String} value The value to inspect.
* @returns {Number} Returns `value.length` if `value` is a string or array,
* or the number of own enumerable properties if `value` is an object.
* @example
*
* _.size([1, 2]);
* // => 2
*
* _.size({ 'one': 1, 'two': 2, 'three': 3 });
* // => 3
*
* _.size('curly');
* // => 5
*/
function size(value) {
var className = toString.call(value);
return className == arrayClass || className == stringClass
? value.length
: keys(value).length;
}
/**
* Invokes `interceptor` with the `value` as the first argument, and then returns
* `value`. The primary purpose of this method is to "tap into" a method chain,
@@ -2719,12 +2746,11 @@
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;')
.replace(/\//g,'&#x2F;');
.replace(/'/g, '&#x27;');
}
/**
* This function simply returns the first argument passed to it.
* This function returns the first argument passed to it.
* Note: It is used throughout Lo-Dash as a default callback.
*
* @static
@@ -2889,7 +2915,7 @@
options || (options = {});
var result,
defaults = lodash.templateSettings || {},
defaults = lodash.templateSettings,
escapeDelimiter = options.escape,
evaluateDelimiter = options.evaluate,
interpolateDelimiter = options.interpolate,
@@ -2926,7 +2952,7 @@
// if `options.variable` is not specified, add `data` to the top of the scope chain
if (!variable) {
variable = defaults.variable || 'object';
variable = defaults.variable;
text = 'with (' + variable + ' || {}) {\n' + text + '\n}\n';
}
@@ -3063,54 +3089,7 @@
* @memberOf _
* @type String
*/
lodash.VERSION = '0.2.0';
/**
* By default, Lo-Dash uses ERB-style template delimiters, change the
* following template settings to use alternative delimiters.
*
* @static
* @memberOf _
* @type Object
*/
lodash.templateSettings = {
/**
* Used to detect `data` property values to be HTML-escaped.
*
* @static
* @memberOf _.templateSettings
* @type RegExp
*/
'escape': reEscapeDelimiter,
/**
* Used to detect code to be evaluated.
*
* @static
* @memberOf _.templateSettings
* @type RegExp
*/
'evaluate': reEvaluateDelimiter,
/**
* Used to detect `data` property values to inject.
*
* @static
* @memberOf _.templateSettings
* @type RegExp
*/
'interpolate': reInterpolateDelimiter,
/**
* Used to reference the data object in the template text.
*
* @static
* @memberOf _.templateSettings
* @type String
*/
'variable': 'object'
};
lodash.VERSION = '0.2.2';
// assign static methods
lodash.after = after;
@@ -3206,14 +3185,14 @@
lodash.head = first;
lodash.include = contains;
lodash.inject = reduce;
lodash.intersect = intersection;
lodash.methods = functions;
lodash.select = filter;
lodash.tail = rest;
lodash.take = first;
lodash.unique = uniq;
// add pseudo private template used and removed during the build process
// add pseudo privates used and removed during the build process
lodash._createIterator = createIterator;
lodash._iteratorTemplate = iteratorTemplate;
/*--------------------------------------------------------------------------*/
@@ -3275,7 +3254,22 @@
/*--------------------------------------------------------------------------*/
// expose Lo-Dash
if (freeExports) {
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// Expose Lo-Dash to the global object even when an AMD loader is present in
// case Lo-Dash was injected by a third-party script and not intended to be
// loaded as a module. The global assignment can be reverted in the Lo-Dash
// module via its `noConflict()` method.
window._ = lodash;
// define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module
define(function() {
return lodash;
});
}
// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports) {
// in Node.js or RingoJS v0.8.0+
if (typeof module == 'object' && module && module.exports == freeExports) {
(module.exports = lodash)._ = lodash;
@@ -3285,21 +3279,8 @@
freeExports._ = lodash;
}
}
// in a browser or Rhino
else {
// Expose Lo-Dash to the global object even when an AMD loader is present in
// case Lo-Dash was injected by a third-party script and not intended to be
// loaded as a module. The global assignment can be reverted in the Lo-Dash
// module via its `noConflict()` method.
// in a browser or Rhino
window._ = lodash;
// some AMD build optimizers, like r.js, check for specific 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
// referenced as the "underscore" module
define(function() {
return lodash;
});
}
}
}(this));

54
lodash.min.js vendored
View File

@@ -1,30 +1,30 @@
/*!
Lo-Dash 0.2.0 lodash.com/license
Lo-Dash 0.2.2 lodash.com/license
Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE
*/
;(function(u,m){"use strict";function R(a){return"[object Arguments]"==h.call(a)}function c(a){return new p(a)}function p(a){if(a&&a._wrapped)return a;this._wrapped=a}function j(){for(var a,b,d,k=-1,c=arguments.length,f={e:"",f:"",k:"",q:"",c:{m:"++o<t"},o:{}};++k<c;)for(b in a=arguments[k],a)d=(d=a[b])==o?"":d,/d|m|j/.test(b)?("string"==typeof d&&(d={b:d,n:d}),f.c[b]=d.b,f.o[b]=d.n):f[b]=d;a=f.a,b=f.c,d=f.o;var k=/^[^,]+/.exec(a)[0],c=d.m,g=/\S+$/.exec(c||k)[0];f.g=k,f.i=H,f.h="m.call("+g+",o)",f
.l=g,f.p=ba,f.r=f.r!==r,f.f||(f.f="if("+k+"==null)return z");if("u"==k||!b.j)f.c=o;return c||(d.m="o in "+g),Function("d,e,i,l,m,n,p,q,r,v,B,E,H,I,k,J",'"use strict";return function('+a+"){"+ta(f)+"}")(I,v,D,s,t,ca,w,J,da,S,l,K,h,n,r)}function ua(a,b){return x[b]}function va(a){return"\\"+wa[a]}function xa(a,b){var d=x.length;return x[d]="'+((__t=("+b+"))==null?'':_['escape'](__t))+'",T+d}function ya(a,b){var d=x.length;return x[d]="'+((__t=("+b+"))==null?'':__t)+'",T+d}function za(a,b){var d=x.length
;return x[d]="';"+b+";__p+='",T+d}function ea(a,b,d,c){if(!a)return d;var e=a.length,f=3>arguments.length;c&&(b=v(b,c));if(e===+e){for(e&&f&&(d=a[--e]);e--;)d=b(d,a[e],e,a);return d}var g=U(a);for((e=g.length)&&f&&(d=a[g[--e]]);e--;)f=g[e],d=b(d,a[f],f,a);return d}function V(a,b,d){return b==m||d?a[0]:l.call(a,0,b)}function fa(a,b){if(b)return D.apply(z,a);for(var d,c=-1,e=a.length,f=[];++c<e;)d=a[c],J(d)?E.apply(f,fa(d)):f.push(d);return f}function w(a,b,d){var c;if(!a)return-1;if(d)return d=ga(
a,b),a[d]===b?d:-1;d=0;for(c=a.length;d<c;d++)if(a[d]===b)return d;return-1}function ha(a){for(var b,d=-1,c=a.length,e=l.call(arguments,1),f=[];++d<c;)b=a[d],0>w(f,b)&&W(e,function(a){return-1<w(a,b)})&&f.push(b);return f}function ia(a,b,d){var c=-Infinity,e=-1,f=a.length,g=c;if(b)d&&(b=v(b,d));else{if(a[0]===+a[0]&&f<=L)try{return Math.max.apply(Math,a)}catch(i){}if(!a.length)return g}for(;++e<f;)d=b?b(a[e],e,a):a[e],d>c&&(c=d,g=a[e]);return g}function ja(a,b,d){return l.call(a,b==m||d?1:b)}function ga
(a,b,d){var c,e=0,f=a.length;for(d&&(b=d(b));e<f;)c=e+f>>1,(d?d(a[c]):a[c])<b?e=c+1:f=c;return e}function ka(a,b,d){var c,e=-1,f=a.length,g=[],i=[];for(3>f&&(b=n);++e<f;)if(c=d?d(a[e]):a[e],b?!e||i[i.length-1]!==c:0>w(i,c))i.push(c),g.push(a[e]);return g}function v(a,b){var d,c=h.call(a)==s;if(c){if(B)return a=B.call.apply(B,arguments),function(){return arguments.length?a.apply(m,arguments):a()}}else d=b,b=a;var e=l.call(arguments,2),f=e.length;return function(){var g;return g=arguments,c||(a=b[d
]),f&&(g.length&&(e.length=f,E.apply(e,g)),g=e),g=g.length?a.apply(b,g):a.call(b),e.length=f,g}}function M(a,b,d){d||(d=[]);if(a===b)return 0!==a||1/a==1/b;if(a==m||b==m)return a===b;a.s&&(a=a._wrapped),b.s&&(b=b._wrapped);if(a.isEqual&&h.call(a.isEqual)==s)return a.isEqual(b);if(b.isEqual&&h.call(b.isEqual)==s)return b.isEqual(a);var c=h.call(a);if(c!=h.call(b))return r;switch(c){case K:return a==""+b;case N:return a!=+a?b!=+b:0==a?1/a==1/b:a==+b;case la:case ma:return+a==+b;case na:return a.source==
b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if("object"!=typeof a||"object"!=typeof b)return r;for(var e=d.length;e--;)if(d[e]==a)return n;var e=-1,f=n,g=0;d.push(a);if(c==I){if(g=a.length,f=g==b.length)for(;g--&&(f=M(a[g],b[g],d)););}else{if("constructor"in a!="constructor"in b||a.constructor!=b.constructor)return r;for(var i in a)if(t.call(a,i)&&(g++,!(f=t.call(b,i)&&M(a[i],b[i],d))))break;if(f){for(i in b)if(t.call(b,i)&&!(g--))break;f=!g}if(f&&H)for(;7>++
e&&(i=ba[e],!t.call(a,i)||!!(f=t.call(b,i)&&M(a[i],b[i],d))););}return d.pop(),f}function ca(a){return a}function oa(a){F(O(a),function(b){var d=c[b]=a[b];p.prototype[b]=function(){var a=[this._wrapped];return arguments.length&&E.apply(a,arguments),a=1==a.length?d.call(c,a[0]):d.apply(c,a),this.s&&(a=new p(a),a.s=n),a}})}var n=!0,o=null,r=!1,X="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(u=global),exports),L=5e4;try{(function(){L=arguments.length}).
apply(o,Array(L))}catch(Ha){}var wa={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},H=!{valueOf:0}.propertyIsEnumerable("valueOf"),Aa=0,S={"boolean":r,"function":n,object:n,number:r,string:r,"undefined":r},Ba=u._,A=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Ca=/__token__(\d+)/g,Da=/['\n\r\t\u2028\u2029\\]/g,ba="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf"
.split(" "),T="__token__",x=[],I="[object Array]",la="[object Boolean]",ma="[object Date]",s="[object Function]",N="[object Number]",na="[object RegExp]",K="[object String]",z=Array.prototype,y=Object.prototype,D=z.concat,t=y.hasOwnProperty,E=z.push,l=z.slice,h=y.toString,B=A.test(B=l.bind)&&/\n|Opera/.test(B+h.call(u.opera))&&B,C=A.test(C=Array.isArray)&&C,Ea=u.isFinite,Y=A.test(Y=Object.keys)&&Y,Fa=u.clearTimeout,P=u.setTimeout,ta=Function("u","var __p;with(u){__p='var o,z';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var t='+g+'.length;o=-1;';if(o){__p+='if(t===+t){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var A=typeof '+l+'==\\'function\\';'};__p+=''+o['d']+';for('+o['m']+'){';if(i){if(r){__p+='if('+h+'){'};__p+=''+o['j']+';';if(r){__p+='}'}}else{__p+='if(!(A&&o==\\'prototype\\')';if(r){__p+='&&'+h};__p+='){'+o['j']+'}'};__p+='}';if(i){__p+='var j='+l+'.constructor;';for(var k=0;k<7;k++){__p+='o=\\''+p[k]+'\\';if(';if(p[k]=='constructor'){__p+='!(j&&j.prototype==='+l+')&&'};__p+=''+h+'){'+o['j']+'}'}}if(c){__p+='}'}};__p+=''+e+';return z'}return __p"
),q={a:"h,f,G",k:"h",q:"if(!f){f=n}else if(G){f=e(f,G)}",j:"f(h[o],o,h)"},Z={k:"I",j:"if(!f(h[o],o,h))return!z"},A={a:"u",k:"u",q:"for(var C,D=1,t=arguments.length;D<t;D++){C=arguments[D];"+(H?"if(C){":""),m:"o in C",r:r,j:"u[o]=C[o]",e:(H?"}":"")+"}"},G={k:"[]",j:"f(h[o],o,h)&&z.push(h[o])"},y={k:"",f:"if(!h)return[]",d:{b:"z=Array(t)",n:"z=[]"},j:{b:"z[o]=f(h[o],o,h)",n:"z.push(f(h[o],o,h))"}},J=C||function(a){return h.call(a)==I},da=j({a:"K",k:"I",q:"var g=H.call(K);if(g==d||g==E)return!K.length"
,j:{n:"return k"}}),C=j({a:"h,F",k:"k",j:"if(h[o]===F)return I"}),W=j(q,Z),pa=j(q,G),qa=j(q,{j:"if(f(h[o],o,h))return h[o]"}),F=j(q,{q:"if(G)f=e(f,G)"}),Ga=j(q,{k:"{}",q:"var x,s=H.call(f)==l;if(s&&G)f=e(f,G)",j:"x=s?f(h[o],o,h):h[o][f];(z[x]||(z[x]=[])).push(h[o])"}),$=j(q,y),Q=j(y,{a:"h,y",j:{b:"z[o]=h[o][y]",n:"z.push(h[o][y])"}}),aa=j({a:"h,f,a,G",k:"a",q:"var w=arguments.length<3;if(G)f=e(f,G)",d:{b:"if(w)z=h[++o]"},j:{b:"z=f(z,h[o],o,h)",n:"z=w?(w=k,h[o]):f(z,h[o],o,h)"}}),G=j(q,G,{j:"!"+G.
j}),q=j(q,Z,{k:"k",j:Z.j.replace("!","")}),ra=j(y,{a:"h",j:{b:"z[o]=h[o]",n:"z.push(h[o])"}}),y=j(A,{j:"if(u[o]==J)"+A.j}),sa=j(A),O=j({a:"u",k:"[]",r:r,j:"if(H.call(u[o])==l)z.push(o)",e:"z.sort()"});R(arguments)||(R=function(a){return!!a&&!!t.call(a,"callee")});var U=Y||j({a:"u",f:"if(!v[typeof u]||u===null)throw TypeError()",k:"[]",j:"z.push(o)"});c.VERSION="0.2.0",c.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"object"},c.after=
function(a,b){return 1>a?b():function(){if(1>--a)return b.apply(this,arguments)}},c.bind=v,c.bindAll=function(a){var b=arguments,d=1;1==b.length&&(d=0,b=O(a));for(var c=b.length;d<c;d++)a[b[d]]=v(a[b[d]],a);return a},c.chain=function(a){return a=new p(a),a.s=n,a},c.clone=function(a){return S[typeof a]&&a!==o?J(a)?a.slice():sa({},a):a},c.compact=function(a){for(var b=-1,d=a.length,c=[];++b<d;)a[b]&&c.push(a[b]);return c},c.compose=function(){var a=arguments;return function(){for(var b=arguments,d=
a.length;d--;)b=[a[d].apply(this,b)];return b[0]}},c.contains=C,c.debounce=function(a,b,d){function c(){i=m,d||a.apply(g,e)}var e,f,g,i;return function(){var h=d&&!i;return e=arguments,g=this,Fa(i),i=P(c,b),h&&(f=a.apply(g,e)),f}},c.defaults=y,c.defer=function(a){var b=l.call(arguments,1);return P(function(){return a.apply(m,b)},1)},c.delay=function(a,b){var d=l.call(arguments,2);return P(function(){return a.apply(m,d)},b)},c.difference=function(a){for(var b=-1,d=a.length,c=[],e=D.apply(c,l.call(
arguments,1));++b<d;)0>w(e,a[b])&&c.push(a[b]);return c},c.escape=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")},c.every=W,c.extend=sa,c.filter=pa,c.find=qa,c.first=V,c.flatten=fa,c.forEach=F,c.functions=O,c.groupBy=Ga,c.has=function(a,b){return t.call(a,b)},c.identity=ca,c.indexOf=w,c.initial=function(a,b,d){return l.call(a,0,-(b==m||d?1:b))},c.intersection=ha,c.invoke=function(a,b){for(var d=l.call(arguments
,2),c=-1,e=a.length,f=h.call(b)==s,g=[];++c<e;)g[c]=(f?b:a[c][b]).apply(a[c],d);return g},c.isArguments=R,c.isArray=J,c.isBoolean=function(a){return a===n||a===r||h.call(a)==la},c.isDate=function(a){return h.call(a)==ma},c.isElement=function(a){return!!a&&1==a.nodeType},c.isEmpty=da,c.isEqual=M,c.isFinite=function(a){return Ea(a)&&h.call(a)==N},c.isFunction=function(a){return h.call(a)==s},c.isNaN=function(a){return h.call(a)==N&&a!=+a},c.isNull=function(a){return a===o},c.isNumber=function(a){return h
.call(a)==N},c.isObject=function(a){return S[typeof a]&&a!==o},c.isRegExp=function(a){return h.call(a)==na},c.isString=function(a){return h.call(a)==K},c.isUndefined=function(a){return a===m},c.keys=U,c.last=function(a,b,d){var c=a.length;return b==m||d?a[c-1]:l.call(a,-b||c)},c.lastIndexOf=function(a,b){if(!a)return-1;for(var d=a.length;d--;)if(a[d]===b)return d;return-1},c.map=$,c.max=ia,c.memoize=function(a,b){var d={};return function(){var c=b?b.apply(this,arguments):arguments[0];return t.call
(d,c)?d[c]:d[c]=a.apply(this,arguments)}},c.min=function(a,b,d){var c=Infinity,e=-1,f=a.length,g=c;if(b)d&&(b=v(b,d));else{if(a[0]===+a[0]&&f<=L)try{return Math.min.apply(Math,a)}catch(i){}if(!a.length)return g}for(;++e<f;)d=b?b(a[e],e,a):a[e],d<c&&(c=d,g=a[e]);return g},c.mixin=oa,c.noConflict=function(){return u._=Ba,this},c.once=function(a){var b,d=r;return function(){return d?b:(d=n,b=a.apply(this,arguments))}},c.partial=function(a){var b=l.call(arguments,1),d=b.length;return function(){var c
;return c=arguments,c.length&&(b.length=d,E.apply(b,c)),c=1==b.length?a.call(this,b[0]):a.apply(this,b),b.length=d,c}},c.pick=function(a){for(var b,d=0,c=D.apply(z,arguments),e=c.length,f={};++d<e;)b=c[d],b in a&&(f[b]=a[b]);return f},c.pluck=Q,c.range=function(a,b,d){d||(d=1),2>arguments.length&&(b=a||0,a=0);for(var c=-1,e=Math.max(Math.ceil((b-a)/d),0),f=Array(e);++c<e;)f[c]=a,a+=d;return f},c.reduce=aa,c.reduceRight=ea,c.reject=G,c.rest=ja,c.result=function(a,b){if(!a)return o;var d=a[b];return h
.call(d)==s?a[b]():d},c.shuffle=function(a){for(var b,d=-1,c=a.length,e=Array(c);++d<c;)b=Math.floor(Math.random()*(d+1)),e[d]=e[b],e[b]=a[d];return e},c.size=function(a){var b=h.call(a);return b==I||b==K?a.length:U(a).length},c.some=q,c.sortBy=function(a,b,d){if(h.call(b)!=s)var c=b,b=function(a){return a[c]};else d&&(b=v(b,d));return Q($(a,function(d,c){return{a:b(d,c,a),b:d}}).sort(function(a,b){var d=a.a,c=b.a;return d===m?1:c===m?-1:d<c?-1:d>c?1:0}),"b")},c.sortedIndex=ga,c.tap=function(a,b)
{return b(a),a},c.template=function(a,b,d){d||(d={});var k;k=c.templateSettings||{};var e=d.escape,f=d.evaluate,g=d.interpolate,d=d.variable;return e==o&&(e=k.escape),f==o&&(f=k.evaluate),g==o&&(g=k.interpolate),e&&(a=a.replace(e,xa)),g&&(a=a.replace(g,ya)),f&&(a=a.replace(f,za)),a="__p='"+a.replace(Da,va).replace(Ca,ua)+"';\n",x.length=0,d||(d=k.variable||"object",a="with("+d+"||{}){"+a+"}"),a="function("+d+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}"
,k=Function("_","return "+a)(c),b?k(b):(k.source=a,k)},c.throttle=function(a,b){function d(){i=new Date,g=m,a.apply(f,c)}var c,e,f,g,i=0;return function(){var h=new Date,j=b-(h-i);return c=arguments,f=this,0>=j?(i=h,e=a.apply(f,c)):g||(g=P(d,j)),e}},c.times=function(a,b,d){d&&(b=v(b,d));for(d=0;d<a;d++)b(d)},c.toArray=function(a){if(!a)return[];if(h.call(a.toArray)==s)return a.toArray();var b=a.length;return b===+b?l.call(a):ra(a)},c.union=function(){for(var a=-1,b=[],d=D.apply(b,arguments),c=d.length
;++a<c;)0>w(b,d[a])&&b.push(d[a]);return b},c.uniq=ka,c.uniqueId=function(a){var b=Aa++;return a?a+b:b},c.values=ra,c.without=function(a){for(var b=l.call(arguments,1),d=-1,c=a.length,e=[];++d<c;)0>w(b,a[d])&&e.push(a[d]);return e},c.wrap=function(a,b){return function(){var c=[a];return arguments.length&&E.apply(c,arguments),b.apply(this,c)}},c.zip=function(){for(var a=-1,b=ia(Q(arguments,"length")),c=Array(b);++a<b;)c[a]=Q(arguments,a);return c},c.all=W,c.any=q,c.collect=$,c.detect=qa,c.each=F,c
.foldl=aa,c.foldr=ea,c.head=V,c.include=C,c.inject=aa,c.intersect=ha,c.methods=O,c.select=pa,c.tail=ja,c.take=V,c.unique=ka,p.prototype=c.prototype,oa(c),p.prototype.chain=function(){return this.s=n,this},p.prototype.value=function(){return this._wrapped},F("pop push reverse shift sort splice unshift".split(" "),function(a){var b=z[a];p.prototype[a]=function(){var a=this._wrapped;return arguments.length?b.apply(a,arguments):b.call(a),a.length===0&&delete a[0],this.s&&(a=new p(a),a.s=n),a}}),F(["concat"
,"join","slice"],function(a){var b=z[a];p.prototype[a]=function(){var a=this._wrapped,a=arguments.length?b.apply(a,arguments):b.call(a);return this.s&&(a=new p(a),a.s=n),a}}),X?"object"==typeof module&&module&&module.t==X?(module.t=c)._=c:X._=c:(u._=c,typeof define=="function"&&typeof define.amd=="object"&&define.amd&&define(function(){return c}))})(this);
;(function(u,n){"use strict";function S(a){return"[object Arguments]"==i.call(a)}function b(a){return new p(a)}function p(a){if(a&&a._wrapped)return a;this._wrapped=a}function k(){for(var a,c,d,j=-1,b=arguments.length,e={e:"",f:"",k:"",q:"",c:{d:"",m:"++l<m"},o:{d:""}};++j<b;)for(c in a=arguments[j],a)d=(d=a[c])==o?"":d,/d|m|j/.test(c)?("string"==typeof d&&(d={b:d,n:d}),e.c[c]=d.b,e.o[c]=d.n):e[c]=d;a=e.a,c=e.c,d=e.o;var j=/^[^,]+/.exec(a)[0],b=d.m,g=/\S+$/.exec(b||j)[0];e.g=j,e.i=H,e.h="j.call("+
g+",l)",e.l=g,e.p=ca,e.r=e.r!==q,e.f||(e.f="if(!"+j+")return r");if("n"==j||!c.j)e.c=o;return b||(d.m="l in "+g),Function("b,c,i,j,k,o,v,y,z,h,A",'"use strict";return function('+a+"){"+sa(e)+"}")(I,v,r,s,da,J,K,i,m,q)}function ta(a,c){return w[c]}function ua(a){return"\\"+va[a]}function ea(){}function wa(a,c){var d=w.length;return w[d]="'+((__t=("+c+"))==null?'':_['escape'](__t))+'",T+d}function xa(a,c){var d=w.length;return w[d]="'+((__t=("+c+"))==null?'':__t)+'",T+d}function ya(a,c){var d=w.length
;return w[d]="';"+c+";__p+='",T+d}function fa(a,c,d,j){if(!a)return d;var b=a.length,e=3>arguments.length;j&&(c=v(c,j));if(b===+b){for(b&&e&&(d=a[--b]);b--;)d=c(d,a[b],b,a);return d}var g=U(a);for((b=g.length)&&e&&(d=a[g[--b]]);b--;)e=g[b],d=c(d,a[e],e,a);return d}function V(a,c,d){return c==n||d?a[0]:l.call(a,0,c)}function ga(a,c){for(var d,b=-1,f=a.length,e=[];++b<f;)d=a[b],W(d)?L.apply(e,c?d:ga(d)):e.push(d);return e}function x(a,c,d){var b;if(!a)return-1;if(d)return d=ha(a,c),a[d]===c?d:-1;d=0
;for(b=a.length;d<b;d++)if(a[d]===c)return d;return-1}function ia(a,c,d){var b=-Infinity,f=-1,e=a.length,g=b;if(!c){for(;++f<e;)a[f]>g&&(g=a[f]);return g}for(d&&(c=v(c,d));++f<e;)d=c(a[f],f,a),d>b&&(b=d,g=a[f]);return g}function ja(a,c,d){return l.call(a,c==n||d?1:c)}function ha(a,c,d){var b,f=0,e=a.length;for(d&&(c=d(c));f<e;)b=f+e>>1,(d?d(a[b]):a[b])<c?f=b+1:e=b;return f}function ka(a,c,d){for(var b,f=-1,e=a.length,g=[],h=[];++f<e;)if(b=d?d(a[f]):a[f],c?!f||h[h.length-1]!==b:0>x(h,b))h.push(b),
g.push(a[f]);return g}function v(a,c){function d(){var g=arguments,h=c;return f||(a=c[b]),e.length&&(g=g.length?M.apply(e,g):e),this instanceof d?(ea.prototype=a.prototype,h=new ea,g=a.apply(h,g),J[typeof g]&&g!==o?g:h):a.apply(h,g)}var b,f=i.call(a)==r;if(f){if(y)return y.call.apply(y,arguments)}else b=c,c=a;var e=l.call(arguments,2);return d}function N(a,c,d){d||(d=[]);if(a===c)return 0!==a||1/a==1/c;if(a==n||c==n)return a===c;a._chain&&(a=a._wrapped),c._chain&&(c=c._wrapped);if(a.isEqual&&i.call
(a.isEqual)==r)return a.isEqual(c);if(c.isEqual&&i.call(c.isEqual)==r)return c.isEqual(a);var b=i.call(a);if(b!=i.call(c))return q;switch(b){case K:return a==""+c;case O:return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case la:case ma:return+a==+c;case na:return a.source==c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return q;for(var f=d.length;f--;)if(d[f]==a)return m;var f=-1,e=m,g=0;d.push(a);if(b==I){if(g=a.length,e=g==c.length
)for(;g--&&(e=N(a[g],c[g],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return q;for(var h in a)if(s.call(a,h)&&(g++,!(e=s.call(c,h)&&N(a[h],c[h],d))))break;if(e){for(h in c)if(s.call(c,h)&&!(g--))break;e=!g}if(e&&H)for(;7>++f&&(h=ca[f],!s.call(a,h)||!!(e=s.call(c,h)&&N(a[h],c[h],d))););}return d.pop(),e}function da(a){return a}function oa(a){C(P(a),function(c){var d=b[c]=a[c];p.prototype[c]=function(){var a=[this._wrapped];return arguments.length&&L.apply(a,arguments
),a=1==a.length?d.call(b,a[0]):d.apply(b,a),this._chain&&(a=new p(a),a._chain=m),a}})}var m=!0,o=null,q=!1,X="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(u=global),exports),va={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},H=!{valueOf:0}.propertyIsEnumerable("valueOf"),za=0,J={"boolean":q,"function":m,object:m,number:q,string:q,"undefined":q},Aa=u._,z=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&"
).replace(/valueOf|for [^\]]+/g,".+?")+"$"),Ba=/__token__(\d+)/g,Ca=/['\n\r\t\u2028\u2029\\]/g,ca="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="__token__",w=[],I="[object Array]",la="[object Boolean]",ma="[object Date]",r="[object Function]",O="[object Number]",na="[object RegExp]",K="[object String]",A=Array.prototype,D=Object.prototype,M=A.concat,s=D.hasOwnProperty,L=A.push,l=A.slice,i=D.toString,y=z.test(y=l.bind)&&/\n|Opera/.test
(y+i.call(u.opera))&&y,E=z.test(E=Array.isArray)&&E,Da=u.isFinite,Y=z.test(Y=Object.keys)&&Y,Ea=u.clearTimeout,Q=u.setTimeout;b.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"};var sa=Function("obj","var __p;with(obj){__p='var l,r';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var m='+g+'.length;l=-1;';if(o){__p+='if(m===+m){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var s=typeof '+l+'==\\'function\\';'};__p+=''+o['d']+';for('+o['m']+'){';if(i){if(r){__p+='if('+h+'){'};__p+=''+o['j']+';';if(r){__p+='}'}}else{__p+='if(!(s&&l==\\'prototype\\')';if(r){__p+='&&'+h};__p+='){'+o['j']+'}'};__p+='}';if(i){__p+='var g='+l+'.constructor;';for(var k=0;k<7;k++){__p+='l=\\''+p[k]+'\\';if(';if(p[k]=='constructor'){__p+='!(g&&g.prototype==='+l+')&&'};__p+=''+h+'){'+o['j']+'}'}}if(c){__p+='}'}};__p+=''+e+';return r'}return __p"
),t={a:"f,d,x",k:"f",q:"if(!d){d=k}else if(x){d=c(d,x)}",j:"d(f[l],l,f)"},Z={k:"z",j:"if(!d(f[l],l,f))return!r"},$={a:"n",k:"n",q:"for(var t,u=1,m=arguments.length;u<m;u++){t=arguments[u];"+(H?"if(t){":""),m:"l in t",r:q,j:"n[l]=t[l]",e:(H?"}":"")+"}"},F={k:"[]",j:"d(f[l],l,f)&&r.push(f[l])"},B={q:"if(x)d=c(d,x)"},G={k:"",f:"if(!f)return[]",d:{b:"r=Array(m)",n:"r=[]"},j:{b:"r[l]=d(f[l],l,f)",n:"r.push(d(f[l],l,f))"}},z=k({a:"f,w",k:"h",j:"if(f[l]===w)return z"}),aa=k(t,Z),D=k(t,F),pa=k(t,B,{k:"",
j:"if(d(f[l],l,f))return f[l]"}),C=k(t,B),ba=k(t,G),R=k(G,{a:"f,q",j:{b:"r[l]=f[l][q]",n:"r.push(f[l][q])"}}),B=k({a:"f,d,a,x",k:"a",q:"var p=arguments.length<3;if(x)d=c(d,x)",d:{b:"if(p)r=f[++l]"},j:{b:"r=d(r,f[l],l,f)",n:"r=p?(p=h,f[l]):d(r,f[l],l,f)"}}),F=k(t,F,{j:"!"+F.j}),t=k(t,Z,{k:"h",j:Z.j.replace("!","")}),qa=k(G,{a:"f",j:{b:"r[l]=f[l]",n:"r.push(f[l])"}}),G=k($,{j:"if(n[l]==A)"+$.j}),ra=k($),P=k({a:"n",k:"[]",r:q,j:"if(y.call(n[l])==i)r.push(l)",e:"r.sort()"});S(arguments)||(S=function(
a){return!!a&&!!s.call(a,"callee")});var W=E||function(a){return i.call(a)==I},E=k({a:"B",k:"z",q:"var e=y.call(B);if(e==b||e==v)return!B.length",j:{n:"return h"}}),U=Y||k({a:"n",f:"if(!o[typeof n]||n===null)throw TypeError()",k:"[]",j:"r.push(l)"});b.VERSION="0.2.2",b.after=function(a,c){return 1>a?c():function(){if(1>--a)return c.apply(this,arguments)}},b.bind=v,b.bindAll=function(a){var c=arguments,d=1;1==c.length&&(d=0,c=P(a));for(var b=c.length;d<b;d++)a[c[d]]=v(a[c[d]],a);return a},b.chain=
function(a){return a=new p(a),a._chain=m,a},b.clone=function(a){return J[typeof a]&&a!==o?W(a)?a.slice():ra({},a):a},b.compact=function(a){for(var c=-1,d=a.length,b=[];++c<d;)a[c]&&b.push(a[c]);return b},b.compose=function(){var a=arguments;return function(){for(var c=arguments,d=a.length;d--;)c=[a[d].apply(this,c)];return c[0]}},b.contains=z,b.debounce=function(a,c,d){function b(){h=n,d||a.apply(g,f)}var f,e,g,h;return function(){var i=d&&!h;return f=arguments,g=this,Ea(h),h=Q(b,c),i&&(e=a.apply
(g,f)),e}},b.defaults=G,b.defer=function(a){var c=l.call(arguments,1);return Q(function(){return a.apply(n,c)},1)},b.delay=function(a,c){var d=l.call(arguments,2);return Q(function(){return a.apply(n,d)},c)},b.difference=function(a){for(var c=-1,d=a.length,b=[],f=M.apply(b,l.call(arguments,1));++c<d;)0>x(f,a[c])&&b.push(a[c]);return b},b.escape=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")},b.every=aa,b.extend=ra,b.filter=D,b.find=
pa,b.first=V,b.flatten=ga,b.forEach=C,b.functions=P,b.groupBy=function(a,c,d){var b,f=-1,e=i.call(c)==r,g=a.length,h={};for(e&&d&&(c=v(c,d));++f<g;)b=a[f],d=e?c(b,f,a):b[c],(s.call(h,d)?h[d]:h[d]=[]).push(b);return h},b.has=function(a,c){return s.call(a,c)},b.identity=da,b.indexOf=x,b.initial=function(a,c,d){return l.call(a,0,-(c==n||d?1:c))},b.intersection=function(a){for(var c,d=-1,b=a.length,f=l.call(arguments,1),e=[];++d<b;)c=a[d],0>x(e,c)&&aa(f,function(a){return-1<x(a,c)})&&e.push(c);return e
},b.invoke=function(a,c){for(var d=l.call(arguments,2),b=-1,f=a.length,e=i.call(c)==r,g=[];++b<f;)g[b]=(e?c:a[b][c]).apply(a[b],d);return g},b.isArguments=S,b.isArray=W,b.isBoolean=function(a){return a===m||a===q||i.call(a)==la},b.isDate=function(a){return i.call(a)==ma},b.isElement=function(a){return!!a&&1==a.nodeType},b.isEmpty=E,b.isEqual=N,b.isFinite=function(a){return Da(a)&&i.call(a)==O},b.isFunction=function(a){return i.call(a)==r},b.isNaN=function(a){return i.call(a)==O&&a!=+a},b.isNull=function(
a){return a===o},b.isNumber=function(a){return i.call(a)==O},b.isObject=function(a){return J[typeof a]&&a!==o},b.isRegExp=function(a){return i.call(a)==na},b.isString=function(a){return i.call(a)==K},b.isUndefined=function(a){return a===n},b.keys=U,b.last=function(a,c,d){var b=a.length;return c==n||d?a[b-1]:l.call(a,-c||b)},b.lastIndexOf=function(a,c){if(!a)return-1;for(var d=a.length;d--;)if(a[d]===c)return d;return-1},b.map=ba,b.max=ia,b.memoize=function(a,c){var d={};return function(){var b=c?
c.apply(this,arguments):arguments[0];return s.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}},b.min=function(a,c,d){var b=Infinity,f=-1,e=a.length,g=b;if(!c){for(;++f<e;)a[f]<g&&(g=a[f]);return g}for(d&&(c=v(c,d));++f<e;)d=c(a[f],f,a),d<b&&(b=d,g=a[f]);return g},b.mixin=oa,b.noConflict=function(){return u._=Aa,this},b.once=function(a){var c,d=q;return function(){return d?c:(d=m,c=a.apply(this,arguments))}},b.partial=function(a){var c=l.call(arguments,1),d=c.length;return function(){var b;return b=arguments
,b.length&&(c.length=d,L.apply(c,b)),b=1==c.length?a.call(this,c[0]):a.apply(this,c),c.length=d,b}},b.pick=function(a){for(var c,d=0,b=M.apply(A,arguments),f=b.length,e={};++d<f;)c=b[d],c in a&&(e[c]=a[c]);return e},b.pluck=R,b.range=function(a,c,d){d||(d=1),2>arguments.length&&(c=a||0,a=0);for(var b=-1,f=Math.max(Math.ceil((c-a)/d),0),e=Array(f);++b<f;)e[b]=a,a+=d;return e},b.reduce=B,b.reduceRight=fa,b.reject=F,b.rest=ja,b.result=function(a,c){if(!a)return o;var d=a[c];return i.call(d)==r?a[c](
):d},b.shuffle=function(a){for(var c,d=-1,b=a.length,f=Array(b);++d<b;)c=Math.floor(Math.random()*(d+1)),f[d]=f[c],f[c]=a[d];return f},b.size=function(a){var c=i.call(a);return c==I||c==K?a.length:U(a).length},b.some=t,b.sortBy=function(a,c,d){if(i.call(c)!=r)var b=c,c=function(a){return a[b]};else d&&(c=v(c,d));return R(ba(a,function(b,d){return{a:c(b,d,a),b:b}}).sort(function(a,c){var b=a.a,d=c.a;return b===n?1:d===n?-1:b<d?-1:b>d?1:0}),"b")},b.sortedIndex=ha,b.tap=function(a,c){return c(a),a},
b.template=function(a,c,d){d||(d={});var j;j=b.templateSettings;var f=d.escape,e=d.evaluate,g=d.interpolate,d=d.variable;return f==o&&(f=j.escape),e==o&&(e=j.evaluate),g==o&&(g=j.interpolate),f&&(a=a.replace(f,wa)),g&&(a=a.replace(g,xa)),e&&(a=a.replace(e,ya)),a="__p='"+a.replace(Ca,ua).replace(Ba,ta)+"';\n",w.length=0,d||(d=j.variable,a="with("+d+"||{}){"+a+"}"),a="function("+d+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}",j=Function("_","return "+
a)(b),c?j(c):(j.source=a,j)},b.throttle=function(a,c){function b(){h=new Date,g=n,a.apply(e,j)}var j,f,e,g,h=0;return function(){var i=new Date,k=c-(i-h);return j=arguments,e=this,0>=k?(h=i,f=a.apply(e,j)):g||(g=Q(b,k)),f}},b.times=function(a,c,b){b&&(c=v(c,b));for(b=0;b<a;b++)c(b)},b.toArray=function(a){if(!a)return[];if(i.call(a.toArray)==r)return a.toArray();var b=a.length;return b===+b?l.call(a):qa(a)},b.union=function(){for(var a=-1,b=[],d=M.apply(b,arguments),i=d.length;++a<i;)0>x(b,d[a])&&
b.push(d[a]);return b},b.uniq=ka,b.uniqueId=function(a){var b=za++;return a?a+b:b},b.values=qa,b.without=function(a){for(var b=l.call(arguments,1),d=-1,i=a.length,f=[];++d<i;)0>x(b,a[d])&&f.push(a[d]);return f},b.wrap=function(a,b){return function(){var d=[a];return arguments.length&&L.apply(d,arguments),b.apply(this,d)}},b.zip=function(){for(var a=-1,b=ia(R(arguments,"length")),d=Array(b);++a<b;)d[a]=R(arguments,a);return d},b.all=aa,b.any=t,b.collect=ba,b.detect=pa,b.each=C,b.foldl=B,b.foldr=fa
,b.head=V,b.include=z,b.inject=B,b.methods=P,b.select=D,b.tail=ja,b.take=V,b.unique=ka,p.prototype=b.prototype,oa(b),p.prototype.chain=function(){return this._chain=m,this},p.prototype.value=function(){return this._wrapped},C("pop push reverse shift sort splice unshift".split(" "),function(a){var b=A[a];p.prototype[a]=function(){var a=this._wrapped;return arguments.length?b.apply(a,arguments):b.call(a),a.length===0&&delete a[0],this._chain&&(a=new p(a),a._chain=m),a}}),C(["concat","join","slice"]
,function(a){var b=A[a];p.prototype[a]=function(){var a=this._wrapped,a=arguments.length?b.apply(a,arguments):b.call(a);return this._chain&&(a=new p(a),a._chain=m),a}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(u._=b,define(function(){return b})):X?"object"==typeof module&&module&&module.s==X?(module.s=b)._=b:X._=b:u._=b})(this);

View File

@@ -1,6 +1,6 @@
{
"name": "lodash",
"version": "0.2.0",
"version": "0.2.2",
"description": "A drop-in replacement for Underscore.js that delivers performance improvements, bug fixes, and additional features.",
"homepage": "http://lodash.com",
"main": "lodash",

View File

@@ -9,14 +9,18 @@
padding: 0;
height: 100%;
}
applet {
position: absolute;
left: -9999em;
}
</style>
</head>
<body>
<script src="../lodash.min.js"></script>
<script src="../lodash.js"></script>
<script>
var lodash = _.noConflict();
</script>
<script src="../vendor/underscore/underscore-min.js"></script>
<script src="../vendor/underscore/underscore.js"></script>
<script src="../vendor/benchmark.js/benchmark.js"></script>
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
<script>

View File

@@ -13,7 +13,7 @@
/** Load Lo-Dash */
var lodash =
window.lodash || (
lodash = load('../lodash.min.js') || window._,
lodash = load('../lodash.js') || window._,
lodash = lodash._ || lodash,
lodash.noConflict()
);
@@ -21,7 +21,7 @@
/** Load Underscore */
var _ =
window._ || (
_ = load('../vendor/underscore/underscore-min.js') || window._,
_ = load('../vendor/underscore/underscore.js') || window._,
_._ || _
);
@@ -46,9 +46,29 @@
'setup': function() {
var window = Function('return this || global')(),
_ = window._,
lodash = window.lodash,
numbers = [],
object = {};
lodash = window.lodash;
var numbers = [],
object = {},
fourNumbers = [5, 25, 10, 30],
nestedNumbers = [1, [2], [3, [[4]]]],
twoNumbers = [12, 21],
words = [
'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
'seventeen', 'eighteen', 'nineteen', 'twenty'
];
var ctor = function() { },
func = function(greeting) { return greeting + ': ' + this.name; };
var lodashBoundNormal = lodash.bind(func, { 'name': 'moe' }),
lodashBoundCtor = lodash.bind(ctor, { 'name': 'moe' }),
lodashBoundPartial = lodash.bind(func, { 'name': 'moe' }, 'hi');
var _boundNormal = _.bind(func, { 'name': 'moe' }),
_boundCtor = _.bind(ctor, { 'name': 'moe' }),
_boundPartial = _.bind(func, { 'name': 'moe' }, 'hi');
for (var index = 0; index < 20; index++) {
numbers[index] = index;
@@ -69,15 +89,21 @@
console.log(event.target + '');
},
'onComplete': function() {
var fastest = this.filter('fastest').pluck('name'),
var fastest = this.filter('fastest'),
slowest = this.filter('slowest'),
lodashHz = 1 / (this[0].stats.mean + this[0].stats.moe),
underscoreHz = 1 / (this[1].stats.mean + this[1].stats.moe);
if (fastest.length > 1) {
console.log('It\'s too close to call.');
lodashHz = underscoreHz = Math.min(lodashHz, underscoreHz);
} else {
console.log(fastest + ' is the fastest.');
}
else {
var fastestHz = fastest[0] == this[0] ? lodashHz : underscoreHz,
slowestHz = slowest[0] == this[0] ? lodashHz : underscoreHz,
percent = Math.round(((fastestHz / slowestHz) - 1) * 100);
console.log(fastest[0].name + ' is ' + percent + '% faster.');
}
// add score adjusted for margin of error
score.lodash += lodashHz;
@@ -91,11 +117,17 @@
suites[0].run();
}
else {
var fastestTotalHz = Math.max(score.lodash, score.underscore),
slowestTotalHz = Math.min(score.lodash, score.underscore),
totalPercent = Math.round(((fastestTotalHz / slowestTotalHz) - 1) * 100),
totalX = (fastestTotalHz / slowestTotalHz).toFixed(2),
message = ' is ' + totalPercent + '% (' + totalX + 'x) faster than ';
// report results
if (score.lodash >= score.underscore) {
console.log('\nLo-Dash is ' + (score.lodash / score.underscore).toFixed(2) + 'x faster than Underscore.');
console.log('\nLo-Dash' + message + 'Underscore.');
} else {
console.log('\nUnderscore is ' + (score.underscore / score.lodash).toFixed(2) + 'x faster than Lo-Dash.');
console.log('\nUnderscore' + message + 'Lo-Dash.');
}
}
}
@@ -103,6 +135,48 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('bind call')
.add('Lo-Dash', function() {
lodash.bind(func, { 'name': 'moe' }, 'hi');
})
.add('Underscore', function() {
_.bind(func, { 'name': 'moe' }, 'hi');
})
);
suites.push(
Benchmark.Suite('bound normal')
.add('Lo-Dash', function() {
lodashBoundNormal();
})
.add('Underscore', function() {
_boundNormal();
})
);
suites.push(
Benchmark.Suite('bound partial')
.add('Lo-Dash', function() {
lodashBoundPartial();
})
.add('Underscore', function() {
_boundPartial();
})
);
suites.push(
Benchmark.Suite('bound constructor')
.add('Lo-Dash', function() {
new lodashBoundCtor();
})
.add('Underscore', function() {
new _boundCtor();
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('each array')
.add('Lo-Dash', function() {
@@ -119,8 +193,6 @@
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('each object')
.add('Lo-Dash', function() {
@@ -139,6 +211,90 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('find')
.add('Lo-Dash', function() {
lodash.find(numbers, function(num) {
return num === 19;
});
})
.add('Underscore', function() {
_.find(numbers, function(num) {
return num === 19;
});
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('flatten deep')
.add('Lo-Dash', function() {
lodash.flatten(nestedNumbers);
})
.add('Underscore', function() {
_.flatten(nestedNumbers);
})
);
suites.push(
Benchmark.Suite('flatten shallow')
.add('Lo-Dash', function() {
lodash.flatten(nestedNumbers, true);
})
.add('Underscore', function() {
_.flatten(nestedNumbers, true);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('difference')
.add('Lo-Dash', function() {
lodash.difference(numbers, fourNumbers);
})
.add('Underscore', function() {
_.difference(numbers, fourNumbers);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('groupBy callback')
.add('Lo-Dash', function() {
lodash.groupBy(numbers, function(num) { return Math.floor(num); });
})
.add('Underscore', function() {
_.groupBy(numbers, function(num) { return Math.floor(num); });
})
);
suites.push(
Benchmark.Suite('groupBy property name')
.add('Lo-Dash', function() {
lodash.groupBy(words, 'length');
})
.add('Underscore', function() {
_.groupBy(words, 'length');
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('intersection')
.add('Lo-Dash', function() {
lodash.intersection(numbers, fourNumbers, twoNumbers);
})
.add('Underscore', function() {
_.intersection(numbers, fourNumbers, twoNumbers);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('keys')
.add('Lo-Dash', function() {
@@ -167,6 +323,42 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('max')
.add('Lo-Dash', function() {
lodash.max(numbers);
})
.add('Underscore', function() {
_.max(numbers);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('min')
.add('Lo-Dash', function() {
lodash.min(numbers);
})
.add('Underscore', function() {
_.min(numbers);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('pick')
.add('Lo-Dash', function() {
lodash.pick(object, 'key6', 'key13');
})
.add('Underscore', function() {
_.pick(object, 'key6', 'key13');
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('pluck')
.add('Lo-Dash', function() {
@@ -179,6 +371,18 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('union')
.add('Lo-Dash', function() {
lodash.union(numbers, fourNumbers, twoNumbers);
})
.add('Underscore', function() {
_.union(numbers, fourNumbers, twoNumbers);
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('values')
.add('Lo-Dash', function() {

View File

@@ -92,7 +92,7 @@
ok(_() instanceof _);
});
test('should pass through LoDash instances', function() {
test('should return passed LoDash instances', function() {
var wrapped = _([]);
equal(_(wrapped), wrapped);
});
@@ -174,6 +174,43 @@
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.find');
(function() {
var array = [1, 2, 3, 4];
test('should return found `value`', function() {
equal(_.find(array, function(n) { return n > 2; }), 3);
});
test('should return `undefined` if `value` is not found', function() {
equal(_.find(array, function(n) { return n == 5; }), undefined);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.flatten');
(function() {
test('should treat sparse arrays as dense', function() {
var array = [[1, 2, 3], Array(3)],
expected = [1, 2, 3],
actual1 = _.flatten(array),
actual2 = _.flatten(array, true);
expected.push(undefined, undefined, undefined);
deepEqual(actual1, expected);
ok('4' in actual1);
deepEqual(actual2, expected);
ok('4' in actual2);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.forEach');
(function() {
@@ -204,6 +241,15 @@
deepEqual(actual, { '1': [1.3], '2': [2.1, 2.4] });
});
test('should only add elements to own, not inherited, properties', function() {
var actual = _.groupBy([1.3, 2.1, 2.4], function(num) {
return Math.floor(num) > 1 ? 'hasOwnProperty' : 'constructor';
});
deepEqual(actual.constructor, [1.3]);
deepEqual(actual.hasOwnProperty, [2.1, 2.4]);
});
}());
/*--------------------------------------------------------------------------*/
@@ -264,28 +310,6 @@
/*--------------------------------------------------------------------------*/
(function() {
var i = -1,
largeArray = [];
while (++i <= 1e6) {
largeArray[i] = i;
}
_.each(['max', 'min'], function(methodName) {
QUnit.module('lodash.' + methodName);
test('does not error when computing the ' + methodName + ' value of massive arrays', function() {
try {
var actual = _[methodName](largeArray);
} catch(e) { }
equal(actual, methodName == 'max' ? 1e6 : 0);
});
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.partial');
(function() {
@@ -378,7 +402,7 @@
(function() {
test('supports recursive calls', function() {
var compiled = _.template('<%= a %><% a = _.template(c, object) %><%= a %>'),
var compiled = _.template('<%= a %><% a = _.template(c, obj) %><%= a %>'),
data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
equal(compiled(data), 'AB');
@@ -412,7 +436,7 @@
while ((new Date - start) < limit) {
throttled();
}
equal(counter, 3);
ok(counter > 1);
});
}());

2
vendor/docdown vendored