From f97c6fb94c058fb11fb760e9d0b18c3be121b965 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Oct 2012 00:27:46 -0700 Subject: [PATCH 01/79] Tweak npm global install note in README.md. [ci skip] Former-commit-id: 1105c1cf4c5889278eeb5be4bff9534091904821 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3775a4111c..9eee7ab168 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): var _ = require('lodash'); ``` -**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before attempting to `require` it. +**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before requiring it. In [RingoJS v0.7.0-](http://ringojs.org/): From b751fd738d3bbfaab9a61f152177e6abefcc5c7e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Oct 2012 00:46:52 -0700 Subject: [PATCH 02/79] Tweak `_.isPlainObject` doc example. [ci skip] Former-commit-id: 5d4916d5c1a2909062cc9f2646a580b630fb4e35 --- lodash.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lodash.js b/lodash.js index 4ef55e8d08..411ce2c232 100644 --- a/lodash.js +++ b/lodash.js @@ -892,10 +892,10 @@ * } * * _.isPlainObject(new Stooge('moe', 40)); - * // false + * // => false * * _.isPlainObject([1, 2, 3]); - * // false + * // => false * * _.isPlainObject({ 'name': 'moe', 'age': 40 }); * // => true From 4cd4d8f31ab64345f1bdd16fd8156df307059f45 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Oct 2012 22:13:42 -0700 Subject: [PATCH 03/79] Add `sourceURL` template option. [closes #90] Former-commit-id: 5db79c6b08aa7c8b2925db70d86dde75298da4c4 --- lodash.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lodash.js b/lodash.js index 411ce2c232..6408ae7484 100644 --- a/lodash.js +++ b/lodash.js @@ -3693,9 +3693,9 @@ * @example * * // using a compiled template - * var compiled = _.template('hello: <%= name %>'); + * var compiled = _.template('hello <%= name %>'); * compiled({ 'name': 'moe' }); - * // => 'hello: moe' + * // => 'hello moe' * * var list = '<% _.forEach(people, function(name) { %>
  • <%= name %>
  • <% }); %>'; * _.template(list, { 'people': ['moe', 'larry', 'curly'] }); @@ -3706,26 +3706,31 @@ * // => '<script>' * * // using the internal `print` function in "evaluate" delimiters - * _.template('<% print("Hello " + epithet); %>.', { 'epithet': 'stooge' }); - * // => 'Hello stooge.' + * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' }); + * // => 'hello stooge!' * * // using custom template delimiter settings * _.templateSettings = { * 'interpolate': /\{\{([\s\S]+?)\}\}/g * }; * - * _.template('Hello {{ name }}!', { 'name': 'Mustache' }); - * // => 'Hello Mustache!' + * _.template('hello {{ name }}!', { 'name': 'mustache' }); + * // => 'hello mustache!' * * // using the `variable` option to ensure a with-statement isn't used in the compiled template - * var compiled = _.template('hello: <%= data.name %>', null, { 'variable': 'data' }); + * var compiled = _.template('hello <%= data.name %>!', null, { 'variable': 'data' }); * compiled.source; * // => function(data) { * var __t, __p = '', __e = _.escape; - * __p += 'hello: ' + ((__t = ( data.name )) == null ? '' : __t); + * __p += 'hello ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; * return __p; * } * + * // using the `sourceURL` option to specify a custom sourceURL for the template + * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' }); + * compiled(data); + * // => find the source of "greeting.jst" under the sources tab or resources panel of the web inspector + * * // using the `source` property to inline compiled templates for meaningful * // line numbers in error messages and a stack trace * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ @@ -3810,7 +3815,7 @@ // use a sourceURL for easier debugging // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl var sourceURL = useSourceURL - ? '\n//@ sourceURL=/lodash/template/source[' + (templateCounter++) + ']' + ? '\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') : ''; try { From 58dc0b1aef12ca0ee54d9b366ab1b5a7881ca652 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Oct 2012 22:14:05 -0700 Subject: [PATCH 04/79] Remove unnecessary template unit test. Former-commit-id: 42ea5be4168d4db818ec93a8f6c61c51905127c7 --- test/test.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/test/test.js b/test/test.js index e903e7cc6a..ec392f583e 100644 --- a/test/test.js +++ b/test/test.js @@ -105,16 +105,6 @@ QUnit.module('lodash'); (function() { - // ensure this test is executed before any other template tests to avoid false positives - test('should initialize `reEvaluateDelimiter` (test with production build)', function() { - var data = { 'a': [1, 2] }, - settings = _.templateSettings; - - _.templateSettings = { 'interpolate': /\{\{(.+?)\}\}/g }; - equal(_.template('{{ a.join(",") }}', data), '1,2'); - _.templateSettings = settings; - }); - test('supports loading lodash.js as the "lodash" module', function() { if (window.document && window.require) { equal((lodashModule || {}).moduleName, 'lodash'); @@ -1509,7 +1499,7 @@ equal(compiled(data), '1'); }); - + test('should work when passing `options.variable`', function() { var compiled = _.template( '<% _.forEach( data.a, function( value ) { %>' + From c8f871ff2ab6e8b90c13fa5b8f4d97dd32abbbf6 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Oct 2012 23:51:15 -0700 Subject: [PATCH 05/79] =?UTF-8?q?Escape=20template=20properties=20for=20mi?= =?UTF-8?q?nified=20precompiled=20templates=20and=20add=20a=20`lodash=20te?= =?UTF-8?q?mplate=3D"=E2=80=A6"=20exports=3D"=E2=80=A6"`=20build=20test.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Former-commit-id: 866252235232ab52cf21842554c37573de4cf402 --- build.js | 18 ++++++++---------- build/minify.js | 2 +- build/pre-compile.js | 1 - test/test-build.js | 23 +++++++++++++++++++++++ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/build.js b/build.js index f0b8caa974..ce222f73b1 100755 --- a/build.js +++ b/build.js @@ -275,9 +275,8 @@ " var freeExports = typeof exports == 'object' && exports &&", " (typeof global == 'object' && global && global == global.global && (window = global), exports);", '', - ' var templates = {};', - '', - ' var _ = window._;', + ' var templates = {},', + ' _ = window._;', '' ]; @@ -295,16 +294,14 @@ precompiled = getFunctionSource(_.template(text, null, options)), prop = filename.replace(/\..*$/, ''); - source.push(" templates['" + prop + "'] = " + precompiled + ';'); + source.push(" templates['" + prop.replace(/'/g, "\\'") + "'] = " + precompiled + ';', ''); } }); source.push( - '', " if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {", " define(['" + moduleName + "'], function(lodash) {", - ' _ = lodash;', - ' _.templates = _.extend(_.templates || {}, templates);', + ' lodash.templates = lodash.extend(lodash.templates || {}, templates);', ' });', " } else if (freeExports) {", " if (typeof module == 'object' && module && module.exports == freeExports) {", @@ -1382,7 +1379,7 @@ if (isAMD && isGlobal) { source = source.replace(/(?: *\/\/.*\n)* *(?:else )?if *\(freeExports\) *{\s*}\n/, ''); } else { - source = source.replace(/(?: *\/\/.*\n)* *(?:else )?if *\(freeExports\) *{\s*}(?:\s*else *{([\s\S]+?) *})?\n/, '$1'); + source = source.replace(/(?: *\/\/.*\n)* *(?:else )?if *\(freeExports\) *{\s*}(?:\s*else *{([\s\S]+?) *})?\n/, '$1\n'); } if ((source.match(/\bfreeExports\b/g) || []).length < 2) { @@ -1511,8 +1508,9 @@ 'outputPath': outputPath, 'onComplete': function(source) { // correct overly aggressive Closure Compiler minification - source = source.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}'); - + if (!isTemplate) { + source = source.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}'); + } // inject "use strict" directive if (isStrict) { source = source.replace(/^(\/\*![\s\S]+?\*\/\n;\(function[^)]+\){)([^'"])/, '$1"use strict";$2'); diff --git a/build/minify.js b/build/minify.js index 3fede079b5..e819b38c6a 100755 --- a/build/minify.js +++ b/build/minify.js @@ -119,7 +119,7 @@ // use simple optimizations when minifying template files if (this.isTemplate) { options = options.map(function(value) { - return value.replace(/^(compilation_level)=.+$/, '$1=SIMPLE_OPTIMIZATIONS'); + return value.replace(/^(--compilation_level)=.+$/, '$1=SIMPLE_OPTIMIZATIONS'); }); } diff --git a/build/pre-compile.js b/build/pre-compile.js index 76987dd1a0..b63f6cec10 100644 --- a/build/pre-compile.js +++ b/build/pre-compile.js @@ -215,7 +215,6 @@ 'take', 'tap', 'template', - 'templates', 'templateSettings', 'throttle', 'times', diff --git a/test/test-build.js b/test/test-build.js index e76c95dff7..bd704449cc 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -483,6 +483,29 @@ equal(templates.a(data.a).replace(/[\r\n]+/g, ''), '
    • moe
    • larry
    • curly
    ', basename); equal(templates.b(data.b), 'Hello stooge.', basename); + delete _.templates; + start(); + }); + }); + + asyncTest('`lodash template=*.jst` exports=amd', function() { + var start = _.after(2, _.once(QUnit.start)); + + build(['-s', 'template=' + templatePath + '/*.jst', 'exports=amd'], function(source, filePath) { + var basename = path.basename(filePath, '.js'), + context = createContext(), + pass = false; + + (context.define = function(requires, factory) { + factory(_); + var templates = _.templates; + pass = 'a' in templates && 'b' in templates; + }) + .amd = {}; + + vm.runInContext(source, context); + ok(pass, basename); + delete _.templates; start(); }); }); From bda00bf51221f78343c713a222b8cfe4e322263d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Oct 2012 01:11:58 -0700 Subject: [PATCH 06/79] Add json3.js, remove json2 and jslitmus from vendors. Former-commit-id: d801c48ec81ea2f5c5638910190da461facf98cf --- test/backbone.html | 6 +- test/underscore.html | 6 +- vendor/backbone/test/vendor/jslitmus.js | 649 ------------------ vendor/backbone/test/vendor/json2.js | 481 ------------- vendor/json3/LICENSE | 20 + vendor/json3/README.md | 124 ++++ vendor/json3/lib/json3.js | 783 ++++++++++++++++++++++ vendor/underscore/test/vendor/jslitmus.js | 670 ------------------ 8 files changed, 931 insertions(+), 1808 deletions(-) delete mode 100644 vendor/backbone/test/vendor/jslitmus.js delete mode 100644 vendor/backbone/test/vendor/json2.js create mode 100644 vendor/json3/LICENSE create mode 100644 vendor/json3/README.md create mode 100644 vendor/json3/lib/json3.js delete mode 100644 vendor/underscore/test/vendor/jslitmus.js diff --git a/test/backbone.html b/test/backbone.html index ca1f4942da..77f3549ae2 100644 --- a/test/backbone.html +++ b/test/backbone.html @@ -8,9 +8,6 @@ body > #qunit-header { display: none; } - #jslitmus { - display: none; - } @@ -21,9 +18,8 @@

    Backbone Speed Suite

    Test

    - + - + - + + +## CommonJS Environments + + var JSON3 = require("./path/to/json3"); + JSON3.parse("[1, 2, 3]"); + // => [1, 2, 3] + +## JavaScript Engines + + load("path/to/json3.js"); + JSON.stringify({"Hello": 123, "Good-bye": 456}, ["Hello"], "\t"); + // => '{\n\t"Hello": 123\n}' + +# Compatibility # + +JSON 3 has been **tested** with the following web browsers, CommonJS environments, and JavaScript engines. + +## Web Browsers + +- Windows [Internet Explorer](http://www.microsoft.com/windows/internet-explorer), version 6.0 and higher +- Mozilla [Firefox](http://www.mozilla.com/firefox), version 1.0 and higher +- Apple [Safari](http://www.apple.com/safari), version 2.0 and higher +- [Opera](http://www.opera.com) 7.02 and higher +- [Mozilla](http://sillydog.org/narchive/gecko.php) 1.0, [Netscape](http://sillydog.org/narchive/) 6.2.3, and [SeaMonkey](http://www.seamonkey-project.org/) 1.0 and higher + +## CommonJS Environments + +- [Node](http://nodejs.org/) 0.2.6 and higher +- [RingoJS](http://ringojs.org/) 0.4 and higher +- [Narwhal](http://narwhaljs.org/) 0.3.2 and higher + +## JavaScript Engines + +- Mozilla [Rhino](http://www.mozilla.org/rhino) 1.5R5 and higher +- WebKit [JSC](https://trac.webkit.org/wiki/JSC) +- Google [V8](http://code.google.com/p/v8) + +## Known Incompatibilities + +* Attempting to serialize the `arguments` object may produce inconsistent results across environments due to specification version differences. As a workaround, please convert the `arguments` object to an array first: `JSON.stringify([].slice.call(arguments, 0))`. + +## Required Native Methods + +JSON 3 assumes that the following methods exist and function as described in the ECMAScript specification: + +- The `Number`, `String`, `Array`, `Object`, `Date`, `SyntaxError`, and `TypeError` constructors. +- `String.fromCharCode` +- `Object#toString` +- `Function#call` +- `Math.floor` +- `Number#toString` +- `Date#valueOf` +- `String.prototype`: `indexOf`, `charCodeAt`, `charAt`, `slice`. +- `Array.prototype`: `push`, `pop`, `join`. + +# Contribute # + +Check out a working copy of the JSON 3 source code with [Git](http://git-scm.com/): + + $ git clone git://github.com/bestiejs/json3.git + $ cd json3 + $ git submodule update --init + +If you'd like to contribute a feature or bug fix, you can [fork](http://help.github.com/fork-a-repo/) JSON 3, commit your changes, and [send a pull request](http://help.github.com/send-pull-requests/). Please make sure to update the unit tests in the `test` directory as well. + +Alternatively, you can use the [GitHub issue tracker](https://github.com/bestiejs/json3/issues) to submit bug reports, feature requests, and questions, or send tweets to [@kitcambridge](http://twitter.com/kitcambridge). + +JSON 3 is released under the [MIT License](http://kit.mit-license.org/). \ No newline at end of file diff --git a/vendor/json3/lib/json3.js b/vendor/json3/lib/json3.js new file mode 100644 index 0000000000..b152b27ffb --- /dev/null +++ b/vendor/json3/lib/json3.js @@ -0,0 +1,783 @@ +/*! JSON v3.2.4 | http://bestiejs.github.com/json3 | Copyright 2012, Kit Cambridge | http://kit.mit-license.org */ +;(function () { + // Convenience aliases. + var getClass = {}.toString, isProperty, forEach, undef; + + // Detect the `define` function exposed by asynchronous module loaders. The + // strict `define` check is necessary for compatibility with `r.js`. + var isLoader = typeof define === "function" && define.amd, JSON3 = !isLoader && typeof exports == "object" && exports; + + if (JSON3 || isLoader) { + if (typeof JSON == "object" && JSON) { + // Delegate to the native `stringify` and `parse` implementations in + // asynchronous module loaders and CommonJS environments. + if (isLoader) { + JSON3 = JSON; + } else { + JSON3.stringify = JSON.stringify; + JSON3.parse = JSON.parse; + } + } else if (isLoader) { + JSON3 = this.JSON = {}; + } + } else { + // Export for web browsers and JavaScript engines. + JSON3 = this.JSON || (this.JSON = {}); + } + + // Local variables. + var Escapes, toPaddedString, quote, serialize; + var fromCharCode, Unescapes, abort, lex, get, walk, update, Index, Source; + + // Test the `Date#getUTC*` methods. Based on work by @Yaffle. + var isExtended = new Date(-3509827334573292), floor, Months, getDay; + + try { + // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical + // results for certain dates in Opera >= 10.53. + isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() == 1 && + // Safari < 2.0.2 stores the internal millisecond time value correctly, + // but clips the values returned by the date methods to the range of + // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). + isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; + } catch (exception) {} + + // Internal: Determines whether the native `JSON.stringify` and `parse` + // implementations are spec-compliant. Based on work by Ken Snyder. + function has(name) { + var stringifySupported, parseSupported, value, serialized = '{"A":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}', all = name == "json"; + if (all || name == "json-stringify" || name == "json-parse") { + // Test `JSON.stringify`. + if (name == "json-stringify" || all) { + if ((stringifySupported = typeof JSON3.stringify == "function" && isExtended)) { + // A test function object with a custom `toJSON` method. + (value = function () { + return 1; + }).toJSON = value; + try { + stringifySupported = + // Firefox 3.1b1 and b2 serialize string, number, and boolean + // primitives as object literals. + JSON3.stringify(0) === "0" && + // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object + // literals. + JSON3.stringify(new Number()) === "0" && + JSON3.stringify(new String()) == '""' && + // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or + // does not define a canonical JSON representation (this applies to + // objects with `toJSON` properties as well, *unless* they are nested + // within an object or array). + JSON3.stringify(getClass) === undef && + // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and + // FF 3.1b3 pass this test. + JSON3.stringify(undef) === undef && + // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, + // respectively, if the value is omitted entirely. + JSON3.stringify() === undef && + // FF 3.1b1, 2 throw an error if the given value is not a number, + // string, array, object, Boolean, or `null` literal. This applies to + // objects with custom `toJSON` methods as well, unless they are nested + // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` + // methods entirely. + JSON3.stringify(value) === "1" && + JSON3.stringify([value]) == "[1]" && + // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of + // `"[null]"`. + JSON3.stringify([undef]) == "[null]" && + // YUI 3.0.0b1 fails to serialize `null` literals. + JSON3.stringify(null) == "null" && + // FF 3.1b1, 2 halts serialization if an array contains a function: + // `[1, true, getClass, 1]` serializes as "[1,true,],". These versions + // of Firefox also allow trailing commas in JSON objects and arrays. + // FF 3.1b3 elides non-JSON values from objects and arrays, unless they + // define custom `toJSON` methods. + JSON3.stringify([undef, getClass, null]) == "[null,null,null]" && + // Simple serialization test. FF 3.1b1 uses Unicode escape sequences + // where character escape codes are expected (e.g., `\b` => `\u0008`). + JSON3.stringify({ "A": [value, true, false, null, "\0\b\n\f\r\t"] }) == serialized && + // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. + JSON3.stringify(null, value) === "1" && + JSON3.stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && + // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly + // serialize extended years. + JSON3.stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && + // The milliseconds are optional in ES 5, but required in 5.1. + JSON3.stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && + // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative + // four-digit years instead of six-digit years. Credits: @Yaffle. + JSON3.stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && + // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond + // values less than 1000. Credits: @Yaffle. + JSON3.stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; + } catch (exception) { + stringifySupported = false; + } + } + if (!all) { + return stringifySupported; + } + } + // Test `JSON.parse`. + if (name == "json-parse" || all) { + if (typeof JSON3.parse == "function") { + try { + // FF 3.1b1, b2 will throw an exception if a bare literal is provided. + // Conforming implementations should also coerce the initial argument to + // a string prior to parsing. + if (JSON3.parse("0") === 0 && !JSON3.parse(false)) { + // Simple parsing test. + value = JSON3.parse(serialized); + if ((parseSupported = value.A.length == 5 && value.A[0] == 1)) { + try { + // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. + parseSupported = !JSON3.parse('"\t"'); + } catch (exception) {} + if (parseSupported) { + try { + // FF 4.0 and 4.0.1 allow leading `+` signs, and leading and + // trailing decimal points. FF 4.0, 4.0.1, and IE 9-10 also + // allow certain octal literals. + parseSupported = JSON3.parse("01") != 1; + } catch (exception) {} + } + } + } + } catch (exception) { + parseSupported = false; + } + } + if (!all) { + return parseSupported; + } + } + return stringifySupported && parseSupported; + } + } + + if (!has("json")) { + // Define additional utility methods if the `Date` methods are buggy. + if (!isExtended) { + floor = Math.floor; + // A mapping between the months of the year and the number of days between + // January 1st and the first of the respective month. + Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; + // Internal: Calculates the number of days between the Unix epoch and the + // first day of the given month. + getDay = function (year, month) { + return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); + }; + } + + // Internal: Determines if a property is a direct property of the given + // object. Delegates to the native `Object#hasOwnProperty` method. + if (!(isProperty = {}.hasOwnProperty)) { + isProperty = function (property) { + var members = {}, constructor; + if ((members.__proto__ = null, members.__proto__ = { + // The *proto* property cannot be set multiple times in recent + // versions of Firefox and SeaMonkey. + "toString": 1 + }, members).toString != getClass) { + // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but + // supports the mutable *proto* property. + isProperty = function (property) { + // Capture and break the object's prototype chain (see section 8.6.2 + // of the ES 5.1 spec). The parenthesized expression prevents an + // unsafe transformation by the Closure Compiler. + var original = this.__proto__, result = property in (this.__proto__ = null, this); + // Restore the original prototype chain. + this.__proto__ = original; + return result; + }; + } else { + // Capture a reference to the top-level `Object` constructor. + constructor = members.constructor; + // Use the `constructor` property to simulate `Object#hasOwnProperty` in + // other environments. + isProperty = function (property) { + var parent = (this.constructor || constructor).prototype; + return property in this && !(property in parent && this[property] === parent[property]); + }; + } + members = null; + return isProperty.call(this, property); + }; + } + + // Internal: Normalizes the `for...in` iteration algorithm across + // environments. Each enumerated key is yielded to a `callback` function. + forEach = function (object, callback) { + var size = 0, Properties, members, property, forEach; + + // Tests for bugs in the current environment's `for...in` algorithm. The + // `valueOf` property inherits the non-enumerable flag from + // `Object.prototype` in older versions of IE, Netscape, and Mozilla. + (Properties = function () { + this.valueOf = 0; + }).prototype.valueOf = 0; + + // Iterate over a new instance of the `Properties` class. + members = new Properties(); + for (property in members) { + // Ignore all properties inherited from `Object.prototype`. + if (isProperty.call(members, property)) { + size++; + } + } + Properties = members = null; + + // Normalize the iteration algorithm. + if (!size) { + // A list of non-enumerable properties inherited from `Object.prototype`. + members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; + // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable + // properties. + forEach = function (object, callback) { + var isFunction = getClass.call(object) == "[object Function]", property, length; + for (property in object) { + // Gecko <= 1.0 enumerates the `prototype` property of functions under + // certain conditions; IE does not. + if (!(isFunction && property == "prototype") && isProperty.call(object, property)) { + callback(property); + } + } + // Manually invoke the callback for each non-enumerable property. + for (length = members.length; property = members[--length]; isProperty.call(object, property) && callback(property)); + }; + } else if (size == 2) { + // Safari <= 2.0.4 enumerates shadowed properties twice. + forEach = function (object, callback) { + // Create a set of iterated properties. + var members = {}, isFunction = getClass.call(object) == "[object Function]", property; + for (property in object) { + // Store each property name to prevent double enumeration. The + // `prototype` property of functions is not enumerated due to cross- + // environment inconsistencies. + if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { + callback(property); + } + } + }; + } else { + // No bugs detected; use the standard `for...in` algorithm. + forEach = function (object, callback) { + var isFunction = getClass.call(object) == "[object Function]", property, isConstructor; + for (property in object) { + if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { + callback(property); + } + } + // Manually invoke the callback for the `constructor` property due to + // cross-environment inconsistencies. + if (isConstructor || isProperty.call(object, (property = "constructor"))) { + callback(property); + } + }; + } + return forEach(object, callback); + }; + + // Public: Serializes a JavaScript `value` as a JSON string. The optional + // `filter` argument may specify either a function that alters how object and + // array members are serialized, or an array of strings and numbers that + // indicates which properties should be serialized. The optional `width` + // argument may be either a string or number that specifies the indentation + // level of the output. + if (!has("json-stringify")) { + // Internal: A map of control characters and their escaped equivalents. + Escapes = { + "\\": "\\\\", + '"': '\\"', + "\b": "\\b", + "\f": "\\f", + "\n": "\\n", + "\r": "\\r", + "\t": "\\t" + }; + + // Internal: Converts `value` into a zero-padded string such that its + // length is at least equal to `width`. The `width` must be <= 6. + toPaddedString = function (width, value) { + // The `|| 0` expression is necessary to work around a bug in + // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. + return ("000000" + (value || 0)).slice(-width); + }; + + // Internal: Double-quotes a string `value`, replacing all ASCII control + // characters (characters with code unit values between 0 and 31) with + // their escaped equivalents. This is an implementation of the + // `Quote(value)` operation defined in ES 5.1 section 15.12.3. + quote = function (value) { + var result = '"', index = 0, symbol; + for (; symbol = value.charAt(index); index++) { + // Escape the reverse solidus, double quote, backspace, form feed, line + // feed, carriage return, and tab characters. + result += '\\"\b\f\n\r\t'.indexOf(symbol) > -1 ? Escapes[symbol] : + // If the character is a control character, append its Unicode escape + // sequence; otherwise, append the character as-is. + (Escapes[symbol] = symbol < " " ? "\\u00" + toPaddedString(2, symbol.charCodeAt(0).toString(16)) : symbol); + } + return result + '"'; + }; + + // Internal: Recursively serializes an object. Implements the + // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. + serialize = function (property, object, callback, properties, whitespace, indentation, stack) { + var value = object[property], className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, any, result; + if (typeof value == "object" && value) { + className = getClass.call(value); + if (className == "[object Date]" && !isProperty.call(value, "toJSON")) { + if (value > -1 / 0 && value < 1 / 0) { + // Dates are serialized according to the `Date#toJSON` method + // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 + // for the ISO 8601 date time string format. + if (getDay) { + // Manually compute the year, month, date, hours, minutes, + // seconds, and milliseconds if the `getUTC*` methods are + // buggy. Adapted from @Yaffle's `date-shim` project. + date = floor(value / 864e5); + for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); + for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); + date = 1 + date - getDay(year, month); + // The `time` value specifies the time within the day (see ES + // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used + // to compute `A modulo B`, as the `%` operator does not + // correspond to the `modulo` operation for negative numbers. + time = (value % 864e5 + 864e5) % 864e5; + // The hours, minutes, seconds, and milliseconds are obtained by + // decomposing the time within the day. See section 15.9.1.10. + hours = floor(time / 36e5) % 24; + minutes = floor(time / 6e4) % 60; + seconds = floor(time / 1e3) % 60; + milliseconds = time % 1e3; + } else { + year = value.getUTCFullYear(); + month = value.getUTCMonth(); + date = value.getUTCDate(); + hours = value.getUTCHours(); + minutes = value.getUTCMinutes(); + seconds = value.getUTCSeconds(); + milliseconds = value.getUTCMilliseconds(); + } + // Serialize extended years correctly. + value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + + "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + + // Months, dates, hours, minutes, and seconds should have two + // digits; milliseconds should have three. + "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + + // Milliseconds are optional in ES 5.0, but required in 5.1. + "." + toPaddedString(3, milliseconds) + "Z"; + } else { + value = null; + } + } else if (typeof value.toJSON == "function" && ((className != "[object Number]" && className != "[object String]" && className != "[object Array]") || isProperty.call(value, "toJSON"))) { + // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the + // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 + // ignores all `toJSON` methods on these objects unless they are + // defined directly on an instance. + value = value.toJSON(property); + } + } + if (callback) { + // If a replacement function was provided, call it to obtain the value + // for serialization. + value = callback.call(object, property, value); + } + if (value === null) { + return "null"; + } + className = getClass.call(value); + if (className == "[object Boolean]") { + // Booleans are represented literally. + return "" + value; + } else if (className == "[object Number]") { + // JSON numbers must be finite. `Infinity` and `NaN` are serialized as + // `"null"`. + return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; + } else if (className == "[object String]") { + // Strings are double-quoted and escaped. + return quote(value); + } + // Recursively serialize objects and arrays. + if (typeof value == "object") { + // Check for cyclic structures. This is a linear search; performance + // is inversely proportional to the number of unique nested objects. + for (length = stack.length; length--;) { + if (stack[length] === value) { + // Cyclic structures cannot be serialized by `JSON.stringify`. + throw TypeError(); + } + } + // Add the object to the stack of traversed objects. + stack.push(value); + results = []; + // Save the current indentation level and indent one additional level. + prefix = indentation; + indentation += whitespace; + if (className == "[object Array]") { + // Recursively serialize array elements. + for (index = 0, length = value.length; index < length; any || (any = true), index++) { + element = serialize(index, value, callback, properties, whitespace, indentation, stack); + results.push(element === undef ? "null" : element); + } + result = any ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; + } else { + // Recursively serialize object members. Members are selected from + // either a user-specified list of property names, or the object + // itself. + forEach(properties || value, function (property) { + var element = serialize(property, value, callback, properties, whitespace, indentation, stack); + if (element !== undef) { + // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} + // is not the empty string, let `member` {quote(property) + ":"} + // be the concatenation of `member` and the `space` character." + // The "`space` character" refers to the literal space + // character, not the `space` {width} argument provided to + // `JSON.stringify`. + results.push(quote(property) + ":" + (whitespace ? " " : "") + element); + } + any || (any = true); + }); + result = any ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; + } + // Remove the object from the traversed object stack. + stack.pop(); + return result; + } + }; + + // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. + JSON3.stringify = function (source, filter, width) { + var whitespace, callback, properties, index, length, value; + if (typeof filter == "function" || typeof filter == "object" && filter) { + if (getClass.call(filter) == "[object Function]") { + callback = filter; + } else if (getClass.call(filter) == "[object Array]") { + // Convert the property names array into a makeshift set. + properties = {}; + for (index = 0, length = filter.length; index < length; value = filter[index++], ((getClass.call(value) == "[object String]" || getClass.call(value) == "[object Number]") && (properties[value] = 1))); + } + } + if (width) { + if (getClass.call(width) == "[object Number]") { + // Convert the `width` to an integer and create a string containing + // `width` number of space characters. + if ((width -= width % 1) > 0) { + for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); + } + } else if (getClass.call(width) == "[object String]") { + whitespace = width.length <= 10 ? width : width.slice(0, 10); + } + } + // Opera <= 7.54u2 discards the values associated with empty string keys + // (`""`) only if they are used directly within an object member list + // (e.g., `!("" in { "": 1})`). + return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); + }; + } + + // Public: Parses a JSON source string. + if (!has("json-parse")) { + fromCharCode = String.fromCharCode; + // Internal: A map of escaped control characters and their unescaped + // equivalents. + Unescapes = { + "\\": "\\", + '"': '"', + "/": "/", + "b": "\b", + "t": "\t", + "n": "\n", + "f": "\f", + "r": "\r" + }; + + // Internal: Resets the parser state and throws a `SyntaxError`. + abort = function() { + Index = Source = null; + throw SyntaxError(); + }; + + // Internal: Returns the next token, or `"$"` if the parser has reached + // the end of the source string. A token may be a string, number, `null` + // literal, or Boolean literal. + lex = function () { + var source = Source, length = source.length, symbol, value, begin, position, sign; + while (Index < length) { + symbol = source.charAt(Index); + if ("\t\r\n ".indexOf(symbol) > -1) { + // Skip whitespace tokens, including tabs, carriage returns, line + // feeds, and space characters. + Index++; + } else if ("{}[]:,".indexOf(symbol) > -1) { + // Parse a punctuator token at the current position. + Index++; + return symbol; + } else if (symbol == '"') { + // Advance to the next character and parse a JSON string at the + // current position. String tokens are prefixed with the sentinel + // `@` character to distinguish them from punctuators. + for (value = "@", Index++; Index < length;) { + symbol = source.charAt(Index); + if (symbol < " ") { + // Unescaped ASCII control characters are not permitted. + abort(); + } else if (symbol == "\\") { + // Parse escaped JSON control characters, `"`, `\`, `/`, and + // Unicode escape sequences. + symbol = source.charAt(++Index); + if ('\\"/btnfr'.indexOf(symbol) > -1) { + // Revive escaped control characters. + value += Unescapes[symbol]; + Index++; + } else if (symbol == "u") { + // Advance to the first character of the escape sequence. + begin = ++Index; + // Validate the Unicode escape sequence. + for (position = Index + 4; Index < position; Index++) { + symbol = source.charAt(Index); + // A valid sequence comprises four hexdigits that form a + // single hexadecimal value. + if (!(symbol >= "0" && symbol <= "9" || symbol >= "a" && symbol <= "f" || symbol >= "A" && symbol <= "F")) { + // Invalid Unicode escape sequence. + abort(); + } + } + // Revive the escaped character. + value += fromCharCode("0x" + source.slice(begin, Index)); + } else { + // Invalid escape sequence. + abort(); + } + } else { + if (symbol == '"') { + // An unescaped double-quote character marks the end of the + // string. + break; + } + // Append the original character as-is. + value += symbol; + Index++; + } + } + if (source.charAt(Index) == '"') { + Index++; + // Return the revived string. + return value; + } + // Unterminated string. + abort(); + } else { + // Parse numbers and literals. + begin = Index; + // Advance the scanner's position past the sign, if one is + // specified. + if (symbol == "-") { + sign = true; + symbol = source.charAt(++Index); + } + // Parse an integer or floating-point value. + if (symbol >= "0" && symbol <= "9") { + // Leading zeroes are interpreted as octal literals. + if (symbol == "0" && (symbol = source.charAt(Index + 1), symbol >= "0" && symbol <= "9")) { + // Illegal octal literal. + abort(); + } + sign = false; + // Parse the integer component. + for (; Index < length && (symbol = source.charAt(Index), symbol >= "0" && symbol <= "9"); Index++); + // Floats cannot contain a leading decimal point; however, this + // case is already accounted for by the parser. + if (source.charAt(Index) == ".") { + position = ++Index; + // Parse the decimal component. + for (; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++); + if (position == Index) { + // Illegal trailing decimal. + abort(); + } + Index = position; + } + // Parse exponents. + symbol = source.charAt(Index); + if (symbol == "e" || symbol == "E") { + // Skip past the sign following the exponent, if one is + // specified. + symbol = source.charAt(++Index); + if (symbol == "+" || symbol == "-") { + Index++; + } + // Parse the exponential component. + for (position = Index; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++); + if (position == Index) { + // Illegal empty exponent. + abort(); + } + Index = position; + } + // Coerce the parsed value to a JavaScript number. + return +source.slice(begin, Index); + } + // A negative sign may only precede numbers. + if (sign) { + abort(); + } + // `true`, `false`, and `null` literals. + if (source.slice(Index, Index + 4) == "true") { + Index += 4; + return true; + } else if (source.slice(Index, Index + 5) == "false") { + Index += 5; + return false; + } else if (source.slice(Index, Index + 4) == "null") { + Index += 4; + return null; + } + // Unrecognized token. + abort(); + } + } + // Return the sentinel `$` character if the parser has reached the end + // of the source string. + return "$"; + }; + + // Internal: Parses a JSON `value` token. + get = function (value) { + var results, any, key; + if (value == "$") { + // Unexpected end of input. + abort(); + } + if (typeof value == "string") { + if (value.charAt(0) == "@") { + // Remove the sentinel `@` character. + return value.slice(1); + } + // Parse object and array literals. + if (value == "[") { + // Parses a JSON array, returning a new JavaScript array. + results = []; + for (;; any || (any = true)) { + value = lex(); + // A closing square bracket marks the end of the array literal. + if (value == "]") { + break; + } + // If the array literal contains elements, the current token + // should be a comma separating the previous element from the + // next. + if (any) { + if (value == ",") { + value = lex(); + if (value == "]") { + // Unexpected trailing `,` in array literal. + abort(); + } + } else { + // A `,` must separate each array element. + abort(); + } + } + // Elisions and leading commas are not permitted. + if (value == ",") { + abort(); + } + results.push(get(value)); + } + return results; + } else if (value == "{") { + // Parses a JSON object, returning a new JavaScript object. + results = {}; + for (;; any || (any = true)) { + value = lex(); + // A closing curly brace marks the end of the object literal. + if (value == "}") { + break; + } + // If the object literal contains members, the current token + // should be a comma separator. + if (any) { + if (value == ",") { + value = lex(); + if (value == "}") { + // Unexpected trailing `,` in object literal. + abort(); + } + } else { + // A `,` must separate each object member. + abort(); + } + } + // Leading commas are not permitted, object property names must be + // double-quoted strings, and a `:` must separate each property + // name and value. + if (value == "," || typeof value != "string" || value.charAt(0) != "@" || lex() != ":") { + abort(); + } + results[value.slice(1)] = get(lex()); + } + return results; + } + // Unexpected token encountered. + abort(); + } + return value; + }; + + // Internal: Updates a traversed object member. + update = function(source, property, callback) { + var element = walk(source, property, callback); + if (element === undef) { + delete source[property]; + } else { + source[property] = element; + } + }; + + // Internal: Recursively traverses a parsed JSON object, invoking the + // `callback` function for each value. This is an implementation of the + // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. + walk = function (source, property, callback) { + var value = source[property], length; + if (typeof value == "object" && value) { + if (getClass.call(value) == "[object Array]") { + for (length = value.length; length--;) { + update(value, length, callback); + } + } else { + // `forEach` can't be used to traverse an array in Opera <= 8.54, + // as `Object#hasOwnProperty` returns `false` for array indices + // (e.g., `![1, 2, 3].hasOwnProperty("0")`). + forEach(value, function (property) { + update(value, property, callback); + }); + } + } + return callback.call(source, property, value); + }; + + // Public: `JSON.parse`. See ES 5.1 section 15.12.2. + JSON3.parse = function (source, callback) { + var result, value; + Index = 0; + Source = source; + result = get(lex()); + // If a JSON string contains multiple tokens, it is invalid. + if (lex() != "$") { + abort(); + } + // Reset the parser state. + Index = Source = null; + return callback && getClass.call(callback) == "[object Function]" ? walk((value = {}, value[""] = result, value), "", callback) : result; + }; + } + } + + // Export for asynchronous module loaders. + if (isLoader) { + define(function () { + return JSON3; + }); + } +}).call(this); \ No newline at end of file diff --git a/vendor/underscore/test/vendor/jslitmus.js b/vendor/underscore/test/vendor/jslitmus.js deleted file mode 100644 index a0e9f806fa..0000000000 --- a/vendor/underscore/test/vendor/jslitmus.js +++ /dev/null @@ -1,670 +0,0 @@ -// JSLitmus.js -// -// History: -// 2008-10-27: Initial release -// 2008-11-09: Account for iteration loop overhead -// 2008-11-13: Added OS detection -// 2009-02-25: Create tinyURL automatically, shift-click runs tests in reverse -// -// Copyright (c) 2008-2009, Robert Kieffer -// All Rights Reserved -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the -// Software), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -(function() { - // Private methods and state - - // Get platform info but don't go crazy trying to recognize everything - // that's out there. This is just for the major platforms and OSes. - var platform = 'unknown platform', ua = navigator.userAgent; - - // Detect OS - var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|'); - var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null; - if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null; - - // Detect browser - var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null; - - // Detect version - var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)'); - var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null; - var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform'; - - /** - * A smattering of methods that are needed to implement the JSLitmus testbed. - */ - var jsl = { - /** - * Enhanced version of escape() - */ - escape: function(s) { - s = s.replace(/,/g, '\\,'); - s = escape(s); - s = s.replace(/\+/g, '%2b'); - s = s.replace(/ /g, '+'); - return s; - }, - - /** - * Get an element by ID. - */ - $: function(id) { - return document.getElementById(id); - }, - - /** - * Null function - */ - F: function() {}, - - /** - * Set the status shown in the UI - */ - status: function(msg) { - var el = jsl.$('jsl_status'); - if (el) el.innerHTML = msg || ''; - }, - - /** - * Convert a number to an abbreviated string like, "15K" or "10M" - */ - toLabel: function(n) { - if (n == Infinity) { - return 'Infinity'; - } else if (n > 1e9) { - n = Math.round(n/1e8); - return n/10 + 'B'; - } else if (n > 1e6) { - n = Math.round(n/1e5); - return n/10 + 'M'; - } else if (n > 1e3) { - n = Math.round(n/1e2); - return n/10 + 'K'; - } - return n; - }, - - /** - * Copy properties from src to dst - */ - extend: function(dst, src) { - for (var k in src) dst[k] = src[k]; return dst; - }, - - /** - * Like Array.join(), but for the key-value pairs in an object - */ - join: function(o, delimit1, delimit2) { - if (o.join) return o.join(delimit1); // If it's an array - var pairs = []; - for (var k in o) pairs.push(k + delimit1 + o[k]); - return pairs.join(delimit2); - }, - - /** - * Array#indexOf isn't supported in IE, so we use this as a cross-browser solution - */ - indexOf: function(arr, o) { - if (arr.indexOf) return arr.indexOf(o); - for (var i = 0; i < this.length; i++) if (arr[i] === o) return i; - return -1; - } - }; - - /** - * Test manages a single test (created with - * JSLitmus.test()) - * - * @private - */ - var Test = function (name, f) { - if (!f) throw new Error('Undefined test function'); - if (!(/function[^\(]*\(([^,\)]*)/).test(f.toString())) { - throw new Error('"' + name + '" test: Test is not a valid Function object'); - } - this.loopArg = RegExp.$1; - this.name = name; - this.f = f; - }; - - jsl.extend(Test, /** @lends Test */ { - /** Calibration tests for establishing iteration loop overhead */ - CALIBRATIONS: [ - new Test('calibrating loop', function(count) {while (count--);}), - new Test('calibrating function', jsl.F) - ], - - /** - * Run calibration tests. Returns true if calibrations are not yet - * complete (in which case calling code should run the tests yet again). - * onCalibrated - Callback to invoke when calibrations have finished - */ - calibrate: function(onCalibrated) { - for (var i = 0; i < Test.CALIBRATIONS.length; i++) { - var cal = Test.CALIBRATIONS[i]; - if (cal.running) return true; - if (!cal.count) { - cal.isCalibration = true; - cal.onStop = onCalibrated; - //cal.MIN_TIME = .1; // Do calibrations quickly - cal.run(2e4); - return true; - } - } - return false; - } - }); - - jsl.extend(Test.prototype, {/** @lends Test.prototype */ - /** Initial number of iterations */ - INIT_COUNT: 10, - /** Max iterations allowed (i.e. used to detect bad looping functions) */ - MAX_COUNT: 1e9, - /** Minimum time a test should take to get valid results (secs) */ - MIN_TIME: .5, - - /** Callback invoked when test state changes */ - onChange: jsl.F, - - /** Callback invoked when test is finished */ - onStop: jsl.F, - - /** - * Reset test state - */ - reset: function() { - delete this.count; - delete this.time; - delete this.running; - delete this.error; - }, - - /** - * Run the test (in a timeout). We use a timeout to make sure the browser - * has a chance to finish rendering any UI changes we've made, like - * updating the status message. - */ - run: function(count) { - count = count || this.INIT_COUNT; - jsl.status(this.name + ' x ' + count); - this.running = true; - var me = this; - setTimeout(function() {me._run(count);}, 200); - }, - - /** - * The nuts and bolts code that actually runs a test - */ - _run: function(count) { - var me = this; - - // Make sure calibration tests have run - if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return; - this.error = null; - - try { - var start, f = this.f, now, i = count; - - // Start the timer - start = new Date(); - - // Now for the money shot. If this is a looping function ... - if (this.loopArg) { - // ... let it do the iteration itself - f(count); - } else { - // ... otherwise do the iteration for it - while (i--) f(); - } - - // Get time test took (in secs) - this.time = Math.max(1,new Date() - start)/1000; - - // Store iteration count and per-operation time taken - this.count = count; - this.period = this.time/count; - - // Do we need to do another run? - this.running = this.time <= this.MIN_TIME; - - // ... if so, compute how many times we should iterate - if (this.running) { - // Bump the count to the nearest power of 2 - var x = this.MIN_TIME/this.time; - var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2)))); - count *= pow; - if (count > this.MAX_COUNT) { - throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.'); - } - } - } catch (e) { - // Exceptions are caught and displayed in the test UI - this.reset(); - this.error = e; - } - - // Figure out what to do next - if (this.running) { - me.run(count); - } else { - jsl.status(''); - me.onStop(me); - } - - // Finish up - this.onChange(this); - }, - - /** - * Get the number of operations per second for this test. - * - * @param normalize if true, iteration loop overhead taken into account - */ - getHz: function(/**Boolean*/ normalize) { - var p = this.period; - - // Adjust period based on the calibration test time - if (normalize && !this.isCalibration) { - var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1]; - - // If the period is within 20% of the calibration time, then zero the - // it out - p = p < cal.period*1.2 ? 0 : p - cal.period; - } - - return Math.round(1/p); - }, - - /** - * Get a friendly string describing the test - */ - toString: function() { - return this.name + ' - ' + this.time/this.count + ' secs'; - } - }); - - // CSS we need for the UI - var STYLESHEET = ''; - - // HTML markup for the UI - var MARKUP = '
    \ - \ - \ -
    \ -
    \ - Normalize results \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -
    ' + platform + '
    TestOps/sec
    \ -
    \ - \ - Powered by JSLitmus \ -
    '; - - /** - * The public API for creating and running tests - */ - window.JSLitmus = { - /** The list of all tests that have been registered with JSLitmus.test */ - _tests: [], - /** The queue of tests that need to be run */ - _queue: [], - - /** - * The parsed query parameters the current page URL. This is provided as a - * convenience for test functions - it's not used by JSLitmus proper - */ - params: {}, - - /** - * Initialize - */ - _init: function() { - // Parse query params into JSLitmus.params[] hash - var match = (location + '').match(/([^?#]*)(#.*)?$/); - if (match) { - var pairs = match[1].split('&'); - for (var i = 0; i < pairs.length; i++) { - var pair = pairs[i].split('='); - if (pair.length > 1) { - var key = pair.shift(); - var value = pair.length > 1 ? pair.join('=') : pair[0]; - this.params[key] = value; - } - } - } - - // Write out the stylesheet. We have to do this here because IE - // doesn't honor sheets written after the document has loaded. - document.write(STYLESHEET); - - // Setup the rest of the UI once the document is loaded - if (window.addEventListener) { - window.addEventListener('load', this._setup, false); - } else if (document.addEventListener) { - document.addEventListener('load', this._setup, false); - } else if (window.attachEvent) { - window.attachEvent('onload', this._setup); - } - - return this; - }, - - /** - * Set up the UI - */ - _setup: function() { - var el = jsl.$('jslitmus_container'); - if (!el) document.body.appendChild(el = document.createElement('div')); - - el.innerHTML = MARKUP; - - // Render the UI for all our tests - for (var i=0; i < JSLitmus._tests.length; i++) - JSLitmus.renderTest(JSLitmus._tests[i]); - }, - - /** - * (Re)render all the test results - */ - renderAll: function() { - for (var i = 0; i < JSLitmus._tests.length; i++) - JSLitmus.renderTest(JSLitmus._tests[i]); - JSLitmus.renderChart(); - }, - - /** - * (Re)render the chart graphics - */ - renderChart: function() { - var url = JSLitmus.chartUrl(); - jsl.$('chart_link').href = url; - jsl.$('chart_image').src = url; - jsl.$('chart').style.display = ''; - - // Update the tiny URL - jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url); - }, - - /** - * (Re)render the results for a specific test - */ - renderTest: function(test) { - // Make a new row if needed - if (!test._row) { - var trow = jsl.$('test_row_template'); - if (!trow) return; - - test._row = trow.cloneNode(true); - test._row.style.display = ''; - test._row.id = ''; - test._row.onclick = function() {JSLitmus._queueTest(test);}; - test._row.title = 'Run ' + test.name + ' test'; - trow.parentNode.appendChild(test._row); - test._row.cells[0].innerHTML = test.name; - } - - var cell = test._row.cells[1]; - var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping']; - - if (test.error) { - cns.push('test_error'); - cell.innerHTML = - '
    ' + test.error + '
    ' + - '
    • ' + - jsl.join(test.error, ': ', '
    • ') + - '
    '; - } else { - if (test.running) { - cns.push('test_running'); - cell.innerHTML = 'running'; - } else if (jsl.indexOf(JSLitmus._queue, test) >= 0) { - cns.push('test_pending'); - cell.innerHTML = 'pending'; - } else if (test.count) { - cns.push('test_done'); - var hz = test.getHz(jsl.$('test_normalize').checked); - cell.innerHTML = hz != Infinity ? hz : '∞'; - } else { - cell.innerHTML = 'ready'; - } - } - cell.className = cns.join(' '); - }, - - /** - * Create a new test - */ - test: function(name, f) { - // Create the Test object - var test = new Test(name, f); - JSLitmus._tests.push(test); - - // Re-render if the test state changes - test.onChange = JSLitmus.renderTest; - - // Run the next test if this one finished - test.onStop = function(test) { - if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test); - JSLitmus.currentTest = null; - JSLitmus._nextTest(); - }; - - // Render the new test - this.renderTest(test); - }, - - /** - * Add all tests to the run queue - */ - runAll: function(e) { - e = e || window.event; - var reverse = e && e.shiftKey, len = JSLitmus._tests.length; - for (var i = 0; i < len; i++) { - JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]); - } - }, - - /** - * Remove all tests from the run queue. The current test has to finish on - * it's own though - */ - stop: function() { - while (JSLitmus._queue.length) { - var test = JSLitmus._queue.shift(); - JSLitmus.renderTest(test); - } - }, - - /** - * Run the next test in the run queue - */ - _nextTest: function() { - if (!JSLitmus.currentTest) { - var test = JSLitmus._queue.shift(); - if (test) { - jsl.$('stop_button').disabled = false; - JSLitmus.currentTest = test; - test.run(); - JSLitmus.renderTest(test); - if (JSLitmus.onTestStart) JSLitmus.onTestStart(test); - } else { - jsl.$('stop_button').disabled = true; - JSLitmus.renderChart(); - } - } - }, - - /** - * Add a test to the run queue - */ - _queueTest: function(test) { - if (jsl.indexOf(JSLitmus._queue, test) >= 0) return; - JSLitmus._queue.push(test); - JSLitmus.renderTest(test); - JSLitmus._nextTest(); - }, - - /** - * Generate a Google Chart URL that shows the data for all tests - */ - chartUrl: function() { - var n = JSLitmus._tests.length, markers = [], data = []; - var d, min = 0, max = -1e10; - var normalize = jsl.$('test_normalize').checked; - - // Gather test data - for (var i=0; i < JSLitmus._tests.length; i++) { - var test = JSLitmus._tests[i]; - if (test.count) { - var hz = test.getHz(normalize); - var v = hz != Infinity ? hz : 0; - data.push(v); - markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' + - markers.length + ',10'); - max = Math.max(v, max); - } - } - if (markers.length <= 0) return null; - - // Build chart title - var title = document.getElementsByTagName('title'); - title = (title && title.length) ? title[0].innerHTML : null; - var chart_title = []; - if (title) chart_title.push(title); - chart_title.push('Ops/sec (' + platform + ')'); - - // Build labels - var labels = [jsl.toLabel(min), jsl.toLabel(max)]; - - var w = 250, bw = 15; - var bs = 5; - var h = markers.length*(bw + bs) + 30 + chart_title.length*20; - - var params = { - chtt: escape(chart_title.join('|')), - chts: '000000,10', - cht: 'bhg', // chart type - chd: 't:' + data.join(','), // data set - chds: min + ',' + max, // max/min of data - chxt: 'x', // label axes - chxl: '0:|' + labels.join('|'), // labels - chsp: '0,1', - chm: markers.join('|'), // test names - chbh: [bw, 0, bs].join(','), // bar widths - // chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient - chs: w + 'x' + h - }; - return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&'); - } - }; - - JSLitmus._init(); -})(); \ No newline at end of file From 10c87012bec17192318cb123a84ee25fe8530b41 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 00:01:29 -0700 Subject: [PATCH 07/79] Update vendor/underscore. Former-commit-id: 5ede87579d9b7a8e505da23fc3a4531be40a151b --- vendor/underscore/test/collections.js | 8 ++++++++ vendor/underscore/underscore-min.js | 2 +- vendor/underscore/underscore.js | 9 +++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/vendor/underscore/test/collections.js b/vendor/underscore/test/collections.js index 7dce44ba51..e089626dfd 100644 --- a/vendor/underscore/test/collections.js +++ b/vendor/underscore/test/collections.js @@ -171,6 +171,14 @@ $(document).ready(function() { test('reject', function() { var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); + + var context = "obj"; + + var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){ + equal(context, "obj"); + return num % 2 != 0; + }, context); + equal(evens.join(', '), '2, 4, 6', 'rejected each odd number'); }); test('all', function() { diff --git a/vendor/underscore/underscore-min.js b/vendor/underscore/underscore-min.js index 448bf171d5..fd137df572 100644 --- a/vendor/underscore/underscore-min.js +++ b/vendor/underscore/underscore-min.js @@ -2,4 +2,4 @@ // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. -(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=r.unshift,l=i.toString,c=i.hasOwnProperty,h=r.forEach,p=r.map,d=r.reduce,v=r.reduceRight,m=r.filter,g=r.every,y=r.some,b=r.indexOf,w=r.lastIndexOf,E=Array.isArray,S=Object.keys,x=s.bind,T=function(e){if(e instanceof T)return e;if(!(this instanceof T))return new T(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=T),exports._=T):e._=T,T.VERSION="1.4.2";var N=T.each=T.forEach=function(e,t,r){if(e==null)return;if(h&&e.forEach===h)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i2;e==null&&(e=[]);if(d&&e.reduce===d)return r&&(t=T.bind(t,r)),i?e.reduce(t,n):e.reduce(t);N(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.reduceRight=T.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(v&&e.reduceRight===v)return r&&(t=T.bind(t,r)),arguments.length>2?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=T.keys(e);s=o.length}N(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.find=T.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},T.filter=T.select=function(e,t,n){var r=[];return e==null?r:m&&e.filter===m?e.filter(t,n):(N(e,function(e,i,s){t.call(n,e,i,s)&&(r[r.length]=e)}),r)},T.reject=function(e,t,n){var r=[];return e==null?r:(N(e,function(e,i,s){t.call(n,e,i,s)||(r[r.length]=e)}),r)},T.every=T.all=function(e,t,r){t||(t=T.identity);var i=!0;return e==null?i:g&&e.every===g?e.every(t,r):(N(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=T.some=T.any=function(e,t,r){t||(t=T.identity);var i=!1;return e==null?i:y&&e.some===y?e.some(t,r):(N(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};T.contains=T.include=function(e,t){var n=!1;return e==null?n:b&&e.indexOf===b?e.indexOf(t)!=-1:(n=C(e,function(e){return e===t}),n)},T.invoke=function(e,t){var n=u.call(arguments,2);return T.map(e,function(e){return(T.isFunction(t)?t:e[t]).apply(e,n)})},T.pluck=function(e,t){return T.map(e,function(e){return e[t]})},T.where=function(e,t){return T.isEmpty(t)?[]:T.filter(e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},T.max=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&T.isEmpty(e))return-Infinity;var r={computed:-Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},T.min=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&T.isEmpty(e))return Infinity;var r={computed:Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;or||n===void 0)return 1;if(n>>1;n.call(r,e[u])=0})})},T.difference=function(e){var t=a.apply(r,u.call(arguments,1));return T.filter(e,function(e){return!T.contains(t,e)})},T.zip=function(){var e=u.call(arguments),t=T.max(T.pluck(e,"length")),n=new Array(t);for(var r=0;r=0;n--)t=[e[n].apply(this,t)];return t[0]}},T.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},T.keys=S||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)T.has(e,n)&&(t[t.length]=n);return t},T.values=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push(e[n]);return t},T.pairs=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push([n,e[n]]);return t},T.invert=function(e){var t={};for(var n in e)T.has(e,n)&&(t[e[n]]=n);return t},T.functions=T.methods=function(e){var t=[];for(var n in e)T.isFunction(e[n])&&t.push(n);return t.sort()},T.extend=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]=t[n]}),e},T.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return N(n,function(n){n in e&&(t[n]=e[n])}),t},T.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)T.contains(n,i)||(t[i]=e[i]);return t},T.defaults=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]==null&&(e[n]=t[n])}),e},T.clone=function(e){return T.isObject(e)?T.isArray(e)?e.slice():T.extend({},e):e},T.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof T&&(e=e._wrapped),t instanceof T&&(t=t._wrapped);var i=l.call(e);if(i!=l.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,f=t.constructor;if(a!==f&&!(T.isFunction(a)&&a instanceof a&&T.isFunction(f)&&f instanceof f))return!1;for(var c in e)if(T.has(e,c)){o++;if(!(u=T.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(T.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};T.isEqual=function(e,t){return M(e,t,[],[])},T.isEmpty=function(e){if(e==null)return!0;if(T.isArray(e)||T.isString(e))return e.length===0;for(var t in e)if(T.has(e,t))return!1;return!0},T.isElement=function(e){return!!e&&e.nodeType===1},T.isArray=E||function(e){return l.call(e)=="[object Array]"},T.isObject=function(e){return e===Object(e)},N(["Arguments","Function","String","Number","Date","RegExp"],function(e){T["is"+e]=function(t){return l.call(t)=="[object "+e+"]"}}),T.isArguments(arguments)||(T.isArguments=function(e){return!!e&&!!T.has(e,"callee")}),typeof /./!="function"&&(T.isFunction=function(e){return typeof e=="function"}),T.isFinite=function(e){return T.isNumber(e)&&isFinite(e)},T.isNaN=function(e){return T.isNumber(e)&&e!=+e},T.isBoolean=function(e){return e===!0||e===!1||l.call(e)=="[object Boolean]"},T.isNull=function(e){return e===null},T.isUndefined=function(e){return e===void 0},T.has=function(e,t){return c.call(e,t)},T.noConflict=function(){return e._=t,this},T.identity=function(e){return e},T.times=function(e,t,n){for(var r=0;r":">",'"':""","'":"'","/":"/"}};_.unescape=T.invert(_.escape);var D={escape:new RegExp("["+T.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+T.keys(_.unescape).join("|")+")","g")};T.each(["escape","unescape"],function(e){T[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),T.result=function(e,t){if(e==null)return null;var n=e[t];return T.isFunction(n)?n.call(e):n},T.mixin=function(e){N(T.functions(e),function(t){var n=T[t]=e[t];T.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(T,e))}})};var P=0;T.uniqueId=function(e){var t=P++;return e?e+t:t},T.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;T.template=function(e,t,n){n=T.defaults({},n,T.templateSettings);var r=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),i=0,s="__p+='";e.replace(r,function(t,n,r,o,u){s+=e.slice(i,u).replace(j,function(e){return"\\"+B[e]}),s+=n?"'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":r?"'+\n((__t=("+r+"))==null?'':__t)+\n'":o?"';\n"+o+"\n__p+='":"",i=u+t.length}),s+="';\n",n.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n";try{var o=new Function(n.variable||"obj","_",s)}catch(u){throw u.source=s,u}if(t)return o(t,T);var a=function(e){return o.call(this,e,T)};return a.source="function("+(n.variable||"obj")+"){\n"+s+"}",a},T.chain=function(e){return T(e).chain()};var F=function(e){return this._chain?T(e).chain():e};T.mixin(T),N(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];T.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),N(["concat","join","slice"],function(e){var t=r[e];T.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),T.extend(T.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); \ No newline at end of file +(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=r.unshift,l=i.toString,c=i.hasOwnProperty,h=r.forEach,p=r.map,d=r.reduce,v=r.reduceRight,m=r.filter,g=r.every,y=r.some,b=r.indexOf,w=r.lastIndexOf,E=Array.isArray,S=Object.keys,x=s.bind,T=function(e){if(e instanceof T)return e;if(!(this instanceof T))return new T(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=T),exports._=T):e._=T,T.VERSION="1.4.2";var N=T.each=T.forEach=function(e,t,r){if(e==null)return;if(h&&e.forEach===h)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i2;e==null&&(e=[]);if(d&&e.reduce===d)return r&&(t=T.bind(t,r)),i?e.reduce(t,n):e.reduce(t);N(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.reduceRight=T.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(v&&e.reduceRight===v)return r&&(t=T.bind(t,r)),arguments.length>2?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=T.keys(e);s=o.length}N(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.find=T.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},T.filter=T.select=function(e,t,n){var r=[];return e==null?r:m&&e.filter===m?e.filter(t,n):(N(e,function(e,i,s){t.call(n,e,i,s)&&(r[r.length]=e)}),r)},T.reject=function(e,t,n){return T.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},T.every=T.all=function(e,t,r){t||(t=T.identity);var i=!0;return e==null?i:g&&e.every===g?e.every(t,r):(N(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=T.some=T.any=function(e,t,r){t||(t=T.identity);var i=!1;return e==null?i:y&&e.some===y?e.some(t,r):(N(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};T.contains=T.include=function(e,t){var n=!1;return e==null?n:b&&e.indexOf===b?e.indexOf(t)!=-1:(n=C(e,function(e){return e===t}),n)},T.invoke=function(e,t){var n=u.call(arguments,2);return T.map(e,function(e){return(T.isFunction(t)?t:e[t]).apply(e,n)})},T.pluck=function(e,t){return T.map(e,function(e){return e[t]})},T.where=function(e,t){return T.isEmpty(t)?[]:T.filter(e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},T.max=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&T.isEmpty(e))return-Infinity;var r={computed:-Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},T.min=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&T.isEmpty(e))return Infinity;var r={computed:Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;or||n===void 0)return 1;if(n>>1;n.call(r,e[u])=0})})},T.difference=function(e){var t=a.apply(r,u.call(arguments,1));return T.filter(e,function(e){return!T.contains(t,e)})},T.zip=function(){var e=u.call(arguments),t=T.max(T.pluck(e,"length")),n=new Array(t);for(var r=0;r=0;n--)t=[e[n].apply(this,t)];return t[0]}},T.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},T.keys=S||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)T.has(e,n)&&(t[t.length]=n);return t},T.values=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push(e[n]);return t},T.pairs=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push([n,e[n]]);return t},T.invert=function(e){var t={};for(var n in e)T.has(e,n)&&(t[e[n]]=n);return t},T.functions=T.methods=function(e){var t=[];for(var n in e)T.isFunction(e[n])&&t.push(n);return t.sort()},T.extend=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]=t[n]}),e},T.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return N(n,function(n){n in e&&(t[n]=e[n])}),t},T.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)T.contains(n,i)||(t[i]=e[i]);return t},T.defaults=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]==null&&(e[n]=t[n])}),e},T.clone=function(e){return T.isObject(e)?T.isArray(e)?e.slice():T.extend({},e):e},T.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof T&&(e=e._wrapped),t instanceof T&&(t=t._wrapped);var i=l.call(e);if(i!=l.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,f=t.constructor;if(a!==f&&!(T.isFunction(a)&&a instanceof a&&T.isFunction(f)&&f instanceof f))return!1;for(var c in e)if(T.has(e,c)){o++;if(!(u=T.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(T.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};T.isEqual=function(e,t){return M(e,t,[],[])},T.isEmpty=function(e){if(e==null)return!0;if(T.isArray(e)||T.isString(e))return e.length===0;for(var t in e)if(T.has(e,t))return!1;return!0},T.isElement=function(e){return!!e&&e.nodeType===1},T.isArray=E||function(e){return l.call(e)=="[object Array]"},T.isObject=function(e){return e===Object(e)},N(["Arguments","Function","String","Number","Date","RegExp"],function(e){T["is"+e]=function(t){return l.call(t)=="[object "+e+"]"}}),T.isArguments(arguments)||(T.isArguments=function(e){return!!e&&!!T.has(e,"callee")}),typeof /./!="function"&&(T.isFunction=function(e){return typeof e=="function"}),T.isFinite=function(e){return T.isNumber(e)&&isFinite(e)},T.isNaN=function(e){return T.isNumber(e)&&e!=+e},T.isBoolean=function(e){return e===!0||e===!1||l.call(e)=="[object Boolean]"},T.isNull=function(e){return e===null},T.isUndefined=function(e){return e===void 0},T.has=function(e,t){return c.call(e,t)},T.noConflict=function(){return e._=t,this},T.identity=function(e){return e},T.times=function(e,t,n){for(var r=0;r":">",'"':""","'":"'","/":"/"}};_.unescape=T.invert(_.escape);var D={escape:new RegExp("["+T.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+T.keys(_.unescape).join("|")+")","g")};T.each(["escape","unescape"],function(e){T[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),T.result=function(e,t){if(e==null)return null;var n=e[t];return T.isFunction(n)?n.call(e):n},T.mixin=function(e){N(T.functions(e),function(t){var n=T[t]=e[t];T.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(T,e))}})};var P=0;T.uniqueId=function(e){var t=P++;return e?e+t:t},T.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;T.template=function(e,t,n){n=T.defaults({},n,T.templateSettings);var r=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),i=0,s="__p+='";e.replace(r,function(t,n,r,o,u){s+=e.slice(i,u).replace(j,function(e){return"\\"+B[e]}),s+=n?"'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":r?"'+\n((__t=("+r+"))==null?'':__t)+\n'":o?"';\n"+o+"\n__p+='":"",i=u+t.length}),s+="';\n",n.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n";try{var o=new Function(n.variable||"obj","_",s)}catch(u){throw u.source=s,u}if(t)return o(t,T);var a=function(e){return o.call(this,e,T)};return a.source="function("+(n.variable||"obj")+"){\n"+s+"}",a},T.chain=function(e){return T(e).chain()};var F=function(e){return this._chain?T(e).chain():e};T.mixin(T),N(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];T.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),N(["concat","join","slice"],function(e){var t=r[e];T.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),T.extend(T.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); \ No newline at end of file diff --git a/vendor/underscore/underscore.js b/vendor/underscore/underscore.js index 617092d898..65b59c0cd7 100644 --- a/vendor/underscore/underscore.js +++ b/vendor/underscore/underscore.js @@ -177,12 +177,9 @@ // Return all the elements for which a truth test fails. _.reject = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - each(obj, function(value, index, list) { - if (!iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; + return _.filter(obj, function(value, index, list) { + return !iterator.call(context, value, index, list); + }, context); }; // Determine whether all of the elements match a truth test. From 1dda31a28c658e56a8effdb44b3e5605dba840ee Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 00:03:40 -0700 Subject: [PATCH 08/79] Make remove compiling from _.merge, _.countBy, _.groupBy, _.pick, _.omit, and _.sortBy. Former-commit-id: 52b245e69629e7a9fbe5f0dcbdfafabcd75d9dfc --- build.js | 17 ++- build/pre-compile.js | 57 ++-------- lodash.js | 242 +++++++++++++++++++++++-------------------- 3 files changed, 145 insertions(+), 171 deletions(-) diff --git a/build.js b/build.js index ce222f73b1..78f6740a14 100755 --- a/build.js +++ b/build.js @@ -71,7 +71,7 @@ 'compact': [], 'compose': [], 'contains': [], - 'countBy': ['identity'], + 'countBy': ['forEach', 'identity'], 'debounce': [], 'defaults': ['isArguments'], 'defer': [], @@ -88,7 +88,7 @@ 'forIn': ['identity', 'isArguments'], 'forOwn': ['identity', 'isArguments'], 'functions': ['isArguments', 'isFunction'], - 'groupBy': ['identity'], + 'groupBy': ['forEach', 'identity'], 'has': [], 'identity': [], 'indexOf': ['sortedIndex'], @@ -120,16 +120,16 @@ 'map': ['identity'], 'max': ['forEach'], 'memoize': [], - 'merge': ['isArray', 'isPlainObject'], + 'merge': ['forOwn', 'isArray', 'isPlainObject'], 'min': ['forEach'], 'mixin': ['forEach', 'functions'], 'noConflict': [], 'object': [], - 'omit': ['indexOf', 'isArguments'], + 'omit': ['forIn', 'indexOf', 'isArguments'], 'once': [], 'pairs': [], 'partial': ['isFunction'], - 'pick': [], + 'pick': ['forIn'], 'pluck': [], 'random': [], 'range': [], @@ -141,7 +141,7 @@ 'shuffle': ['forEach'], 'size': ['keys'], 'some': ['identity'], - 'sortBy': ['identity'], + 'sortBy': ['forEach', 'identity'], 'sortedIndex': ['identity'], 'tap': ['mixin'], 'template': ['escape'], @@ -1247,11 +1247,6 @@ source = source.replace(reFunc, '$1' + getFunctionSource(lodash[methodName]) + ';\n'); }); - // replace `callee` in `_.merge` with `merge` - source = source.replace(matchFunction(source, 'merge'), function(match) { - return match.replace(/\bcallee\b/g, 'merge'); - }); - if (isUnderscore) { // remove "compiled template cleanup" from `_.template` source = source.replace(/(?:\s*\/\/.*)*\n *source *=.+?isEvaluating.+?reEmptyStringLeading[\s\S]+?\);/, ''); diff --git a/build/pre-compile.js b/build/pre-compile.js index b63f6cec10..3d2afa552c 100644 --- a/build/pre-compile.js +++ b/build/pre-compile.js @@ -11,7 +11,6 @@ 'argsLength', 'callback', 'collection', - 'concat', 'createCallback', 'ctor', 'hasOwnProperty', @@ -36,38 +35,22 @@ 'value', // lesser used variables - 'accumulator', 'args', 'arrayLikeClasses', - 'ArrayProto', 'bind', - 'callee', 'className', - 'compareAscending', 'forIn', - 'found', 'funcs', - 'indexOf', - 'indicator', 'isArguments', - 'isArr', - 'isArray', 'isFunc', 'isFunction', - 'isPlainObject', 'methodName', - 'noaccum', - 'noop', 'objectClass', 'objectTypes', 'pass', 'properties', 'property', 'propsLength', - 'source', - 'stackA', - 'stackB', - 'stackLength', 'target' ]; @@ -310,15 +293,13 @@ // minify internal properties used by 'compareAscending', `_.merge`, and `_.sortBy` (function() { var properties = ['criteria', 'index', 'value'], - snippets = source.match(/( +)(?:function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g); + snippets = source.match(/( +)function (?:compareAscending|merge|sortBy)\b[\s\S]+?\n\1}/g); if (!snippets) { return; } snippets.forEach(function(snippet) { - var modified = snippet, - isCompilable = /(?:var merge|var sortBy)\b/.test(modified), - isInlined = !/\bcreateIterator\b/.test(modified); + var modified = snippet; // minify properties properties.forEach(function(property, index) { @@ -326,32 +307,14 @@ reDotProp = RegExp('\\.' + property + '\\b', 'g'), rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + property + "\\2 *:", 'g'); - if (isCompilable) { - // add quotes around properties in the inlined `_.merge` and `_.sortBy` - // of the mobile build so Closure Compiler won't mung them - if (isInlined) { - modified = modified - .replace(reBracketProp, "['" + minNames[index] + "']") - .replace(reDotProp, "['" + minNames[index] + "']") - .replace(rePropColon, "$1'" + minNames[index] + "':"); - } - else { - modified = modified - .replace(reBracketProp, '.' + minNames[index]) - .replace(reDotProp, '.' + minNames[index]) - .replace(rePropColon, '$1' + minNames[index] + ':'); - } - } - else { - modified = modified - .replace(reBracketProp, "['" + minNames[index] + "']") - .replace(reDotProp, '.' + minNames[index]) - .replace(rePropColon, "$1'" + minNames[index] + "':") - - // correct `value.source` in regexp branch of `_.clone` - if (property == 'source') { - modified = modified.replace("value['" + minNames[index] + "']", "value['source']"); - } + modified = modified + .replace(reBracketProp, "['" + minNames[index] + "']") + .replace(reDotProp, '.' + minNames[index]) + .replace(rePropColon, "$1'" + minNames[index] + "':") + + // correct `value.source` in regexp branch of `_.clone` + if (property == 'source') { + modified = modified.replace("value['" + minNames[index] + "']", "value['source']"); } }); diff --git a/lodash.js b/lodash.js index 6408ae7484..0c598cd208 100644 --- a/lodash.js +++ b/lodash.js @@ -425,9 +425,8 @@ ); /** - * Reusable iterator options shared by - * `countBy`, `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`, - * `map`, `reject`, `some`, and `sortBy`. + * Reusable iterator options shared by `every`, `filter`, + * `find`, `forEach`, `forIn`, `forOwn`, `map`, `reject`, and `some`. */ var baseIteratorOptions = { 'args': 'collection, callback, thisArg', @@ -435,15 +434,6 @@ 'inLoop': 'if (callback(value, index, collection) === false) return result' }; - /** Reusable iterator options for `countBy`, `groupBy`, and `sortBy` */ - var countByIteratorOptions = { - 'init': '{}', - 'top': 'callback = createCallback(callback, thisArg)', - 'inLoop': - 'var prop = callback(value, index, collection);\n' + - '(hasOwnProperty.call(result, prop) ? result[prop]++ : result[prop] = 1)' - }; - /** Reusable iterator options for `every` and `some` */ var everyIteratorOptions = { 'init': 'true', @@ -480,7 +470,7 @@ } }; - /** Reusable iterator options for `invoke`, `map`, `pluck`, and `sortBy` */ + /** Reusable iterator options for `invoke`, `map`, and `pluck` */ var mapIteratorOptions = { 'init': 'collection || []', 'beforeLoop': { @@ -493,22 +483,6 @@ } }; - /** Reusable iterator options for `omit` and `pick` */ - var omitIteratorOptions = { - 'useHas': false, - 'args': 'object, callback, thisArg', - 'init': '{}', - 'top': - 'var isFunc = typeof callback == \'function\';\n' + - 'if (isFunc) callback = createCallback(callback, thisArg);\n' + - 'else var props = concat.apply(ArrayProto, arguments)', - 'inLoop': - 'if (isFunc\n' + - ' ? !callback(value, index, object)\n' + - ' : indexOf(props, index) < 0\n' + - ') result[index] = value' - }; - /*--------------------------------------------------------------------------*/ /** @@ -727,18 +701,15 @@ } // create the function factory var factory = Function( - 'arrayLikeClasses, ArrayProto, bind, compareAscending, concat, createCallback, ' + - 'forIn, hasOwnProperty, indexOf, isArguments, isArray, isFunction, ' + - 'isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' + + 'arrayLikeClasses, bind, createCallback, forIn, hasOwnProperty, isArguments, ' + + 'isFunction, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' + 'slice, stringClass, toString, undefined', - 'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' + - 'return callee' + 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}' ); // return the compiled function return factory( - arrayLikeClasses, ArrayProto, bind, compareAscending, concat, createCallback, - forIn, hasOwnProperty, indexOf, isArguments, isArray, isFunction, - isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, + arrayLikeClasses, bind, createCallback, forIn, hasOwnProperty, isArguments, + isFunction, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, slice, stringClass, toString ); } @@ -1705,37 +1676,48 @@ * _.merge(stooges, ages); * // => [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] */ - var merge = createIterator(extendIteratorOptions, { - 'args': 'object, source, indicator', - 'top': - 'var isArr, args = arguments, argsIndex = 0;\n' + - 'if (indicator == compareAscending) {\n' + - ' var argsLength = 2, stackA = args[3], stackB = args[4]\n' + - '} else {\n' + - ' var argsLength = args.length, stackA = [], stackB = []\n' + - '}\n' + - 'while (++argsIndex < argsLength) {\n' + - ' if (iteratee = args[argsIndex]) {', - 'inLoop': - 'if ((source = value) && ((isArr = isArray(source)) || isPlainObject(source))) {\n' + - ' var found = false, stackLength = stackA.length;\n' + - ' while (stackLength--) {\n' + - ' if (found = stackA[stackLength] == source) break\n' + - ' }\n' + - ' if (found) {\n' + - ' result[index] = stackB[stackLength]\n' + - ' } else {\n' + - ' stackA.push(source);\n' + - ' stackB.push(value = (value = result[index], isArr)\n' + - ' ? (isArray(value) ? value : [])\n' + - ' : (isPlainObject(value) ? value : {})\n' + - ' );\n' + - ' result[index] = callee(value, source, compareAscending, stackA, stackB)\n' + - ' }\n' + - '} else if (source != null) {\n' + - ' result[index] = source\n' + - '}' - }); + function merge(object, source, indicator) { + var args = arguments, + index = 0, + length = 2, + stackA = args[3], + stackB = args[4]; + + if (indicator != compareAscending) { + length = args.length; + stackA = []; + stackB = []; + } + while (++index < length) { + forOwn(args[index], function(source, key) { + var isArr, value; + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + var found = false, + stackLength = stackA.length; + + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + break; + } + } + if (found) { + object[key] = stackB[stackLength]; + } + else { + stackA.push(source); + stackB.push(value = (value = object[key], isArr) + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}) + ); + object[key] = merge(value, source, compareAscending, stackA, stackB); + } + } else if (source != null) { + object[key] = source; + } + }); + } + return object; + } /** * Creates a shallow clone of `object` excluding the specified properties. @@ -1762,7 +1744,25 @@ * }); * // => { 'name': 'moe' } */ - var omit = createIterator(omitIteratorOptions); + function omit(object, callback, thisArg) { + var isFunc = typeof callback == 'function', + result = {}; + + if (isFunc) { + callback = createCallback(callback, thisArg); + } else { + var props = concat.apply(ArrayProto, arguments); + } + forIn(object, function(value, key, object) { + if (isFunc + ? !callback(value, key, object) + : indexOf(props, key) < 0 + ) { + result[key] = value; + } + }); + return result; + } /** * Creates a two dimensional array of the given object's key-value pairs, @@ -1809,22 +1809,29 @@ * }); * // => { 'name': 'moe' } */ - var pick = createIterator(omitIteratorOptions, { - 'top': - 'if (typeof callback != \'function\') {\n' + - ' var index = 0,\n' + - ' props = concat.apply(ArrayProto, arguments),\n' + - ' length = props.length;\n' + - ' while (++index < length) {\n' + - ' var prop = props[index];\n' + - ' if (prop in object) result[prop] = object[prop]\n' + - ' }\n' + - '} else {\n' + - ' callback = createCallback(callback, thisArg)', - 'inLoop': - 'if (callback(value, index, object)) result[index] = value', - 'bottom': '}' - }); + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = 0, + props = concat.apply(ArrayProto, arguments), + length = props.length; + + while (++index < length) { + var prop = props[index]; + if (prop in object) { + result[prop] = object[prop]; + } + } + } else { + callback = createCallback(callback, thisArg); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } /** * Creates an array composed of the own enumerable property values of `object`. @@ -1905,7 +1912,15 @@ * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ - var countBy = createIterator(baseIteratorOptions, countByIteratorOptions); + function countBy(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, key, collection) { + key = callback(value, key, collection); + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + return result; + } /** * Checks if the `callback` returns a truthy value for **all** elements of a @@ -2023,11 +2038,15 @@ * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ - var groupBy = createIterator(baseIteratorOptions, countByIteratorOptions, { - 'inLoop': - 'var prop = callback(value, index, collection);\n' + - '(hasOwnProperty.call(result, prop) ? result[prop] : result[prop] = []).push(value)' - }); + function groupBy(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, key, collection) { + key = callback(value, key, collection); + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + return result; + } /** * Invokes the method named by `methodName` on each element in the `collection`, @@ -2408,28 +2427,25 @@ * _.sortBy(['larry', 'brendan', 'moe'], 'length'); * // => ['moe', 'larry', 'brendan'] */ - var sortBy = createIterator(baseIteratorOptions, countByIteratorOptions, mapIteratorOptions, { - 'inLoop': { - 'array': - 'result[index] = {\n' + - ' criteria: callback(value, index, collection),\n' + - ' index: index,\n' + - ' value: value\n' + - '}', - 'object': - 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '({\n' + - ' criteria: callback(value, index, collection),\n' + - ' index: index,\n' + - ' value: value\n' + - '})' - }, - 'bottom': - 'result.sort(compareAscending);\n' + - 'length = result.length;\n' + - 'while (length--) {\n' + - ' result[length] = result[length].value\n' + - '}' - }); + function sortBy(collection, callback, thisArg) { + var result = []; + callback = createCallback(callback, thisArg); + + forEach(collection, function(value, index, collection) { + result.push({ + 'criteria': callback(value, index, collection), + 'index': index, + 'value': value + }); + }); + + var length = result.length; + result.sort(compareAscending); + while (length--) { + result[length] = result[length].value; + } + return result; + } /** * Converts the `collection`, to an array. From 1e4283aad35e08f0a2cd3dba303100454d7f7c01 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 15:12:21 -0700 Subject: [PATCH 09/79] Remove compiling from `_.functions`, `_.isEmpty`, `_.pairs`, `_.values`, `_.contains`, `_.find`, `_.invoke`, `_.pluck`, `_.reduce`, and `_.where`. Former-commit-id: 207f20330ede82cb58d4f008fe5164771e97a8b0 --- build.js | 78 ++++++++----- build/pre-compile.js | 32 +----- lodash.js | 238 +++++++++++++++++++-------------------- lodash.min.js | 70 ++++++------ lodash.underscore.min.js | 61 +++++----- 5 files changed, 238 insertions(+), 241 deletions(-) diff --git a/build.js b/build.js index 78f6740a14..0d6cb0a92a 100755 --- a/build.js +++ b/build.js @@ -70,8 +70,8 @@ 'clone': ['extend', 'forEach', 'forOwn', 'isArguments', 'isPlainObject'], 'compact': [], 'compose': [], - 'contains': [], - 'countBy': ['forEach', 'identity'], + 'contains': ['some'], + 'countBy': ['forEach'], 'debounce': [], 'defaults': ['isArguments'], 'defer': [], @@ -81,27 +81,27 @@ 'every': ['identity'], 'extend': ['isArguments'], 'filter': ['identity'], - 'find': ['identity'], + 'find': ['some'], 'first': [], 'flatten': ['isArray'], 'forEach': ['identity'], 'forIn': ['identity', 'isArguments'], 'forOwn': ['identity', 'isArguments'], - 'functions': ['isArguments', 'isFunction'], - 'groupBy': ['forEach', 'identity'], + 'functions': ['forIn', 'isFunction'], + 'groupBy': ['forEach'], 'has': [], 'identity': [], 'indexOf': ['sortedIndex'], 'initial': [], 'intersection': ['indexOf'], 'invert': [], - 'invoke': [], + 'invoke': ['forEach'], 'isArguments': [], 'isArray': [], 'isBoolean': [], 'isDate': [], 'isElement': [], - 'isEmpty': ['isArguments', 'isFunction'], + 'isEmpty': ['forOwn', 'isArguments', 'isFunction'], 'isEqual': ['isArguments', 'isFunction'], 'isFinite': [], 'isFunction': [], @@ -125,15 +125,15 @@ 'mixin': ['forEach', 'functions'], 'noConflict': [], 'object': [], - 'omit': ['forIn', 'indexOf', 'isArguments'], + 'omit': ['forIn', 'indexOf'], 'once': [], - 'pairs': [], + 'pairs': ['forOwn'], 'partial': ['isFunction'], 'pick': ['forIn'], - 'pluck': [], + 'pluck': ['forEach'], 'random': [], 'range': [], - 'reduce': ['identity'], + 'reduce': ['forEach'], 'reduceRight': ['forEach', 'keys'], 'reject': ['identity'], 'rest': [], @@ -141,20 +141,20 @@ 'shuffle': ['forEach'], 'size': ['keys'], 'some': ['identity'], - 'sortBy': ['forEach', 'identity'], + 'sortBy': ['forEach'], 'sortedIndex': ['identity'], 'tap': ['mixin'], 'template': ['escape'], 'throttle': [], 'times': [], - 'toArray': ['isFunction', 'values'], + 'toArray': ['values'], 'unescape': [], 'union': ['indexOf'], 'uniq': ['identity', 'indexOf'], 'uniqueId': [], 'value': ['mixin'], - 'values': ['isArguments'], - 'where': ['forIn'], + 'values': ['forOwn'], + 'where': ['forEach', 'forIn'], 'without': ['indexOf'], 'wrap': [], 'zip': ['max', 'pluck'] @@ -676,9 +676,9 @@ return removeVar(source, 'isKeysFast') // remove optimized branch in `iteratorTemplate` .replace(/(?: *\/\/.*\n)* *'( *)<% *if *\(isKeysFast[\s\S]+?'\1<% *} *else *\{ *%>.+\n([\s\S]+?) *'\1<% *} *%>.+/, "'\\n' +\n$2") - // remove `isKeysFast` from `beforeLoop.object` of `mapIteratorOptions` + // remove `isKeysFast` from `beforeLoop.object` of `_.map` .replace(/=\s*'\s*\+\s*\(isKeysFast.+/, "= []'") - // remove `isKeysFast` from `inLoop.object` of `mapIteratorOptions`, `invoke`, `pairs`, `pluck`, and `sortBy` + // remove `isKeysFast` from `inLoop.object` of `_.map` .replace(/'\s*\+\s*\(isKeysFast[^)]+?\)\s*\+\s*'/g, '.push') // remove data object property assignment in `createIterator` .replace(/ *'isKeysFast':.+\n/, ''); @@ -948,6 +948,11 @@ // flag used to specify replacing Lo-Dash's `_.clone` with Underscore's var useUnderscoreClone = isUnderscore; + // flags used to specify exposing Lo-Dash methods in an Underscore build + var exposeForIn = !isUnderscore, + exposeForOwn = !isUnderscore, + exposeIsPlainObject = !isUnderscore; + /*------------------------------------------------------------------------*/ // names of methods to include in the build @@ -972,11 +977,13 @@ (result = getDependencies(optionToMethodsArray(source, value))); }); - // use Lo-Dash's clone if explicitly requested - if (result && result.indexOf('clone') > -1) { - useUnderscoreClone = false; + // include Lo-Dash's methods if explicitly requested + if (result) { + exposeForIn = result.indexOf('forIn') > -1; + exposeForOwn = result.indexOf('forOwn') > -1; + exposeIsPlainObject = result.indexOf('isPlainObject') > -1; + useUnderscoreClone = result.indexOf('clone') < 0; } - // add method names required by Backbone and Underscore builds if (isBackbone && !result) { result = getDependencies(backboneDependencies); @@ -1123,7 +1130,7 @@ ].join('\n')); // replace `arrayLikeClasses` in `_.isEmpty` - source = source.replace(/'if *\(arrayLikeClasses[\s\S]+?' \|\|\\n/, "'if (isArray(value) || className == stringClass ||"); + source = source.replace(/if *\(\(arrayLikeClasses.+?noArgsClass.+/, 'if (isArray(value) || className == stringClass ||'); // replace `arrayLikeClasses` in `_.isEqual` source = source.replace(/(?: *\/\/.*\n)*( +)var isArr *= *arrayLikeClasses[^}]+}/, '$1var isArr = isArray(a);'); @@ -1248,11 +1255,22 @@ }); if (isUnderscore) { - // remove "compiled template cleanup" from `_.template` - source = source.replace(/(?:\s*\/\/.*)*\n *source *=.+?isEvaluating.+?reEmptyStringLeading[\s\S]+?\);/, ''); - source = removeVar(source, 'reEmptyStringLeading'); - source = removeVar(source, 'reEmptyStringMiddle'); - source = removeVar(source, 'reEmptyStringTrailing'); + // remove `_.forIn`, `_.forOwn`, and `_.isPlainObject` assignments + (function() { + var snippet = getMethodAssignments(source), + modified = snippet; + + if (!exposeForIn) { + modified = modified.replace(/(?:\n *\/\/.*\s*)* *lodash\.forIn *= *.+\n/, ''); + } + if (!exposeForOwn) { + modified = modified.replace(/(?:\n *\/\/.*\s*)* *lodash\.forOwn *= *.+\n/, ''); + } + if (!exposeIsPlainObject) { + modified = modified.replace(/(?:\n *\/\/.*\s*)* *lodash\.isPlainObject *= *.+\n/, ''); + } + source = source.replace(snippet, modified); + }()); // replace `isArguments` and its fallback (function() { @@ -1267,6 +1285,12 @@ .replace(/\bnoArgsClass\b/g, '!lodash.isArguments(arguments)'); }); }()); + + // remove "compiled template cleanup" from `_.template` + source = source.replace(/(?:\s*\/\/.*)*\n *source *=.+?isEvaluating.+?reEmptyStringLeading[\s\S]+?\);/, ''); + source = removeVar(source, 'reEmptyStringLeading'); + source = removeVar(source, 'reEmptyStringMiddle'); + source = removeVar(source, 'reEmptyStringTrailing'); } else { source = removeIsArgumentsFallback(source); diff --git a/build/pre-compile.js b/build/pre-compile.js index 3d2afa552c..8fb409c9f2 100644 --- a/build/pre-compile.js +++ b/build/pre-compile.js @@ -21,37 +21,20 @@ 'object', 'ownIndex', 'ownProps', - 'prop', 'propertyIsEnumerable', - 'propIndex', - 'props', 'result', 'skipProto', - 'slice', 'stringClass', 'thisArg', 'toString', - 'undefined', 'value', // lesser used variables - 'args', - 'arrayLikeClasses', 'bind', - 'className', - 'forIn', 'funcs', 'isArguments', - 'isFunc', 'isFunction', - 'methodName', - 'objectClass', - 'objectTypes', - 'pass', - 'properties', - 'property', - 'propsLength', - 'target' + 'objectTypes' ]; /** Used to minify `compileIterator` option properties */ @@ -290,10 +273,10 @@ // remove debug sourceURL use in `_.template` source = source.replace(/(?:\s*\/\/.*\n)* *var sourceURL[^;]+;|\+ *sourceURL/g, ''); - // minify internal properties used by 'compareAscending', `_.merge`, and `_.sortBy` + // minify internal properties used by 'compareAscending' and `_.sortBy` (function() { var properties = ['criteria', 'index', 'value'], - snippets = source.match(/( +)function (?:compareAscending|merge|sortBy)\b[\s\S]+?\n\1}/g); + snippets = source.match(/( +)function (?:compareAscending|sortBy)\b[\s\S]+?\n\1}/g); if (!snippets) { return; @@ -309,13 +292,8 @@ modified = modified .replace(reBracketProp, "['" + minNames[index] + "']") - .replace(reDotProp, '.' + minNames[index]) - .replace(rePropColon, "$1'" + minNames[index] + "':") - - // correct `value.source` in regexp branch of `_.clone` - if (property == 'source') { - modified = modified.replace("value['" + minNames[index] + "']", "value['source']"); - } + .replace(reDotProp, "['" + minNames[index] + "']") + .replace(rePropColon, "$1'" + minNames[index] + "':"); }); // replace with modified snippet diff --git a/lodash.js b/lodash.js index 0c598cd208..ada830bdca 100644 --- a/lodash.js +++ b/lodash.js @@ -425,8 +425,8 @@ ); /** - * Reusable iterator options shared by `every`, `filter`, - * `find`, `forEach`, `forIn`, `forOwn`, `map`, `reject`, and `some`. + * Reusable iterator options shared by `every`, `filter`, forEach`, `forIn`, + * `forOwn`, `map`, `reject`, and `some`. */ var baseIteratorOptions = { 'args': 'collection, callback, thisArg', @@ -452,13 +452,13 @@ 'bottom': ' }\n}' }; - /** Reusable iterator options for `filter`, `reject`, and `where` */ + /** Reusable iterator options for `filter` and `reject` */ var filterIteratorOptions = { 'init': '[]', 'inLoop': 'callback(value, index, collection) && result.push(value)' }; - /** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */ + /** Reusable iterator options for `forEach`, `forIn`, and `forOwn` */ var forEachIteratorOptions = { 'top': 'callback = createCallback(callback, thisArg)' }; @@ -470,19 +470,6 @@ } }; - /** Reusable iterator options for `invoke`, `map`, and `pluck` */ - var mapIteratorOptions = { - 'init': 'collection || []', - 'beforeLoop': { - 'array': 'result = Array(length)', - 'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]') - }, - 'inLoop': { - 'array': 'result[index] = callback(value, index, collection)', - 'object': 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '(callback(value, index, collection))' - } - }; - /*--------------------------------------------------------------------------*/ /** @@ -701,16 +688,14 @@ } // create the function factory var factory = Function( - 'arrayLikeClasses, bind, createCallback, forIn, hasOwnProperty, isArguments, ' + - 'isFunction, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' + - 'slice, stringClass, toString, undefined', + 'bind, createCallback, forIn, hasOwnProperty, isArguments, isFunction, ' + + 'objectTypes, nativeKeys, propertyIsEnumerable, stringClass, toString', 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}' ); // return the compiled function return factory( - arrayLikeClasses, bind, createCallback, forIn, hasOwnProperty, isArguments, - isFunction, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, - slice, stringClass, toString + bind, createCallback, forIn, hasOwnProperty, isArguments, isFunction, + objectTypes, nativeKeys, propertyIsEnumerable, stringClass, toString ); } @@ -1171,13 +1156,15 @@ * _.functions(_); * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] */ - var functions = createIterator({ - 'useHas': false, - 'args': 'object', - 'init': '[]', - 'inLoop': 'isFunction(value) && result.push(index)', - 'bottom': 'result.sort()' - }); + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } /** * Checks if the specified object `property` exists and is a direct property, @@ -1270,21 +1257,23 @@ * _.isEmpty(''); * // => true */ - var isEmpty = createIterator({ - 'args': 'value', - 'init': 'true', - 'top': - 'var className = toString.call(value),\n' + - ' length = value.length;\n' + - 'if (arrayLikeClasses[className]' + - (noArgsClass ? ' || isArguments(value)' : '') + ' ||\n' + - ' (className == objectClass && length === +length &&\n' + - ' isFunction(value.splice))' + - ') return !length', - 'inLoop': { - 'object': 'return false' + function isEmpty(value) { + var result = true; + if (!value) { + return result; } - }); + var className = toString.call(value), + length = value.length; + + if ((arrayLikeClasses[className] || (noArgsClass && isArguments(value))) || + (className == objectClass && length === +length && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } /** * Performs a deep comparison between two values to determine if they are @@ -1778,11 +1767,13 @@ * _.pairs({ 'moe': 30, 'larry': 40, 'curly': 50 }); * // => [['moe', 30], ['larry', 40], ['curly', 50]] (order is not guaranteed) */ - var pairs = createIterator({ - 'args': 'object', - 'init':'[]', - 'inLoop': 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '([index, value])' - }); + function pairs(object) { + var result = []; + forOwn(object, function(value, key) { + result.push([key, value]); + }); + return result; + } /** * Creates a shallow clone of `object` composed of the specified properties. @@ -1846,11 +1837,13 @@ * _.values({ 'one': 1, 'two': 2, 'three': 3 }); * // => [1, 2, 3] */ - var values = createIterator({ - 'args': 'object', - 'init': '[]', - 'inLoop': 'result.push(value)' - }); + function values(object) { + var result = []; + forOwn(object, function(value) { + result.push(value); + }); + return result; + } /*--------------------------------------------------------------------------*/ @@ -1876,15 +1869,11 @@ * _.contains('curly', 'ur'); * // => true */ - var contains = createIterator({ - 'args': 'collection, target', - 'init': 'false', - 'noCharByIndex': false, - 'beforeLoop': { - 'array': 'if (toString.call(collection) == stringClass) return collection.indexOf(target) > -1' - }, - 'inLoop': 'if (value === target) return true' - }); + function contains(collection, target) { + return toString.call(collection) == stringClass + ? collection.indexOf(target) > -1 + : some(collection, function(value) { return value === target; }); + } /** * Creates an object composed of keys returned from running each element of @@ -1983,10 +1972,14 @@ * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); * // => 2 */ - var find = createIterator(baseIteratorOptions, forEachIteratorOptions, { - 'init': 'undefined', - 'inLoop': 'if (callback(value, index, collection)) return value' - }); + function find(collection, callback, thisArg) { + var result; + callback = createCallback(callback, thisArg); + some(collection, function(value, index, collection) { + return callback(value, index, collection) && (result = value, true); + }); + return result; + } /** * Iterates over a `collection`, executing the `callback` for each element in @@ -2070,19 +2063,16 @@ * _.invoke([123, 456], String.prototype.split, ''); * // => [['1', '2', '3'], ['4', '5', '6']] */ - var invoke = createIterator(mapIteratorOptions, { - 'args': 'collection, methodName', - 'top': - 'var args = slice.call(arguments, 2),\n' + - ' isFunc = typeof methodName == \'function\'', - 'inLoop': { - 'array': - 'result[index] = (isFunc ? methodName : value[methodName]).apply(value, args)', - 'object': - 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + - '((isFunc ? methodName : value[methodName]).apply(value, args))' - } - }); + function invoke(collection, methodName) { + var args = slice.call(arguments, 2), + isFunc = typeof methodName == 'function', + result = []; + + forEach(collection, function(value) { + result.push((isFunc ? methodName : value[methodName]).apply(value, args)); + }); + return result; + } /** * Creates an array of values by running each element in the `collection` @@ -2105,7 +2095,17 @@ * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); * // => [3, 6, 9] (order is not guaranteed) */ - var map = createIterator(baseIteratorOptions, mapIteratorOptions); + var map = createIterator(baseIteratorOptions, { + 'init': 'collection || []', + 'beforeLoop': { + 'array': 'result = Array(length)', + 'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]') + }, + 'inLoop': { + 'array': 'result[index] = callback(value, index, collection)', + 'object': 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '(callback(value, index, collection))' + } + }); /** * Retrieves the maximum value of an `array`. If `callback` is passed, @@ -2220,13 +2220,13 @@ * _.pluck(stooges, 'name'); * // => ['moe', 'larry', 'curly'] */ - var pluck = createIterator(mapIteratorOptions, { - 'args': 'collection, property', - 'inLoop': { - 'array': 'result[index] = value[property]', - 'object': 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '(value[property])' - } - }); + function pluck(collection, property) { + var result = []; + forEach(collection, function(value) { + result.push(value[property]); + }); + return result; + } /** * Boils down a `collection` to a single value. The initial state of the @@ -2248,24 +2248,16 @@ * var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; }); * // => 6 */ - var reduce = createIterator({ - 'args': 'collection, callback, accumulator, thisArg', - 'init': 'accumulator', - 'top': - 'var noaccum = arguments.length < 3;\n' + - 'callback = createCallback(callback, thisArg)', - 'beforeLoop': { - 'array': 'if (noaccum) result = iteratee[++index]' - }, - 'inLoop': { - 'array': - 'result = callback(result, value, index, collection)', - 'object': - 'result = noaccum\n' + - ' ? (noaccum = false, value)\n' + - ' : callback(result, value, index, collection)' - } - }); + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + return accumulator; + } /** * The right-associative version of `_.reduce`. @@ -2430,7 +2422,6 @@ function sortBy(collection, callback, thisArg) { var result = []; callback = createCallback(callback, thisArg); - forEach(collection, function(value, index, collection) { result.push({ 'criteria': callback(value, index, collection), @@ -2494,19 +2485,26 @@ * _.where(stooges, { 'age': 40 }); * // => [{ 'name': 'moe', 'age': 40 }] */ - var where = createIterator(filterIteratorOptions, { - 'args': 'collection, properties', - 'top': - 'var props = [];\n' + - 'forIn(properties, function(value, prop) { props.push(prop) });\n' + - 'var propsLength = props.length', - 'inLoop': - 'for (var pass = true, propIndex = 0; propIndex < propsLength; propIndex++) {\n' + - ' var prop = props[propIndex];\n' + - ' if (!(pass = value[prop] === properties[prop])) break\n' + - '}\n' + - 'pass && result.push(value)' - }); + function where(collection, properties) { + var props = []; + forIn(properties, function(value, prop) { props.push(prop); }); + + var propsLength = props.length, + result = []; + + forEach(collection, function(value) { + for (var pass = true, propIndex = 0; propIndex < propsLength; propIndex++) { + var prop = props[propIndex]; + if (!(pass = value[prop] === properties[prop])) { + break; + } + } + if (pass) { + result.push(value); + } + }); + return result; + } /*--------------------------------------------------------------------------*/ diff --git a/lodash.min.js b/lodash.min.js index ad96091e84..0d502f550d 100644 --- a/lodash.min.js +++ b/lodash.min.js @@ -2,38 +2,38 @@ Lo-Dash 0.8.2 lodash.com/license Underscore.js 1.4.2 underscorejs.org/LICENSE */ -;(function(e,t){function s(e){if(e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||H),s=i?{}:e;if(i)for(n=t-1;++nn||e===t)return 1;if(es;s++)i+="i='"+e.o[s]+"';if(","constructor"==e.o[s]&&(i+="!(g&&g.prototype===j)&&"),i+="h.call(j,i)){A=j[i];"+ -e.l.h+"}"}if(e.c||e.m)i+="}"}return i+=e.e+";return t",Function("D,E,F,I,e,f,J,h,M,O,Q,S,T,X,Y,l,q,v,w,y,z","var G=function("+t+"){"+i+"};return G")(Dt,_,L,u,Q,f,en,Z,T,v,$t,m,Jt,mt,Ht,ut,tt,nt,yt,rt)}function c(e){return"\\"+Bt[e]}function h(e){return Qt[e]}function p(){}function d(e){return Gt[e]}function v(e){return rt.call(e)==ct}function m(e){return"function"==typeof e}function g(e){var t=i;if(!e||"object"!=typeof e||v(e))return t;var n=e.constructor;return(!Lt||"function"==typeof e.toString||"string"!=typeof -(e+""))&&(!m(n)||n instanceof n)?xt?(en(e,function(e,n,r){return t=!Z.call(r,n),i}),t===i):(en(e,function(e,n){t=n}),t===i||Z.call(e,t)):t}function y(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=Ht[typeof e]){var u=rt.call(e);if(!Pt[u]||Nt&&v(e))return e;var a=u==ht,n=a||(u==mt?Jt(e):n)}if(!n||!t)return n?a?nt.call(e):Zt({},e):e;n=e.constructor;switch(u){case pt:case dt:return new n(+e);case vt:case yt:return new n(e);case gt:return n(e.source,U.exec(e))}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[ -u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?mn:tn)(e,function(e,n){f[n]=y(e,t,r,s,o)}),f}function b(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Ht[typeof e]||Ht[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=rt.call(e);if(u!=rt.call(t))return i;switch(u){case pt:case dt:return+e==+t;case vt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case gt:case yt:return e==t+""}var a=Dt[u];if(Nt&&!a&&(a=v(e))&&!v(t)||!a&&(u!=mt||Lt&&("function"!=typeof e. -toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=b(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!m(a)||!(a instanceof a&&m(f)&&f instanceof f)))return i;for(var c in e)if(Z.call(e,c)&&(l++,!Z.call(t,c)||!b(e[c],t[c],s,o)))return i;for(c in t)if(Z.call(t,c)&&!(l--))return i;if( -Et)for(;7>++u;)if(c=J[u],Z.call(e,c)&&(!Z.call(t,c)||!b(e[c],t[c],s,o)))return i;return n}function w(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),mn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++io&&(o=e[i]);return o}function E(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if(o!==+o)var a=sn(e),o=a.length;else kt&&rt.call(e)==yt&&(s=e.split(""));return mn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function S(e,t,n){ -if(e)return t==r||n?e[0]:nt.call(e,0,t)}function x(e,t){for(var n=-1,r=e?e.length:0,i=[];++nn?at(0,i+n):n||0)-1;else if(n)return r=C(e,t),e[r]===t?r:-1;for(;++r>>1,n(e[r])>>1,e[r]T(a,r))a.push(r),u.push(e[s]);return u}function L(e,t){return Ot||it&&2|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,F=/&(?:amp|lt|gt|quot|#x27);/g,I=/\b__p\+='';/g,q=/\b(__p\+=)''\+/g,R=/(__e\(.*?\)|\b__t\))\+'';/g,U=/\w*$/,z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,W=RegExp("^"+(D.valueOf+"" -).replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),X=/($^)/,V=/[&<>"']/g,$=/['\n\r\t\u2028\u2029\\]/g,J="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),K=Math.ceil,Q=_.concat,G=Math.floor,Y=W.test(Y=Object.getPrototypeOf)&&Y,Z=D.hasOwnProperty,et=_.push,tt=D.propertyIsEnumerable,nt=_.slice,rt=D.toString,it=W.test(it=nt.bind)&&it,st=W.test(st=Array.isArray)&&st,ot=e.isFinite,ut=W.test(ut=Object.keys)&&ut -,at=Math.max,ft=Math.min,lt=Math.random,ct="[object Arguments]",ht="[object Array]",pt="[object Boolean]",dt="[object Date]",vt="[object Number]",mt="[object Object]",gt="[object RegExp]",yt="[object String]",bt=e.clearTimeout,wt=e.setTimeout,Et,St,xt,Tt=n;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);for(r in arguments)Tt=!r;Et=4>(n+"").length,xt="x"!=n[0],St=(n.splice.call(t,0,1),t[0])})(1);var Nt=!v(arguments),Ct="x"!=nt.call("x" -)[0],kt="xx"!="x"[0]+Object("x")[0];try{var Lt=("[object Object]",rt.call(e.document||0)==mt)}catch(At){}var Ot=it&&/\n|Opera/.test(it+rt.call(e.opera)),Mt=ut&&/^.+$|true/.test(ut+!!e.attachEvent),_t=!Ot,Dt={};Dt[pt]=Dt[dt]=Dt["[object Function]"]=Dt[vt]=Dt[mt]=Dt[gt]=i,Dt[ct]=Dt[ht]=Dt[yt]=n;var Pt={};Pt[ct]=Pt["[object Function]"]=i,Pt[ht]=Pt[pt]=Pt[dt]=Pt[vt]=Pt[mt]=Pt[gt]=Pt[yt]=n;var Ht={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Bt={"\\":"\\","'":"'","\n":"n" -,"\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var jt={a:"d,c,x",p:"c=f(c,x)",h:"if(c(A,i,d)===false)return t"},Ft={i:"{}",p:"c=f(c,x)",h:"var p=c(A,i,d);(h.call(t,p)?t[p]++:t[p]=1)"},It={i:"true",h:"if(!c(A,i,d))return!t"},qt={q:i,r:i,a:"m",p:"for(var a=1,b=arguments.length;a":">",'"':""","'":"'"},Gt=Vt(Qt),Yt=l(qt,{h:"if(t[i]==null)"+qt.h}),Zt=l(qt),en=l(jt,Ut,zt,{q:i}),tn=l(jt,Ut,zt),nn=l({q:i,a:"m",i:"[]",h:"S(A)&&t.push(i)",e:"t.sort()"}),rn=l({a:"A",i:"true",p:"var H=y.call(A),k=A.length;if(D[H]"+(Nt?"||O(A)":"")+"||(H==X&&k===+k&&S(A.splice)))return!k",h:{k:"return false"}}),sn=ut?function( -e){var t=typeof e;return"function"==t&&tt.call(e,"prototype")?Kt(e):e&&Ht[t]?ut(e):[]}:Kt,on=l(qt,{a:"m,dd,N",p:"var P,C=arguments,a=0;if(N==I){var b=2,ee=C[3],ff=C[4]}else var b=C.length,ee=[],ff=[];while(++a-1"},h:"if(A===hh)return true"}),hn=l(jt,Ft),pn=l(jt,It),dn=l(jt,Rt),vn=l(jt,Ut,{i:"z",h:"if(c(A,i,d))return A"}),mn=l(jt,Ut),gn=l(jt,Ft,{h:"var p=c(A,i,d);(h.call(t,p)?t[p]:t[p]=[]).push(A)"}),yn=l(Wt,{a:"d,U" -,p:"var C=v.call(arguments,2),R=typeof U=='function'",h:{b:"t[i]=(R?U:A[U]).apply(A,C)",k:"t"+(Mt?"[n]=":".push")+"((R?U:A[U]).apply(A,C))"}}),bn=l(jt,Wt),wn=l(Wt,{a:"d,bb",h:{b:"t[i]=A[bb]",k:"t"+(Mt?"[n]=":".push")+"(A[bb])"}}),En=l({a:"d,c,B,x",i:"B",p:"var V=arguments.length<3;c=f(c,x)",d:{b:"if(V)t=j[++i]"},h:{b:"t=c(t,A,i,d)",k:"t=V?(V=false,A):c(t,A,i,d)"}}),Sn=l(jt,Rt,{h:"!"+Rt.h}),xn=l(jt,It,{i:"false",h:It.h.replace("!","")}),Tn=l(jt,Ft,Wt,{h:{b:"t[i]={a:c(A,i,d),b:i,c:A}",k:"t"+(Mt?"[n]=" -:".push")+"({a:c(A,i,d),b:i,c:A})"},e:"t.sort(I);k=t.length;while(k--)t[k]=t[k].c"}),Nn=l(Rt,{a:"d,aa",p:"var s=[];J(aa,function(A,p){s.push(p)});var cc=s.length",h:"for(var Z=true,r=0;r1){while(++ie?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=L,s.bindAll= -Cn,s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=y,s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++tT(s,u)){for(var a=1;an?at(0,r+n):ft(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.lateBind=function(e,t){return a(t,e,nt.call(arguments,2))},s.map=bn,s.max=w,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Z.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=on,s.min=function(e,t,n){var r= -Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),mn(e,function(e,n,i){n=t(e,n,i),n=f?(bt(u),a=r,s=e.apply(o,i)):u||(u=wt(n,f)),s}},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++rT(r,i)&&r.push(i)}return r},s.uniq=k,s.uniqueId=function(e){var t=P++;return e?e+t:t},s.values=ln,s.where=Nn,s.without=function(e){for(var t=-1,n=e?e.length:0,r=o(arguments,1,20),i=[];++t=(n||U),s=i?{}:e;if(i)for(n=t-1;++nn||e===t)return 1;if(es;s++)i+="h='"+e.o[s]+"';if(","constructor"==e.o[s]&&(i+="!(f&&f.prototype===i)&&"),i+="g.call(i,h)){u=i[h];"+ +e.l.h+"}"}if(e.c||e.m)i+="}"}return i+=e.e+";return p",Function("v,e,forIn,g,x,y,z,k,o,r,t","return function("+t+"){"+i+"}")(H,f,sn,ot,v,m,Ut,dt,at,Nt,lt)}function c(e){return"\\"+zt[e]}function h(e){return en[e]}function p(){}function d(e){return tn[e]}function v(e){return lt.call(e)==yt}function m(e){return"function"==typeof e}function g(e){var t=i;if(!e||"object"!=typeof e||v(e))return t;var n=e.constructor;return(!Ht||"function"==typeof e.toString||"string"!=typeof (e+""))&&(!m(n)||n instanceof +n)?Ot?(sn(e,function(e,n,r){return t=!ot.call(r,n),i}),t===i):(sn(e,function(e,n){t=n}),t===i||ot.call(e,t)):t}function y(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=Ut[typeof e]){var u=lt.call(e);if(!Rt[u]||_t&&v(e))return e;var a=u==bt,n=a||(u==xt?Yt(e):n)}if(!n||!t)return n?a?ft.call(e):rn({},e):e;n=e.constructor;switch(u){case wt:case Et:return new n(+e);case St:case Nt:return new n(e);case Tt:return n(e.source,K.exec(e))}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u];var f=a?n( +e.length):{};return s.push(e),o.push(f),(a?ln:on)(e,function(e,n){f[n]=y(e,t,r,s,o)}),f}function b(e){var t=[];return sn(e,function(e,n){m(e)&&t.push(n)}),t.sort()}function w(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Ut[typeof e]||Ut[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=lt.call(e);if(u!=lt.call(t))return i;switch(u){case wt:case Et:return+e==+t;case St:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Tt:case Nt:return e==t+""}var a=qt[u];if(_t&&!a&&(a=v(e) +)&&!v(t)||!a&&(u!=xt||Ht&&("function"!=typeof e.toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=w(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!m(a)||!(a instanceof a&&m(f)&&f instanceof f)))return i;for(var c in e)if(ot.call(e,c)&&(l++,!ot.call(t,c)||!w(e[c],t[c],s,o)))return i +;for(c in t)if(ot.call(t,c)&&!(l--))return i;if(Lt)for(;7>++u;)if(c=tt[u],ot.call(e,c)&&(!ot.call(t,c)||!w(e[c],t[c],s,o)))return i;return n}function E(e,t,n){var s=arguments,o=0,a=2,f=s[3],l=s[4];n!=u&&(a=s.length,f=[],l=[]);for(;++or&&(r=n,o=e)});else for(;++io&&(o=e[i]);return o}function C(e,t){var n=[];return ln(e,function(e){n.push(e[t])}),n}function k(e,t,n,r){var s=3>arguments.length,t=f(t,r);return ln(e,function( +e,r,o){n=s?(s=i,e):t(n,e,r,o)}),n}function L(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if(o!==+o)var a=un(e),o=a.length;else Pt&<.call(e)==Nt&&(s=e.split(""));return ln(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function A(e,t,n){if(e)return t==r||n?e[0]:ft.call(e,0,t)}function O(e,t){for(var n=-1,r=e?e.length:0,i=[];++nn?vt(0 +,i+n):n||0)-1;else if(n)return r=D(e,t),e[r]===t?r:-1;for(;++r>>1,n(e[r])>>1,e[r]M(a,r))a.push(r),u.push(e[s]);return u}function H +(e,t){return jt||ct&&2|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,X=/&(?:amp|lt|gt|quot|#x27);/g,V=/\b__p\+='';/g,$=/\b(__p\+=)''\+/g,J=/(__e\(.*?\)|\b__t\))\+'';/g,K=/\w*$/,Q=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,G=RegExp("^"+(q.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Y=/($^)/,Z=/[&<>"']/g,et=/['\n\r\t\u2028\u2029\\]/g,tt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf" +.split(" "),nt=Math.ceil,rt=I.concat,it=Math.floor,st=G.test(st=Object.getPrototypeOf)&&st,ot=q.hasOwnProperty,ut=I.push,at=q.propertyIsEnumerable,ft=I.slice,lt=q.toString,ct=G.test(ct=ft.bind)&&ct,ht=G.test(ht=Array.isArray)&&ht,pt=e.isFinite,dt=G.test(dt=Object.keys)&&dt,vt=Math.max,mt=Math.min,gt=Math.random,yt="[object Arguments]",bt="[object Array]",wt="[object Boolean]",Et="[object Date]",St="[object Number]",xt="[object Object]",Tt="[object RegExp]",Nt="[object String]",Ct=e.clearTimeout,kt= +e.setTimeout,Lt,At,Ot,Mt=n;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);for(r in arguments)Mt=!r;Lt=4>(n+"").length,Ot="x"!=n[0],At=(n.splice.call(t,0,1),t[0])})(1);var _t=!v(arguments),Dt="x"!=ft.call("x")[0],Pt="xx"!="x"[0]+Object("x")[0];try{var Ht=("[object Object]",lt.call(e.document||0)==xt)}catch(Bt){}var jt=ct&&/\n|Opera/.test(ct+lt.call(e.opera)),Ft=dt&&/^.+$|true/.test(dt+!!e.attachEvent),It=!jt,qt={};qt[wt]=qt[Et]=qt["[object Function]" +]=qt[St]=qt[xt]=qt[Tt]=i,qt[yt]=qt[bt]=qt[Nt]=n;var Rt={};Rt[yt]=Rt["[object Function]"]=i,Rt[bt]=Rt[wt]=Rt[Et]=Rt[St]=Rt[xt]=Rt[Tt]=Rt[Nt]=n;var Ut={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},zt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var Wt={a:"d,c,s",p:"c=e(c,s)",h:"if(c(u,h,d)===false)return p"},Xt={i:"true" +,h:"if(!c(u,h,d))return!p"},Vt={q:i,r:i,a:"l",p:"for(var a=1,b=arguments.length;a":">",'"':""","'":"'"},tn=Qt(en),nn=l(Vt,{h:"if(p[h]==null)"+Vt.h}),rn=l(Vt),sn=l(Wt,Jt,Kt,{q:i}),on=l(Wt,Jt,Kt),un=dt?function(e){var t=typeof e;return"function"==t&&at.call(e,"prototype")?Zt(e):e&&Ut[t]?dt(e):[]}:Zt,an=l(Wt,Xt),fn=l(Wt,$t),ln=l(Wt,Jt),cn=l(Wt,{i:"d||[]",d:{b:"p=Array(j)",k:"p="+(Ft?"Array(j)":"[]")},h:{b:"p[h]=c(u,h,d)",k:"p"+(Ft?"[m]=":".push")+"(c(u,h,d))"}} +),hn=l(Wt,$t,{h:"!"+$t.h}),pn=l(Wt,Xt,{i:"false",h:Xt.h.replace("!","")}),dn=l({q:i,r:i,a:"l",p:"var w=arguments,h=0,j=w.length;if(j>1){while(++he?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=H,s.bindAll=dn,s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=y,s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++tM(s,u)){for(var a=1;an?vt(0,r+n):mt(n,r-1))+1); +r--;)if(e[r]===t)return r;return-1},s.lateBind=function(e,t){return a(t,e,ft.call(arguments,2))},s.map=cn,s.max=N,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return ot.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=E,s.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),ln(e,function(e,n,i){n=t(e,n,i),nM(s,n))i[n]=e}),i},s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=function(e){var t=[];return on(e,function(e,n){t.push([n,e])}),t},s.partial=function(e){return a(e,ft.call(arguments,1 +))},s.pick=function(e,t,n){var r={};if("function"!=typeof t)for(var i=0,s=rt.apply(I,arguments),o=s.length;++i=f?(Ct(u),a=r,s=e.apply(o,i)):u||(u=kt(n,f)),s}},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++rM(r,i)&&r.push(i)}return r},s.uniq=P,s.uniqueId=function( +e){var t=R++;return e?e+t:t},s.values=S,s.where=function(e,t){var r=[];sn(t,function(e,t){r.push(t)});var i=r.length,s=[];return ln(e,function(e){for(var o=n,u=0;uarguments.length,t=x(t,r),f=e.length;s=-1;if(f===+f)for(a&&(u=e[++s]);++sn||e===t)return 1 -;if(er&&(r=n,o=e)});else for(;++io&&(o=e[i]);return o}function _(e,t,n,r){var s=e?e.length:0,o=3>arguments.length;if(s!==+s)var u=At(e),s=u.length;return f(e,function(a,f,l){f=u?u[--s]:--s,n=o?(o=i,e[f]):t.call(r,n,e[f],f,l)}),n}function D(e,t,n){if(e)return t==r||n?e[0]:ot.call(e,0,t)}function P(e,t){for(var n=-1,r=e?e.length:0,i=[];++nn?ht(0, -i+n):n||0)-1;else if(n)return r=j(e,t),e[r]===t?r:-1;for(;++r>>1,n(e[r])>>1,e[r]H(a,r))a.push(r),u.push(e[s]);return u}function I -(e,t){return xt||at&&2|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,J=/&(?:amp|lt|gt|quot|#x27);/g,K=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,Q=RegExp("^"+(W.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),G=/($^)/,Y=/[&<>"']/g,Z=/['\n\r\t\u2028\u2029\\]/g,et=Math.ceil,tt=z.concat,nt=Math.floor,rt=Q.test(rt=Object.getPrototypeOf)&&rt,it=W.hasOwnProperty,st=z.push,ot=z.slice,ut=W.toString,at=Q.test(at=ot.bind)&&at,ft=Q.test(ft=Array.isArray -)&&ft,lt=e.isFinite,ct=Q.test(ct=Object.keys)&&ct,ht=Math.max,pt=Math.min,dt=Math.random,vt="[object Boolean]",mt="[object Date]",gt="[object Number]",yt="[object Object]",bt="[object RegExp]",wt="[object String]",Et=e.clearTimeout,St=e.setTimeout,xt=at&&/\n|Opera/.test(at+ut.call(e.opera)),Tt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Nt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};w.templateSettings={escape:/<%-([\s\S]+?)%>/g -,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},w.isArguments=function(e){return"[object Arguments]"==ut.call(e)},w.isArguments(arguments)||(w.isArguments=function(e){return e?it.call(e,"callee"):i});var Ct=ft||function(e){return"[object Array]"==ut.call(e)};L(/x/)&&(L=function(e){return"[object Function]"==ut.call(e)});var W=rt?function(e){if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=rt(t))&&rt(n);return n?e==n||rt(e)==n&&!isArguments(e):A -(e)}:A,kt={"&":"&","<":"<",">":">",'"':""","'":"'"},Lt=b(kt),At=ct?function(e){return e&&Tt[typeof e]?ct(e):[]}:y;w.VERSION="0.8.2",w.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},w.bind=I,w.bindAll=function(e){var t,n,r=e,i=e;if(!e)return i;n=arguments,t=0;var s=n.length;if(1H(r,s,n)&&i.push(s)}return i},w.escape=function(e){return e==r?"":(e+"").replace(Y,N)},w.every=h,w.extend=g,w.filter=c,w.find=l,w.first=D,w.flatten=P,w.forEach=f,w.forIn=m,w.forOwn=function(e,t,n){var r;if(!e)return e;t=x(t,n);for(r in e)it.call(e,r)&&(n=e[r],t(n,r,e));return e},w.functions=v,w.groupBy=function(e,t,n){var r,i={};if(!e)return i;var t=x(t,n),s=e.length -,n=-1;if(s===+s)for(;++nH(i,s)){for(var o=1;oH(arguments[o],s))continue e;i.push(s)}}return i -},w.invert=b,w.invoke=function(e,t){var n,r,i=e,s=e||[];if(!e)return s;var o=ot.call(arguments,2),u="function"==typeof t,a=i.length;n=-1;if(a===+a)for(s=Array(a);++nn?ht(0,r+n):pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},w.map=a,w.max=M,w.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return it.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},w.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+ -s)t=x(t,n),f(e,function(e,n,i){n=t(e,n,i),nH(a,r))o[r]=i;return o},w.once=function(e){var t,s=i;return function(){ -return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},w.pairs=function(e){var t,n,r=[];if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r.push([t,n]));return r},w.pick=function(e,t,n){var r,i,s=e,o={};if(!e)return o;if("function"!=typeof t){r=0,i=tt.apply(z,arguments);for(s=i.length;++r=f?(Et(u),a=r,s=e.apply(o,i)):u||(u=St(n,f)),s}},w.times=function( -e,t,n){for(var e=+e||0,r=-1,i=Array(e);++rH(r,i)&&r.push(i)}return r},w.uniq=F,w.uniqueId=function(e){var t=X++;return e?e+t:t},w.values=d,w.where=function(e,t){var r,i,s=[];if(!e)return s;var o=[];m(t,function( -e,t){o.push(t)});var u=o.length,a=e.length;r=-1;if(a===+a)for(;++rH(arguments,i,1)&&r.push(i)}return r},w.wrap=function(e,t){return function(){var n=[e];return arguments.length&&st.apply(n,arguments),t.apply(this,n)}},w.zip=function(e){for(var t=-1 -,n=e?M(u(arguments,"length")):0,r=Array(n);++tn||e===t)return 1;if(er&&(r=n,o=e)});else for(;++io&&(o=e[i]);return o}function O(e,t){var n=[];return u(e,function(e){n.push(e[t])}),n}function M(e,t,n,r){var s=3>arguments.length,t=y(t,r);return u(e,function(e,r,o){n=s?(s=i,e):t(n,e,r,o)}),n}function _(e,t,n,r +){var s=e?e.length:0,o=3>arguments.length;if(s!==+s)var a=Ot(e),s=a.length;return u(e,function(u,f,l){f=a?a[--s]:--s,n=o?(o=i,e[f]):t.call(r,n,e[f],f,l)}),n}function D(e,t,n){if(e)return t==r||n?e[0]:ot.call(e,0,t)}function P(e,t){for(var n=-1,r=e?e.length:0,i=[];++nn?ht(0,i+n):n||0)-1;else if(n)return r=j(e,t),e[r]===t?r:-1;for(;++r>>1,n(e[r])>>1,e[r]H(a,r))a.push(r),u.push(e[s]);return u}function I(e,t){return Tt||at&&2|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,J=/&(?:amp|lt|gt|quot|#x27);/g +,K=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,Q=RegExp("^"+(W.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),G=/($^)/,Y=/[&<>"']/g,Z=/['\n\r\t\u2028\u2029\\]/g,et=Math.ceil,tt=z.concat,nt=Math.floor,rt=Q.test(rt=Object.getPrototypeOf)&&rt,it=W.hasOwnProperty,st=z.push,ot=z.slice,ut=W.toString,at=Q.test(at=ot.bind)&&at,ft=Q.test(ft=Array.isArray)&&ft,lt=e.isFinite,ct=Q.test(ct=Object.keys)&&ct,ht=Math.max,pt=Math.min,dt=Math.random,vt="[object Boolean]" +,mt="[object Date]",gt="[object Number]",yt="[object Object]",bt="[object RegExp]",wt="[object String]",Et=e.clearTimeout,St=e.setTimeout,xt;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);xt=(n.splice.call(t,0,1),t[0])})(1);var Tt=at&&/\n|Opera/.test(at+ut.call(e.opera)),Nt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Ct={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"} +;v.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},v.isArguments=function(e){return"[object Arguments]"==ut.call(e)},v.isArguments(arguments)||(v.isArguments=function(e){return e?it.call(e,"callee"):i});var kt=ft||function(e){return"[object Array]"==ut.call(e)};x(/x/)&&(x=function(e){return"[object Function]"==ut.call(e)});var Lt={"&":"&","<":"<",">":">",'"':""","'":"'"},At=d(Lt),Ot=ct?function(e){return e&&Nt[typeof +e]?ct(e):[]}:p;v.VERSION="0.8.2",v.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},v.bind=I,v.bindAll=function(e){var t,n,r=e,i=e;if(!e)return i;n=arguments,t=0;var s=n.length;if(1H(r,s,n)&&i.push(s)}return i},v.escape=function(e){return e==r?"":(e+"").replace(Y,w)},v.every=f,v.extend= +h,v.filter=a,v.find=L,v.first=D,v.flatten=P,v.forEach=u,v.functions=T,v.groupBy=function(e,t,n){var r={},t=y(t,n);return u(e,function(e,n,i){n=t(e,n,i),(it.call(r,n)?r[n]:r[n]=[]).push(e)}),r},v.has=function(e,t){return e?it.call(e,t):i},v.identity=q,v.indexOf=H,v.initial=function(e,t,n){return e?ot.call(e,0,-(t==r||n?1:t)):[]},v.intersection=function(e){var t=arguments.length,n=-1,r=e.length,i=[];e:for(;++nH(i,s)){for(var o=1;oH(arguments[o],s))continue e;i.push( +s)}}return i},v.invert=d,v.invoke=function(e,t){var n=ot.call(arguments,2),r="function"==typeof t,i=[];return u(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},v.isArray=kt,v.isBoolean=function(e){return e===n||e===i||ut.call(e)==vt},v.isDate=function(e){return ut.call(e)==mt},v.isElement=function(e){return e?1===e.nodeType:i},v.isEmpty=function(e){var t=n;if(!e)return t;var r=ut.call(e),s=e.length;return kt(e)||r==wt||r==yt&&s===+s&&x(e.splice)?!s:(l(e,function(){return t=i}),t)},v.isEqual=N,v. +isFinite=function(e){return lt(e)&&ut.call(e)==gt},v.isFunction=x,v.isNaN=function(e){return ut.call(e)==gt&&e!=+e},v.isNull=function(e){return e===r},v.isNumber=function(e){return ut.call(e)==gt},v.isObject=function(e){return e?Nt[typeof e]:i},v.isRegExp=function(e){return ut.call(e)==bt},v.isString=function(e){return ut.call(e)==wt},v.isUndefined=function(e){return e===t},v.keys=Ot,v.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:ot.call(e,-t||i)}},v.lastIndexOf=function(e,t,n) +{var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?ht(0,r+n):pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},v.map=o,v.max=A,v.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return it.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},v.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=y(t,n),u(e,function(e,n,i){n=t(e,n,i),nH(s,n))i[n]=e}),i},v.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},v.pairs=function(e){var t=[];return l(e,function(e,n){t.push([n,e])}),t},v.pick=function(e,t,n){var r={};if("function"!=typeof +t)for(var i=0,s=tt.apply(z,arguments),o=s.length;++i=f?(Et(u),a=r,s=e.apply(o,i)):u||(u=St(n,f)),s}},v.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++rH(r,i)&& +r.push(i)}return r},v.uniq=F,v.uniqueId=function(e){var t=X++;return e?e+t:t},v.values=C,v.where=function(e,t){var r=[];c(t,function(e,t){r.push(t)});var i=r.length,s=[];return u(e,function(e){for(var o=n,u=0;uH(arguments,i,1)&&r.push(i)}return r},v.wrap=function(e,t){return function(){var n=[e];return arguments.length&&st.apply(n,arguments),t.apply(this,n)}},v.zip=function(e) +{for(var t=-1,n=e?A(O(arguments,"length")):0,r=Array(n);++t Date: Sat, 13 Oct 2012 20:58:08 -0700 Subject: [PATCH 10/79] Reduce `_.isEmpty` and ensure dependencies are modified correctly for the `lodash underscore` build. Former-commit-id: 23ff37da17578dfeafbabee4bcae100f4df68ed6 --- build.js | 37 +++++++++++++++++++++++++++---------- test/test-build.js | 31 +++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/build.js b/build.js index 0d6cb0a92a..4bb8eeac98 100755 --- a/build.js +++ b/build.js @@ -971,6 +971,15 @@ : accumulator; }, []); + // update dependencies + if (isUnderscore) { + dependencyMap.isEqual = ['isArray', 'isFunction']; + dependencyMap.isEmpty = ['isArray', 'isString']; + + if (useUnderscoreClone) { + dependencyMap.clone = ['extend', 'isArray']; + } + } // add method names explicitly options.some(function(value) { return /include/.test(value) && @@ -1006,11 +1015,9 @@ return (result = _.union(result || [], getDependencies(methodNames))); }); - // init `result` if it hasn't been inited if (!result) { result = allMethods.slice(); } - if (plusMethods.length) { result = _.union(result, getDependencies(plusMethods)); } @@ -1047,10 +1054,6 @@ source = removeKeysOptimization(source); } else if (isUnderscore) { - // update dependencies - dependencyMap.isEqual = ['isArray', 'isFunction']; - dependencyMap.isEmpty = ['isArray']; - // remove unneeded variables source = removeVar(source, 'arrayLikeClasses'); source = removeVar(source, 'cloneableClasses'); @@ -1061,7 +1064,6 @@ // replace `_.clone` if (useUnderscoreClone) { - dependencyMap.clone = ['extend', 'isArray']; source = source.replace(/^( +)function clone[\s\S]+?\n\1}/m, [ ' function clone(value) {', ' return value && objectTypes[typeof value]', @@ -1112,6 +1114,24 @@ ' }' ].join('\n')); + // replace `_.isEmpty` + source = source.replace(/^( +)function isEmpty[\s\S]+?\n\1}/m, [ + ' function isEmpty(value) {', + ' if (!value) {', + ' return true;', + ' }', + ' if (isArray(value) || isString(value)) {', + ' return !value.length;', + ' }', + ' for (var key in value) {', + ' if (hasOwnProperty.call(value, key)) {', + ' return false;', + ' }', + ' }', + ' return true;', + ' }' + ].join('\n')); + // replace `_.without` source = source.replace(/^( +)function without[\s\S]+?\n\1}/m, [ ' function without(array) {', @@ -1129,9 +1149,6 @@ ' }' ].join('\n')); - // replace `arrayLikeClasses` in `_.isEmpty` - source = source.replace(/if *\(\(arrayLikeClasses.+?noArgsClass.+/, 'if (isArray(value) || className == stringClass ||'); - // replace `arrayLikeClasses` in `_.isEqual` source = source.replace(/(?: *\/\/.*\n)*( +)var isArr *= *arrayLikeClasses[^}]+}/, '$1var isArr = isArray(a);'); diff --git a/test/test-build.js b/test/test-build.js index bd704449cc..5a649c25e5 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -632,9 +632,11 @@ }); equal(last.value, 2, '_.each: ' + basename); - equal(lodash.isEmpty('moe'), false, '_.isEmpty: ' + basename); - var object = { 'fn': lodash.bind(function(x) { return this.x + x; }, { 'x': 1 }, 1) }; + var object = { 'length': 0, 'splice': Array.prototype.splice }; + equal(lodash.isEmpty(object), false, '_.isEmpty: ' + basename); + + object = { 'fn': lodash.bind(function(x) { return this.x + x; }, { 'x': 1 }, 1) }; equal(object.fn(), 2, '_.bind: ' + basename); ok(lodash.clone(array, true)[0] === array[0], '_.clone: ' + basename); @@ -642,6 +644,31 @@ }); }); + asyncTest('should not have any Lo-Dash-only methods', function() { + var start = _.after(2, _.once(QUnit.start)); + + build(['-s', 'underscore'], function(source, filePath) { + var basename = path.basename(filePath, '.js'), + context = createContext(); + + vm.runInContext(source, context); + var lodash = context._; + + _.each([ + 'forIn', + 'forOwn', + 'isPlainObject', + 'lateBind', + 'merge', + 'partial' + ], function(methodName) { + equal(lodash[methodName], undefined, '_.' + methodName + ' exists: ' + basename); + }); + + start(); + }); + }); + asyncTest('`lodash underscore include=partial`', function() { var start = _.after(2, _.once(QUnit.start)); From 96553b217c10a3147614e9f156d169edc1bb6dd1 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 20:58:39 -0700 Subject: [PATCH 11/79] Reduce `_.merge`. Former-commit-id: 5797e14e589d39e553d7af109d282109e633cd80 --- lodash.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lodash.js b/lodash.js index ada830bdca..5599583d55 100644 --- a/lodash.js +++ b/lodash.js @@ -1665,17 +1665,15 @@ * _.merge(stooges, ages); * // => [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] */ - function merge(object, source, indicator) { + function merge(object, source, indicator, stackA, stackB) { var args = arguments, index = 0, - length = 2, - stackA = args[3], - stackB = args[4]; + length = 2; if (indicator != compareAscending) { - length = args.length; stackA = []; stackB = []; + length = args.length; } while (++index < length) { forOwn(args[index], function(source, key) { @@ -3476,18 +3474,18 @@ return function() { var now = new Date, - remain = wait - (now - lastCalled); + remaining = wait - (now - lastCalled); args = arguments; thisArg = this; - if (remain <= 0) { + if (remaining <= 0) { clearTimeout(timeoutId); lastCalled = now; result = func.apply(thisArg, args); } else if (!timeoutId) { - timeoutId = setTimeout(trailingCall, remain); + timeoutId = setTimeout(trailingCall, remaining); } return result; }; From dea8ad4c49ce2de928b7c38e8c01b6a4001be095 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 23:29:51 -0700 Subject: [PATCH 12/79] Optimize `_.contains` and `_.omit`. Former-commit-id: f1d7b5699bae6de90d880fe593531f7d3772924e --- lodash.js | 15 +++++++++++---- perf/perf.js | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lodash.js b/lodash.js index 5599583d55..383600f813 100644 --- a/lodash.js +++ b/lodash.js @@ -1743,7 +1743,7 @@ forIn(object, function(value, key, object) { if (isFunc ? !callback(value, key, object) - : indexOf(props, key) < 0 + : indexOf(props, key, 1) < 0 ) { result[key] = value; } @@ -1868,9 +1868,16 @@ * // => true */ function contains(collection, target) { - return toString.call(collection) == stringClass - ? collection.indexOf(target) > -1 - : some(collection, function(value) { return value === target; }); + var length = collection ? collection.length : 0; + if (length === +length) { + return (toString.call(collection) == stringClass + ? collection.indexOf(target) + : indexOf(collection, target) + ) > -1; + } + return some(collection, function(value) { + return value === target; + }); } /** diff --git a/perf/perf.js b/perf/perf.js index bf8212b7ad..ae3ff2c415 100644 --- a/perf/perf.js +++ b/perf/perf.js @@ -512,6 +512,28 @@ /*--------------------------------------------------------------------------*/ + suites.push( + Benchmark.Suite('`_.contains` iterating an array') + .add('Lo-Dash', '\ + lodash.contains(numbers, 19)' + ) + .add('Underscore', '\ + _.contains(numbers, 19)' + ) + ); + + suites.push( + Benchmark.Suite('`_.contains` iterating an object') + .add('Lo-Dash', '\ + lodash.contains(object, 19)' + ) + .add('Underscore', '\ + _.contains(object, 19)' + ) + ); + + /*--------------------------------------------------------------------------*/ + suites.push( Benchmark.Suite('`_.countBy` with `callback` iterating an array') .add('Lo-Dash', '\ From 4b95f079234589b872990bdf164fc5f222a1d705 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 23:32:17 -0700 Subject: [PATCH 13/79] Simplify `_.omit` and `_.pick` for the `lodash underscore` build. Former-commit-id: 9a42c964ce4003bde1b4ce55f0f851141dbc9bb6 --- build.js | 39 ++++++++++++++++++++++++++++++++++++++- test/test-build.js | 7 +++++++ test/test.js | 2 +- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/build.js b/build.js index 4bb8eeac98..aacd7eded8 100755 --- a/build.js +++ b/build.js @@ -70,7 +70,7 @@ 'clone': ['extend', 'forEach', 'forOwn', 'isArguments', 'isPlainObject'], 'compact': [], 'compose': [], - 'contains': ['some'], + 'contains': ['indexOf', 'some'], 'countBy': ['forEach'], 'debounce': [], 'defaults': ['isArguments'], @@ -975,6 +975,7 @@ if (isUnderscore) { dependencyMap.isEqual = ['isArray', 'isFunction']; dependencyMap.isEmpty = ['isArray', 'isString']; + dependencyMap.pick = []; if (useUnderscoreClone) { dependencyMap.clone = ['extend', 'isArray']; @@ -1132,6 +1133,39 @@ ' }' ].join('\n')); + // replace `_.omit` + source = source.replace(/^( +)function omit[\s\S]+?\n\1}/m, [ + ' function omit(object) {', + ' var props = concat.apply(ArrayProto, arguments),', + ' result = {};', + '', + ' forIn(object, function(value, key) {', + ' if (indexOf(props, key, 1) < 0) {', + ' result[key] = value;', + ' }', + ' });', + ' return result;', + ' }' + ].join('\n')); + + // replace `_.pick` + source = source.replace(/^( +)function pick[\s\S]+?\n\1}/m, [ + ' function pick(object) {', + ' var index = 0,', + ' props = concat.apply(ArrayProto, arguments),', + ' length = props.length,', + ' result = {};', + '', + ' while (++index < length) {', + ' var prop = props[index];', + ' if (prop in object) {', + ' result[prop] = object[prop];', + ' }', + ' }', + ' return result;', + ' }' + ].join('\n')); + // replace `_.without` source = source.replace(/^( +)function without[\s\S]+?\n\1}/m, [ ' function without(array) {', @@ -1149,6 +1183,9 @@ ' }' ].join('\n')); + // remove string support from `_.contains` + source = source.replace(/return *\(toString\.call.+?stringClass[\s\S]+?;/, 'return indexOf(collection, target) > -1;'); + // replace `arrayLikeClasses` in `_.isEqual` source = source.replace(/(?: *\/\/.*\n)*( +)var isArr *= *arrayLikeClasses[^}]+}/, '$1var isArr = isArray(a);'); diff --git a/test/test-build.js b/test/test-build.js index 5a649c25e5..c113f68319 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -639,6 +639,13 @@ object = { 'fn': lodash.bind(function(x) { return this.x + x; }, { 'x': 1 }, 1) }; equal(object.fn(), 2, '_.bind: ' + basename); + object = { 'a': 1, 'b': 2, 'c': 3 }; + var actual = lodash.omit(object, function(value) { return value == 3; }); + deepEqual(_.keys(actual).sort(), ['a', 'b', 'c'], '_.omit: ' + basename); + + actual = lodash.pick(object, function(value) { return value != 3; }); + deepEqual(_.keys(actual), [], '_.pick: ' + basename); + ok(lodash.clone(array, true)[0] === array[0], '_.clone: ' + basename); start(); }); diff --git a/test/test.js b/test/test.js index ec392f583e..f7a08e3b3b 100644 --- a/test/test.js +++ b/test/test.js @@ -1499,7 +1499,7 @@ equal(compiled(data), '1'); }); - + test('should work when passing `options.variable`', function() { var compiled = _.template( '<% _.forEach( data.a, function( value ) { %>' + From eb32bd45e7225745cf7ba8d435e9737f8d8abe7c Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Oct 2012 23:33:16 -0700 Subject: [PATCH 14/79] Rebuild docs and minified builds. Former-commit-id: 556d91b9c58c9f6be2994ec17de3823f49416911 --- doc/README.md | 219 ++++++++++++++++++++------------------- lodash.min.js | 30 +++--- lodash.underscore.min.js | 50 ++++----- 3 files changed, 152 insertions(+), 147 deletions(-) diff --git a/doc/README.md b/doc/README.md index 4121653823..f5b48cf08e 100644 --- a/doc/README.md +++ b/doc/README.md @@ -184,7 +184,7 @@ ### `_.compact(array)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2511 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2530 "View in source") [Ⓣ][1] Creates an array with all falsey values of `array` removed. The values `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey. @@ -208,7 +208,7 @@ _.compact([0, 1, false, 2, '', 3]); ### `_.difference(array [, array1, array2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2541 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2560 "View in source") [Ⓣ][1] Creates an array of `array` elements not present in the other arrays using strict equality for comparisons, i.e. `===`. @@ -233,7 +233,7 @@ _.difference([1, 2, 3, 4, 5], [5, 2, 10]); ### `_.first(array [, n])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2579 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2598 "View in source") [Ⓣ][1] Gets the first element of the `array`. Pass `n` to return the first `n` elements of the `array`. @@ -261,7 +261,7 @@ _.first([5, 4, 3, 2, 1]); ### `_.flatten(array, shallow)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2603 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2622 "View in source") [Ⓣ][1] Flattens a nested array *(the nesting can be to any depth)*. If `shallow` is truthy, `array` will only be flattened a single level. @@ -289,7 +289,7 @@ _.flatten([1, [2], [3, [[4]]]], true); ### `_.indexOf(array, value [, fromIndex=0])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2645 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2664 "View in source") [Ⓣ][1] Gets the index at which the first occurrence of `value` is found using strict equality for comparisons, i.e. `===`. If the `array` is already sorted, passing `true` for `fromIndex` will run a faster binary search. @@ -321,7 +321,7 @@ _.indexOf([1, 1, 2, 2, 3, 3], 2, true); ### `_.initial(array [, n])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2680 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2699 "View in source") [Ⓣ][1] Gets all but the last element of `array`. Pass `n` to exclude the last `n` elements from the result. @@ -346,7 +346,7 @@ _.initial([3, 2, 1]); ### `_.intersection([array1, array2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2701 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2720 "View in source") [Ⓣ][1] Computes the intersection of all the passed-in arrays using strict equality for comparisons, i.e. `===`. @@ -370,7 +370,7 @@ _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); ### `_.last(array [, n])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2740 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2759 "View in source") [Ⓣ][1] Gets the last element of the `array`. Pass `n` to return the last `n` elements of the `array`. @@ -395,7 +395,7 @@ _.last([3, 2, 1]); ### `_.lastIndexOf(array, value [, fromIndex=array.length-1])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2766 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2785 "View in source") [Ⓣ][1] Gets the index at which the last occurrence of `value` is found using strict equality for comparisons, i.e. `===`. @@ -424,7 +424,7 @@ _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); ### `_.object(keys [, values=[]])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2796 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2815 "View in source") [Ⓣ][1] Creates an object composed from arrays of `keys` and `values`. Pass either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or two arrays, one of `keys` and one of corresponding `values`. @@ -449,7 +449,7 @@ _.object(['moe', 'larry', 'curly'], [30, 40, 50]); ### `_.range([start=0], end [, step=1])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2841 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2860 "View in source") [Ⓣ][1] Creates an array of numbers *(positive and/or negative)* progressing from `start` up to but not including `stop`. This method is a port of Python's `range()` function. See http://docs.python.org/library/functions.html#range. @@ -487,7 +487,7 @@ _.range(0); ### `_.rest(array [, n])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2880 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2899 "View in source") [Ⓣ][1] The opposite of `_.initial`, this method gets all but the first value of `array`. Pass `n` to exclude the first `n` values from the result. @@ -515,7 +515,7 @@ _.rest([3, 2, 1]); ### `_.sortedIndex(array, value [, callback=identity|property, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2926 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2945 "View in source") [Ⓣ][1] Uses a binary search to determine the smallest index at which the `value` should be inserted into `array` in order to maintain the sort order of the sorted `array`. If `callback` is passed, it will be executed for `value` and each element in `array` to compute their sort ranking. The `callback` is bound to `thisArg` and invoked with one argument; *(value)*. The `callback` argument may also be the name of a property to order by. @@ -559,7 +559,7 @@ _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { ### `_.union([array1, array2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2961 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2980 "View in source") [Ⓣ][1] Computes the union of the passed-in arrays using strict equality for comparisons, i.e. `===`. @@ -583,7 +583,7 @@ _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); ### `_.uniq(array [, isSorted=false, callback=identity, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3006 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3025 "View in source") [Ⓣ][1] Creates a duplicate-value-free version of the `array` using strict equality for comparisons, i.e. `===`. If the `array` is already sorted, passing `true` for `isSorted` will run a faster algorithm. If `callback` is passed, each element of `array` is passed through a callback` before uniqueness is computed. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index, array)*. @@ -622,7 +622,7 @@ _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math); ### `_.without(array [, value1, value2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3047 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3066 "View in source") [Ⓣ][1] Creates an array with all occurrences of the passed values removed using strict equality for comparisons, i.e. `===`. @@ -647,7 +647,7 @@ _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); ### `_.zip([array1, array2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3078 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3097 "View in source") [Ⓣ][1] Groups the elements of each array at their corresponding indexes. Useful for separate data sources that are coordinated through matching array indexes. For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix in a similar fashion. @@ -696,7 +696,7 @@ The `lodash` function. ### `_.chain(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3929 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3953 "View in source") [Ⓣ][1] Wraps the value in a `lodash` wrapper object. @@ -730,7 +730,7 @@ var youngest = _.chain(stooges) ### `_.tap(value, interceptor)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3956 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3980 "View in source") [Ⓣ][1] Invokes `interceptor` with the `value` as the first argument, and then returns `value`. The purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. @@ -760,7 +760,7 @@ _.chain([1, 2, 3, 200]) ### `_.prototype.chain()` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3974 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3998 "View in source") [Ⓣ][1] Enables method chaining on the wrapper object. @@ -781,7 +781,7 @@ _([1, 2, 3]).value(); ### `_.prototype.value()` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3991 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L4015 "View in source") [Ⓣ][1] Extracts the wrapped value. @@ -809,7 +809,7 @@ _([1, 2, 3]).value(); ### `_.contains(collection, target)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1872 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1870 "View in source") [Ⓣ][1] Checks if a given `target` element is present in a `collection` using strict equality for comparisons, i.e. `===`. @@ -843,7 +843,7 @@ _.contains('curly', 'ur'); ### `_.countBy(collection, callback|property [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1908 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1909 "View in source") [Ⓣ][1] Creates an object composed of keys returned from running each element of `collection` through a `callback`. The corresponding value of each key is the number of times the key was returned by `callback`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. The `callback` argument may also be the name of a property to count by *(e.g. 'length')*. @@ -875,7 +875,7 @@ _.countBy(['one', 'two', 'three'], 'length'); ### `_.every(collection [, callback=identity, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1929 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1938 "View in source") [Ⓣ][1] Checks if the `callback` returns a truthy value for **all** elements of a `collection`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. @@ -904,7 +904,7 @@ _.every([true, 1, null, 'yes'], Boolean); ### `_.filter(collection [, callback=identity, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1949 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1958 "View in source") [Ⓣ][1] Examines each element in a `collection`, returning an array of all elements the `callback` returns truthy for. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. @@ -933,7 +933,7 @@ var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }) ### `_.find(collection, callback [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1971 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1980 "View in source") [Ⓣ][1] Examines each element in a `collection`, returning the first one the `callback` returns truthy for. The function returns as soon as it finds an acceptable element, and does not iterate over the entire `collection`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. @@ -962,7 +962,7 @@ var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); ### `_.forEach(collection, callback [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1998 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2011 "View in source") [Ⓣ][1] Iterates over a `collection`, executing the `callback` for each element in the `collection`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. Callbacks may exit iteration early by explicitly returning `false`. @@ -994,7 +994,7 @@ _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert); ### `_.groupBy(collection, callback|property [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2026 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2039 "View in source") [Ⓣ][1] Creates an object composed of keys returned from running each element of `collection` through a `callback`. The corresponding value of each key is an array of elements passed to `callback` that returned the key. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. The `callback` argument may also be the name of a property to count by *(e.g. 'length')*. @@ -1026,7 +1026,7 @@ _.groupBy(['one', 'two', 'three'], 'length'); ### `_.invoke(collection, methodName [, arg1, arg2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2054 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2071 "View in source") [Ⓣ][1] Invokes the method named by `methodName` on each element in the `collection`, returning an array of the results of each invoked method. Additional arguments will be passed to each invoked method. If `methodName` is a function it will be invoked for, and `this` bound to, each element in the `collection`. @@ -1055,7 +1055,7 @@ _.invoke([123, 456], String.prototype.split, ''); ### `_.map(collection [, callback=identity, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2089 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2103 "View in source") [Ⓣ][1] Creates an array of values by running each element in the `collection` through a `callback`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. @@ -1087,7 +1087,7 @@ _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); ### `_.max(collection [, callback, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2115 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2139 "View in source") [Ⓣ][1] Retrieves the maximum value of an `array`. If `callback` is passed, it will be executed for each value in the `array` to generate the criterion by which the value is ranked. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index, collection)*. @@ -1119,7 +1119,7 @@ _.max(stooges, function(stooge) { return stooge.age; }); ### `_.min(collection [, callback, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2158 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2182 "View in source") [Ⓣ][1] Retrieves the minimum value of an `array`. If `callback` is passed, it will be executed for each value in the `array` to generate the criterion by which the value is ranked. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index, collection)*. @@ -1145,7 +1145,7 @@ _.min([10, 5, 100, 2, 1000]); ### `_.pluck(collection, property)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2204 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2228 "View in source") [Ⓣ][1] Retrieves the value of a specified property from all elements in the `collection`. @@ -1176,7 +1176,7 @@ _.pluck(stooges, 'name'); ### `_.reduce(collection, callback [, accumulator, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2232 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2256 "View in source") [Ⓣ][1] Boils down a `collection` to a single value. The initial state of the reduction is `accumulator` and each successive step of it should be returned by the `callback`. The `callback` is bound to `thisArg` and invoked with `4` arguments; for arrays they are *(accumulator, value, index|key, collection)*. @@ -1206,7 +1206,7 @@ var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; }); ### `_.reduceRight(collection, callback [, accumulator, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2269 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2285 "View in source") [Ⓣ][1] The right-associative version of `_.reduce`. @@ -1237,7 +1237,7 @@ var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); ### `_.reject(collection [, callback=identity, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2306 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2322 "View in source") [Ⓣ][1] The opposite of `_.filter`, this method returns the values of a `collection` that `callback` does **not** return truthy for. @@ -1263,7 +1263,7 @@ var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); ### `_.shuffle(collection)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2324 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2340 "View in source") [Ⓣ][1] Creates an array of shuffled `array` values, using a version of the Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. @@ -1287,7 +1287,7 @@ _.shuffle([1, 2, 3, 4, 5, 6]); ### `_.size(collection)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2356 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2372 "View in source") [Ⓣ][1] Gets the size of the `collection` by returning `collection.length` for arrays and array-like objects or the number of own enumerable properties for objects. @@ -1317,7 +1317,7 @@ _.size('curly'); ### `_.some(collection [, callback=identity, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2381 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2397 "View in source") [Ⓣ][1] 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 does not iterate over the entire `collection`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. @@ -1346,7 +1346,7 @@ _.some([null, 0, 'yes', false]); ### `_.sortBy(collection, callback|property [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2411 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2427 "View in source") [Ⓣ][1] Creates an array, stable sorted in ascending order by the results of running each element of `collection` through a `callback`. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, index|key, collection)*. The `callback` argument may also be the name of a property to sort by *(e.g. 'length')*. @@ -1378,7 +1378,7 @@ _.sortBy(['larry', 'brendan', 'moe'], 'length'); ### `_.toArray(collection)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2447 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2459 "View in source") [Ⓣ][1] Converts the `collection`, to an array. @@ -1402,7 +1402,7 @@ Converts the `collection`, to an array. ### `_.where(collection, properties)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2481 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L2493 "View in source") [Ⓣ][1] Examines each element in a `collection`, returning an array of all elements that contain the given `properties`. @@ -1440,7 +1440,7 @@ _.where(stooges, { 'age': 40 }); ### `_.after(n, func)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3110 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3129 "View in source") [Ⓣ][1] Creates a function that is restricted to executing only after it is called `n` times. @@ -1468,7 +1468,7 @@ _.forEach(notes, function(note) { ### `_.bind(func [, thisArg, arg1, arg2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3143 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3162 "View in source") [Ⓣ][1] Creates a function that, when called, invokes `func` with the `this` binding of `thisArg` and prepends any additional `bind` arguments to those passed to the bound function. @@ -1499,7 +1499,7 @@ func(); ### `_.bindAll(object [, methodName1, methodName2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3173 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3192 "View in source") [Ⓣ][1] Binds methods on `object` to `object`, overwriting the existing method. If no method names are provided, all the function properties of `object` will be bound. @@ -1530,7 +1530,7 @@ jQuery('#lodash_button').on('click', buttonView.onClick); ### `_.compose([func1, func2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3209 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3228 "View in source") [Ⓣ][1] Creates a function that is the composition of the passed functions, where each function consumes the return value of the function that follows. In math terms, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. @@ -1557,7 +1557,7 @@ welcome('moe'); ### `_.debounce(func, wait, immediate)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3242 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3261 "View in source") [Ⓣ][1] Creates a function that will delay the execution of `func` until after `wait` milliseconds have elapsed since the last time it was invoked. Pass `true` for `immediate` to cause debounce to invoke `func` on the leading, instead of the trailing, edge of the `wait` timeout. Subsequent calls to the debounced function will return the result of the last `func` call. @@ -1583,7 +1583,7 @@ jQuery(window).on('resize', lazyLayout); ### `_.defer(func [, arg1, arg2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3307 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3326 "View in source") [Ⓣ][1] Defers executing the `func` function until the current call stack has cleared. Additional arguments will be passed to `func` when it is invoked. @@ -1608,7 +1608,7 @@ _.defer(function() { alert('deferred'); }); ### `_.delay(func, wait [, arg1, arg2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3287 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3306 "View in source") [Ⓣ][1] Executes the `func` function after `wait` milliseconds. Additional arguments will be passed to `func` when it is invoked. @@ -1635,7 +1635,7 @@ _.delay(log, 1000, 'logged later'); ### `_.lateBind(object, methodName [, arg1, arg2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3345 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3364 "View in source") [Ⓣ][1] Creates a function that, when called, invokes `object[methodName]` and prepends any additional `lateBind` arguments to those passed to the bound function. This method differs from `_.bind` by allowing bound functions to reference methods that will be redefined or don't yet exist. @@ -1676,7 +1676,7 @@ func(); ### `_.memoize(func [, resolver])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3367 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3386 "View in source") [Ⓣ][1] Creates a function that memoizes the result of `func`. If `resolver` is passed, it will be used to determine the cache key for storing the result based on the arguments passed to the memoized function. By default, the first argument passed to the memoized function is used as the cache key. @@ -1702,7 +1702,7 @@ var fibonacci = _.memoize(function(n) { ### `_.once(func)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3393 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3412 "View in source") [Ⓣ][1] Creates a function that is restricted to one execution. Repeat calls to the function will return the value of the first call. @@ -1728,7 +1728,7 @@ initialize(); ### `_.partial(func [, arg1, arg2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3428 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3447 "View in source") [Ⓣ][1] Creates a function that, when called, invokes `func` with any additional `partial` arguments prepended to those passed to the new function. This method is similar to `bind`, except it does **not** alter the `this` binding. @@ -1755,7 +1755,7 @@ hi('moe'); ### `_.throttle(func, wait)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3450 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3469 "View in source") [Ⓣ][1] Creates a function that, when executed, will only call the `func` function at most once per every `wait` milliseconds. If the throttled function is invoked more than once during the `wait` timeout, `func` will also be called on the trailing edge of the timeout. Subsequent calls to the throttled function will return the result of the last `func` call. @@ -1780,7 +1780,7 @@ jQuery(window).on('scroll', throttled); ### `_.wrap(value, wrapper)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3502 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3521 "View in source") [Ⓣ][1] Creates a function that passes `value` to the `wrapper` function as its first argument. Additional arguments passed to the new function are appended to those passed to the `wrapper` function. @@ -1816,7 +1816,7 @@ hello(); ### `_.clone(value, deep)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1029 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L985 "View in source") [Ⓣ][1] Creates a clone of `value`. If `deep` is `true`, all nested objects will also be cloned otherwise they will be assigned by reference. Functions, DOM nodes, `arguments` objects, and objects created by constructors other than `Object` are **not** cloned. @@ -1855,7 +1855,7 @@ shallow[0] === stooges[0]; ### `_.defaults(object [, default1, default2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1112 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1068 "View in source") [Ⓣ][1] Assigns enumerable properties of the default object(s) to the `destination` object for all `destination` properties that resolve to `null`/`undefined`. Once a property is set, additional defaults of the same property will be ignored. @@ -1881,7 +1881,7 @@ _.defaults(iceCream, { 'flavor': 'vanilla', 'sprinkles': 'rainbow' }); ### `_.extend(object [, source1, source2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1132 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1088 "View in source") [Ⓣ][1] Assigns enumerable properties of the source object(s) to the `destination` object. Subsequent sources will overwrite propery assignments of previous sources. @@ -1906,7 +1906,7 @@ _.extend({ 'name': 'moe' }, { 'age': 40 }); ### `_.forIn(object, callback [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1162 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1118 "View in source") [Ⓣ][1] Iterates over `object`'s own and inherited enumerable properties, executing the `callback` for each property. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, key, object)*. Callbacks may exit iteration early by explicitly returning `false`. @@ -1942,7 +1942,7 @@ _.forIn(new Dog('Dagny'), function(value, key) { ### `_.forOwn(object, callback [, thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1186 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1142 "View in source") [Ⓣ][1] Iterates over `object`'s own enumerable properties, executing the `callback` for each property. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, key, object)*. Callbacks may exit iteration early by explicitly returning `false`. @@ -1970,7 +1970,7 @@ _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { ### `_.functions(object)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1203 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1159 "View in source") [Ⓣ][1] Creates a sorted array of all enumerable properties, own and inherited, of `object` that have function values. @@ -1997,7 +1997,7 @@ _.functions(_); ### `_.has(object, property)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1226 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1184 "View in source") [Ⓣ][1] Checks if the specified object `property` exists and is a direct property, instead of an inherited property. @@ -2022,7 +2022,7 @@ _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); ### `_.invert(object)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L804 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L760 "View in source") [Ⓣ][1] Creates an object composed of the inverted keys and values of the given `object`. @@ -2046,7 +2046,7 @@ _.invert({ 'first': 'Moe', 'second': 'Larry', 'third': 'Curly' }); ### `_.isArguments(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L826 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L782 "View in source") [Ⓣ][1] Checks if `value` is an `arguments` object. @@ -2073,7 +2073,7 @@ _.isArguments([1, 2, 3]); ### `_.isArray(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L852 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L808 "View in source") [Ⓣ][1] Checks if `value` is an array. @@ -2100,7 +2100,7 @@ _.isArray([1, 2, 3]); ### `_.isBoolean(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1243 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1201 "View in source") [Ⓣ][1] Checks if `value` is a boolean *(`true` or `false`)* value. @@ -2124,7 +2124,7 @@ _.isBoolean(null); ### `_.isDate(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1260 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1218 "View in source") [Ⓣ][1] Checks if `value` is a date. @@ -2148,7 +2148,7 @@ _.isDate(new Date); ### `_.isElement(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1277 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1235 "View in source") [Ⓣ][1] Checks if `value` is a DOM element. @@ -2172,7 +2172,7 @@ _.isElement(document.body); ### `_.isEmpty(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1302 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1260 "View in source") [Ⓣ][1] Checks if `value` is empty. Arrays, strings, or `arguments` objects with a length of `0` and objects with no own enumerable properties are considered "empty". @@ -2202,7 +2202,7 @@ _.isEmpty(''); ### `_.isEqual(a, b)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1341 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1301 "View in source") [Ⓣ][1] Performs a deep comparison between two values to determine if they are equivalent to each other. @@ -2233,7 +2233,7 @@ _.isEqual(moe, clone); ### `_.isFinite(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1498 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1458 "View in source") [Ⓣ][1] Checks if `value` is a finite number. Note: This is not the same as native `isFinite`, which will return true for booleans and other values. See http://es5.github.com/#x15.1.2.5. @@ -2263,7 +2263,7 @@ _.isFinite(Infinity); ### `_.isFunction(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L869 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L825 "View in source") [Ⓣ][1] Checks if `value` is a function. @@ -2287,7 +2287,7 @@ _.isFunction(_); ### `_.isNaN(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1556 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1516 "View in source") [Ⓣ][1] Checks if `value` is `NaN`. Note: This is not the same as native `isNaN`, which will return true for `undefined` and other values. See http://es5.github.com/#x15.1.2.4. @@ -2320,7 +2320,7 @@ _.isNaN(undefined); ### `_.isNull(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1579 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1539 "View in source") [Ⓣ][1] Checks if `value` is `null`. @@ -2347,7 +2347,7 @@ _.isNull(undefined); ### `_.isNumber(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1596 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1556 "View in source") [Ⓣ][1] Checks if `value` is a number. @@ -2371,7 +2371,7 @@ _.isNumber(8.4 * 5); ### `_.isObject(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1522 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1482 "View in source") [Ⓣ][1] Checks if `value` is the language type of Object. *(e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)* @@ -2401,7 +2401,7 @@ _.isObject(1); ### `_.isPlainObject(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L903 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L859 "View in source") [Ⓣ][1] Checks if a given `value` is an object created by the `Object` constructor. @@ -2419,10 +2419,10 @@ function Stooge(name, age) { } _.isPlainObject(new Stooge('moe', 40)); -// false +// => false _.isPlainObject([1, 2, 3]); -// false +// => false _.isPlainObject({ 'name': 'moe', 'age': 40 }); // => true @@ -2436,7 +2436,7 @@ _.isPlainObject({ 'name': 'moe', 'age': 40 }); ### `_.isRegExp(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1613 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1573 "View in source") [Ⓣ][1] Checks if `value` is a regular expression. @@ -2460,7 +2460,7 @@ _.isRegExp(/moe/); ### `_.isString(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1630 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1590 "View in source") [Ⓣ][1] Checks if `value` is a string. @@ -2484,7 +2484,7 @@ _.isString('moe'); ### `_.isUndefined(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1648 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1608 "View in source") [Ⓣ][1] Checks if `value` is `undefined`. @@ -2508,7 +2508,7 @@ _.isUndefined(void 0); ### `_.keys(object)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1665 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1625 "View in source") [Ⓣ][1] Creates an array composed of the own enumerable property names of `object`. @@ -2532,7 +2532,7 @@ _.keys({ 'one': 1, 'two': 2, 'three': 3 }); ### `_.merge(object [, source1, source2, ...])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1708 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1668 "View in source") [Ⓣ][1] Merges enumerable properties of the source object(s) into the `destination` object. Subsequent sources will overwrite propery assignments of previous sources. @@ -2567,7 +2567,7 @@ _.merge(stooges, ages); ### `_.omit(object, callback|[prop1, prop2, ..., thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1765 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1734 "View in source") [Ⓣ][1] Creates a shallow clone of `object` excluding the specified properties. Property names may be specified as individual arguments or as arrays of property names. If `callback` is passed, it will be executed for each property in the `object`, omitting the properties `callback` returns truthy for. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, key, object)*. @@ -2598,7 +2598,7 @@ _.omit({ 'name': 'moe', '_hint': 'knucklehead', '_seed': '96c4eb' }, function(va ### `_.pairs(object)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1781 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1768 "View in source") [Ⓣ][1] Creates a two dimensional array of the given object's key-value pairs, i.e. `[[key1, value1], [key2, value2]]`. @@ -2622,7 +2622,7 @@ _.pairs({ 'moe': 30, 'larry': 40, 'curly': 50 }); ### `_.pick(object, callback|[prop1, prop2, ..., thisArg])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1812 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1801 "View in source") [Ⓣ][1] Creates a shallow clone of `object` composed of the specified properties. Property names may be specified as individual arguments or as arrays of property names. If `callback` is passed, it will be executed for each property in the `object`, picking the properties `callback` returns truthy for. The `callback` is bound to `thisArg` and invoked with three arguments; *(value, key, object)*. @@ -2653,7 +2653,7 @@ _.pick({ 'name': 'moe', '_hint': 'knucklehead', '_seed': '96c4eb' }, function(va ### `_.values(object)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1842 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L1838 "View in source") [Ⓣ][1] Creates an array composed of the own enumerable property values of `object`. @@ -2684,7 +2684,7 @@ _.values({ 'one': 1, 'two': 2, 'three': 3 }); ### `_.escape(string)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3528 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3547 "View in source") [Ⓣ][1] Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their corresponding HTML entities. @@ -2708,7 +2708,7 @@ _.escape('Moe, Larry & Curly'); ### `_.identity(value)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3548 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3567 "View in source") [Ⓣ][1] This function returns the first argument passed to it. Note: It is used throughout Lo-Dash as a default callback. @@ -2733,7 +2733,7 @@ moe === _.identity(moe); ### `_.mixin(object)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3574 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3593 "View in source") [Ⓣ][1] Adds functions properties of `object` to the `lodash` function and chainable wrapper. @@ -2763,7 +2763,7 @@ _('curly').capitalize(); ### `_.noConflict()` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3605 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3624 "View in source") [Ⓣ][1] Reverts the '_' variable to its previous value and returns a reference to the `lodash` function. @@ -2783,7 +2783,7 @@ var lodash = _.noConflict(); ### `_.random([min=0, max=1])` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3628 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3647 "View in source") [Ⓣ][1] Produces a random number between `min` and `max` *(inclusive)*. If only one argument is passed, a number between `0` and the given number will be returned. @@ -2811,7 +2811,7 @@ _.random(5); ### `_.result(object, property)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3667 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3686 "View in source") [Ⓣ][1] Resolves the value of `property` on `object`. If `property` is a function it will be invoked and its result returned, else the property value is returned. If `object` is falsey, then `null` is returned. @@ -2846,7 +2846,7 @@ _.result(object, 'stuff'); ### `_.template(text, data, options)` -# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3737 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/bestiejs/lodash/blob/master/lodash.js#L3761 "View in source") [Ⓣ][1] A micro-templating method that handles arbitrary delimiters, preserves whitespace, and correctly escapes quotes within interpolated code. Note: In the development build `_.template` utilizes sourceURLs for easier debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp` build and avoiding `_.template` use, or loading Lo-Dash in a sandboxed page. See http://developer.chrome.com/trunk/extensions/sandboxingEval.html @@ -2861,9 +2861,9 @@ A micro-templating method that handles arbitrary delimiters, preserves whitespac #### Example ```js // using a compiled template -var compiled = _.template('hello: <%= name %>'); +var compiled = _.template('hello <%= name %>'); compiled({ 'name': 'moe' }); -// => 'hello: moe' +// => 'hello moe' var list = '<% _.forEach(people, function(name) { %>
  • <%= name %>
  • <% }); %>'; _.template(list, { 'people': ['moe', 'larry', 'curly'] }); @@ -2874,26 +2874,31 @@ _.template('<%- value %>', { 'value': ' - - +
    + + + + diff --git a/test/index.html b/test/index.html index 278db46d88..f48175b64b 100644 --- a/test/index.html +++ b/test/index.html @@ -22,7 +22,7 @@ Object.keys = function() { return []; }; // load Lo-Dash and expose it to the bad `Object.keys` shim - document.write(' From 8617dedc460d58bcd2935b5e5c27c22e9b696076 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Oct 2012 23:32:14 -0700 Subject: [PATCH 27/79] Use the `buildPath` and `otherPath` in the logged perf status updates. Former-commit-id: 0f1301e68dca84c0f72459bcfed11b3cc55cb577 --- perf/index.html | 4 +- perf/perf-ui.js | 42 ++--- perf/perf.js | 403 +++++++++++++++++++++++-------------------- test/backbone.html | 2 +- test/index.html | 34 ++-- test/test-ui.js | 19 +- test/underscore.html | 2 +- 7 files changed, 270 insertions(+), 236 deletions(-) diff --git a/perf/index.html b/perf/index.html index 31dc31788f..5fe5abbc24 100644 --- a/perf/index.html +++ b/perf/index.html @@ -33,13 +33,13 @@ diff --git a/test/index.html b/test/index.html index f48175b64b..8b571dc82b 100644 --- a/test/index.html +++ b/test/index.html @@ -22,7 +22,7 @@ Object.keys = function() { return []; }; // load Lo-Dash and expose it to the bad `Object.keys` shim - document.write(' From 3b7ab2e5535182b5eee410fe2229c9916fe80618 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Oct 2012 08:15:29 -0700 Subject: [PATCH 28/79] Make lib references more generic in perf.js. Former-commit-id: 9984b8ac9f552d5a1051d738b57ff0b69b8d764a --- perf/perf.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/perf/perf.js b/perf/perf.js index df00544f23..7085114d6d 100644 --- a/perf/perf.js +++ b/perf/perf.js @@ -28,8 +28,8 @@ /** Used to access the Firebug Lite panel (set by `run`) */ var fbPanel; - /** Used to score Lo-Dash and Underscore performance */ - var score = { 'lodash': 0, 'underscore': 0 }; + /** Used to score performance */ + var score = { 'a': 0, 'b': 0 }; /** Used to queue benchmark suites */ var suites = []; @@ -38,10 +38,10 @@ var ui = window.ui || {}; /** The Lo-Dash build basename */ - var buildName = basename(ui.buildPath || 'lodash.min', '.js'); + var buildName = basename(ui.buildPath || 'lodash', '.js'); /** The other library basename */ - var otherName = basename(ui.otherPath || 'underscore-min', '.js'); + var otherName = basename(ui.otherPath || 'underscore', '.js'); /** Add `console.log()` support for Narwhal and RingoJS */ window.console || (window.console = { 'log': window.print }); @@ -54,7 +54,7 @@ /*--------------------------------------------------------------------------*/ /** - * Gets the basename of the given `filePath`. If the file `extension` is passed + * Gets the basename of the given `filePath`. If the file `extension` is passed, * it will be removed from the basename. * * @private @@ -124,12 +124,12 @@ fastestHz = getHz(fastest[0]), slowest = this.filter('slowest'), slowestHz = getHz(slowest[0]), - lodashHz = getHz(this[0]), - underscoreHz = getHz(this[1]); + aHz = getHz(this[0]), + bHz = getHz(this[1]); if (fastest.length > 1) { log('It\'s too close to call.'); - lodashHz = underscoreHz = slowestHz; + aHz = bHz = slowestHz; } else { var percent = ((fastestHz / slowestHz) - 1) * 100; @@ -141,8 +141,8 @@ ); } // add score adjusted for margin of error - score.lodash += lodashHz; - score.underscore += underscoreHz; + score.a += aHz; + score.b += bHz; // remove current suite from queue suites.shift(); @@ -152,14 +152,14 @@ suites[0].run(); } else { - var fastestTotalHz = Math.max(score.lodash, score.underscore), - slowestTotalHz = Math.min(score.lodash, score.underscore), + var fastestTotalHz = Math.max(score.a, score.b), + slowestTotalHz = Math.min(score.a, score.b), totalPercent = formatNumber(Math.round(((fastestTotalHz / slowestTotalHz) - 1) * 100)), totalX = fastestTotalHz / slowestTotalHz, message = 'is ' + totalPercent + '% ' + (totalX == 1 ? '' : '(' + formatNumber(totalX.toFixed(2)) + 'x) ') + 'faster than'; // report results - if (score.lodash >= score.underscore) { + if (score.a >= score.b) { log('\n' + buildName + ' ' + message + ' ' + otherName + '.'); } else { log('\n' + otherName + ' ' + message + ' ' + buildName + '.'); From e2de22470e9a4cf5f2a4d98e633a25d07ee2872b Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 17 Oct 2012 00:36:31 -0700 Subject: [PATCH 29/79] Cleanup vendors. Former-commit-id: 9e4f91aa0d498c1b160907f365b82b902e516880 --- .gitignore | 2 + perf/index.html | 2 +- test/backbone.html | 6 +- test/underscore.html | 6 +- vendor/backbone/test/vendor/jquery-1.7.1.js | 9266 ----- vendor/backbone/test/vendor/qunit.css | 235 - vendor/backbone/test/vendor/qunit.js | 1977 - vendor/firebug-lite/src/firebug-lite-debug.js | 31176 ---------------- vendor/firebug-lite/src/firebug-lite.js | 8257 ++++ vendor/jquery/MIT-LICENSE.txt | 21 + vendor/jquery/README.md | 417 + vendor/jquery/jquery.min.js | 2 + vendor/json3/lib/json3.js | 783 - vendor/json3/lib/json3.min.js | 17 + vendor/underscore/test/vendor/jquery.js | 9404 ----- vendor/underscore/test/vendor/qunit.css | 235 - vendor/underscore/test/vendor/qunit.js | 1977 - 17 files changed, 8723 insertions(+), 55060 deletions(-) delete mode 100644 vendor/backbone/test/vendor/jquery-1.7.1.js delete mode 100755 vendor/backbone/test/vendor/qunit.css delete mode 100755 vendor/backbone/test/vendor/qunit.js delete mode 100644 vendor/firebug-lite/src/firebug-lite-debug.js create mode 100644 vendor/firebug-lite/src/firebug-lite.js create mode 100644 vendor/jquery/MIT-LICENSE.txt create mode 100644 vendor/jquery/README.md create mode 100644 vendor/jquery/jquery.min.js delete mode 100644 vendor/json3/lib/json3.js create mode 100644 vendor/json3/lib/json3.min.js delete mode 100644 vendor/underscore/test/vendor/jquery.js delete mode 100644 vendor/underscore/test/vendor/qunit.css delete mode 100644 vendor/underscore/test/vendor/qunit.js diff --git a/.gitignore b/.gitignore index cf9a5f5959..51ba382fee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.custom.* .DS_Store node_modules/ +vendor/closure-compiler/ +vendor/uglifyjs/ diff --git a/perf/index.html b/perf/index.html index 5fe5abbc24..f2acbc6766 100644 --- a/perf/index.html +++ b/perf/index.html @@ -30,7 +30,7 @@
    - + - + + - + + - + - + + - + +