Compare commits

..

2 Commits

Author SHA1 Message Date
jdalton
f2d87df120 Bump to v3.10.0. 2015-06-30 09:40:56 -07:00
jdalton
7351c0b0b9 Rebuild lodash and docs. 2015-06-29 23:19:08 -07:00
81 changed files with 29795 additions and 47913 deletions

View File

@@ -4,9 +4,15 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true
[**.{js,json,md}]
indent_style = space
indent_size = 2
insert_final_newline = true
[**.html]
indent_style = tab
insert_final_newline = false

1
.gitignore vendored
View File

@@ -3,5 +3,4 @@
*.log
*.map
lodash.compat.min.js
coverage
node_modules

96
.jscsrc
View File

@@ -1,96 +0,0 @@
{
"maxErrors": "2000",
"maximumLineLength": {
"value": 180,
"allExcept": ["comments", "functionSignature", "regex"]
},
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": [
"=",
"+",
"-",
"/",
"*",
"==",
"===",
"!=",
"!==",
">",
">=",
"<",
"<="
],
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpaceBeforeBinaryOperators": [
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"&=", "|=", "^=", "+=",
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
"|", "^", "&&", "||", "===", "==", ">=",
"<=", "<", ">", "!=", "!=="
],
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"requireCamelCaseOrUpperCaseIdentifiers": true,
"requireDotNotation": { "allExcept": ["keywords"] },
"requireEarlyReturn": true,
"requireLineFeedAtFileEnd": true,
"requireSemicolons": true,
"requireSpaceAfterBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeObjectValues": true,
"requireSpaceBeforeBlockStatements": true,
"requireSpacesInForStatement": true,
"validateIndentation": 2,
"validateParameterSeparator": ", ",
"validateQuoteMarks": { "mark": "'", "escape": true },
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInFunctionDeclaration": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowKeywords": ["with"],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleLineBreaks": true,
"disallowNewlineBeforeBlockStatements": true,
"disallowSpaceAfterObjectKeys": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpacesInCallExpression": true,
"disallowSpacesInsideArrayBrackets": true,
"disallowSpacesInsideParentheses": true,
"disallowTrailingWhitespace": true,
"jsDoc": {
"checkRedundantAccess": true,
"checkTypes": true,
"requireNewlineAfterDescription": true,
"requireParamDescription": true,
"requireParamTypes": true,
"requireReturnTypes": true
}
}

View File

@@ -1,25 +1,39 @@
language: node_js
sudo: false
node_js:
- "5"
- "0.12"
env:
global:
- BIN="node" ISTANBUL=false OPTION=""
- SAUCE_LABS=false SAUCE_USERNAME="lodash"
- PATTERN1="s|\s*else\s*\{\s*iteratee\(index\);\s*\}||"
- BIN="node" BUILD="compat" ISTANBUL=false OPTION=""
- NPM_VERSION="^2.0.0" SAUCE_LABS=false SAUCE_USERNAME="lodash"
- secure: "tg1JFsIFnxzLaTboFPOnm+aJCuMm5+JdhLlESlqg9x3fwro++7KCnwHKLNovhchaPe4otC43ZMB/nfWhDnDm11dKbm/V6HlTkED+dadTsaLxVDg6J+7yK41QhokBPJOxLV78iDaNaAQVYEirAgZ0yn8kFubxmNKV+bpCGQNc9yU="
matrix:
-
- BUILD="compat"
- BUILD="modern"
- BUILD="modern"
- BUILD="modern" ISTANBUL=true
- BIN="phantomjs"
- ISTANBUL=true
- SAUCE_LABS=true
- BIN="rhino" OPTION="-opt -1"
- BIN="rhino" OPTION="-opt -1 -require"
- BIN="ringo" OPTION="-o -1"
matrix:
include:
- node_js: "iojs"
env:
- node_js: "iojs"
env: BUILD="modern"
- node_js: "0.8"
env: NPM_VERSION="~1.4.0"
- node_js: "0.8"
env: BUILD="modern" NPM_VERSION="~1.4.0"
- node_js: "0.10"
env:
- node_js: "0.10"
env: BUILD="modern"
- node_js: "0.12"
env:
- node_js: "4"
env:
env: SAUCE_LABS=true
- node_js: "0.12"
env: SAUCE_LABS=true BUILD="modern"
git:
depth: 10
branches:
@@ -33,45 +47,30 @@ notifications:
on_failure: always
before_install:
- "nvm use $TRAVIS_NODE_VERSION"
- "npm set loglevel error"
- "npm set progress false"
- "npm i -g npm@\"^2.0.0\""
- |
PATTERN[0]="|\s*if\s*\(isHostObject\b[\s\S]+?\}(?=\n)|"
PATTERN[1]="|\s*if\s*\(enumerate\b[\s\S]+?\};\s*\}|"
PATTERN[2]="|\s*while\s*\([^)]+\)\s*\{\s*iteratee\(index\);\s*\}|"
PATTERN[3]="|\s*else\s*\{\s*assocSet\(data\b[\s\S]+?\}|"
PATTERN[4]="|\s*if\s*\(ctorString\b[\s\S]+?\}\s*\}|"
PATTERN[5]="|\bindex,\s*iterable\)\s*===\s*false\)[^}]+?(break;)|"
PATTERN[6]="|\s*if\s*\(!lodashFunc\)\s*\{\s*return;\s*\}|"
PATTERN[7]="|\s*define\([\s\S]+?\);|"
PATTERN[8]="|\s*root\._\s*=\s*_;|"
if [ $ISTANBUL == true ]; then
set -e
for PTRN in ${PATTERN[@]}; do
node ./test/remove.js "$PTRN" ./lodash.js
done
fi
- "git clone --depth=10 --branch=master git://github.com/lodash/lodash-cli ./node_modules/lodash-cli && mkdir $_/node_modules && cd $_ && ln -s ../../../ ./lodash && cd ../ && npm i && cd ../../"
- "node ./node_modules/lodash-cli/bin/lodash -o ./dist/lodash.js"
- "npm config set loglevel error"
- "npm i -g npm@\"$NPM_VERSION\""
- "[ $SAUCE_LABS == false ] || npm i chalk@\"^1.0.0\" ecstatic@\"0.8.0\" request@\"^2.0.0\" sauce-tunnel@\"2.2.3\""
- "[ $ISTANBUL == false ] || (npm i -g coveralls@\"^2.0.0\" && npm i istanbul@\"0.3.17\")"
- "[ $BIN != 'rhino' ] || (sudo mkdir /opt/rhino-1.7.6 && sudo wget --no-check-certificate -O $_/js.jar https://lodash.com/_travis/rhino-1.7.6.jar)"
- "[ $BIN != 'rhino' ] || (echo -e '#!/bin/sh\\njava -jar /opt/rhino-1.7.6/js.jar $@' | sudo tee /usr/local/bin/rhino && sudo chmod +x /usr/local/bin/rhino)"
- "[ $BIN != 'ringo' ] || (wget --no-check-certificate https://lodash.com/_travis/ringojs-0.11.zip && sudo unzip ringojs-0.11 -d /opt && rm ringojs-0.11.zip)"
- "[ $BIN != 'ringo' ] || (sudo ln -s /opt/ringojs-0.11/bin/ringo /usr/local/bin/ringo && sudo chmod +x $_)"
- "perl -pi -e 's|\"lodash\"|\"lodash-compat\"|' ./package.json"
- "git clone --depth=10 --branch=master git://github.com/lodash/lodash-cli ./node_modules/lodash-cli && mkdir $_/node_modules && cd $_ && ln -s ../../../ ./lodash-compat && cd ../ && npm i && cd ../../"
- "node ./node_modules/lodash-cli/bin/lodash $BUILD -o ./lodash.$BUILD.js"
script:
- "[ $ISTANBUL == false ] || istanbul cover -x \"**/vendor/**\" --report lcovonly ./test/test.js -- ./lodash.js"
- "[ $ISTANBUL == false ] || cp ./lodash.$BUILD.js ./lodash.js"
- "[ $ISTANBUL == false ] || perl -0pi -e \"$PATTERN\" ./lodash.js"
- "[ $ISTANBUL == false ] || node ./node_modules/istanbul/lib/cli.js cover -x \"**/vendor/**\" --report lcovonly ./test/test.js -- ./lodash.js"
- "[ $ISTANBUL == false ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/lcov.info | coveralls) || true"
- "[ $ISTANBUL == false ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/coverage.json | codecov) || true"
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || cd ./test"
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || $BIN $OPTION ./test.js ../lodash.js"
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || $BIN $OPTION ./test.js ../dist/lodash.min.js"
- "[ $SAUCE_LABS == false ] || rm -rf ./node_modules/lodash"
- "[ $SAUCE_LABS == false ] || ($BIN ./node_modules/lodash-cli/bin/lodash modularize exports=node -o ./node_modules/lodash && node ./node_modules/lodash-cli/bin/lodash -d -o ./node_modules/lodash/index.js)"
- "[ $SAUCE_LABS == false ] || $BIN ./node_modules/lodash-cli/bin/lodash core -o ./dist/lodash.core.js"
- "[ $SAUCE_LABS == false ] || npm run build"
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../dist/lodash.js&noglobals=true\" tags=\"development\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../dist/lodash.min.js&noglobals=true\" tags=\"production\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash-fp tests\" runner=\"test/fp.html?noglobals=true\" tags=\"development\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../dist/lodash.js\" tags=\"development,underscore\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../dist/lodash.min.js\" tags=\"production,underscore\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../dist/lodash.js\" tags=\"development,backbone\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../dist/lodash.min.js\" tags=\"production,backbone\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../dist/lodash.core.js\" tags=\"development,backbone\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../dist/lodash.core.min.js\" tags=\"production,backbone\""
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || $BIN $OPTION ./test.js ../lodash.$BUILD.js"
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || $BIN $OPTION ./test.js ../lodash.$BUILD.min.js"
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.js&noglobals=true\" tags=\"$BUILD,development\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.min.js&noglobals=true\" tags=\"$BUILD,production\""
- "[ $SAUCE_LABS == false ] || [ $BUILD != 'compat' ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.js\" tags=\"$BUILD,development,ie-compat\" compatMode=7"
- "[ $SAUCE_LABS == false ] || [ $BUILD != 'compat' ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.min.js\" tags=\"$BUILD,production,ie-compat\" compatMode=7"
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../lodash.$BUILD.min.js\" tags=\"$BUILD,production,backbone\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../lodash.$BUILD.js\" tags=\"$BUILD,development,backbone\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../lodash.$BUILD.min.js\" tags=\"$BUILD,production,underscore\""
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../lodash.$BUILD.js\" tags=\"$BUILD,development,underscore\""

View File

@@ -1,49 +0,0 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all people who
contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to
fairly and consistently applying these principles to every aspect of managing
this project. Project maintainers who do not follow or enforce the Code of
Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer at
[coc@lodash.com](mailto:coc@lodash.com). All complaints will be reviewed and
investigated and will result in a response that is deemed necessary and
appropriate to the circumstances. Maintainers are obligated to maintain
confidentiality with regard to the reporter of an incident.
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.3.0, available at
[http://contributor-covenant.org/version/1/3/0/][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/3/0/

View File

@@ -1,67 +1,39 @@
# Contributing to Lodash
# Contributing to lodash
Contributions are always welcome. Before contributing please read the
[code of conduct](https://github.com/lodash/lodash/blob/master/CODE_OF_CONDUCT.md)
& [search the issue tracker](https://github.com/lodash/lodash/issues); your issue
may have already been discussed or fixed in `master`. To contribute,
[fork](https://help.github.com/articles/fork-a-repo/) Lodash, commit your changes,
& [send a pull request](https://help.github.com/articles/using-pull-requests/).
If youd like to contribute a feature or bug fix, you can [fork](https://help.github.com/articles/fork-a-repo/) lodash, commit your changes, & [send a pull request](https://help.github.com/articles/using-pull-requests/).
Please make sure to [search the issue tracker](https://github.com/lodash/lodash/issues) first; your issue may have already been discussed or fixed in `master`.
## Feature Requests
## Tests
Feature requests are always welcome. They should be submitted in the
[issue tracker](https://github.com/lodash/lodash/issues), with a description of
the expected behavior & use case, where theyll remain closed until sufficient
interest has been shown by the community. Before submitting a request,
please search for similar ones in the
[closed issues](https://github.com/lodash/lodash/issues?q=is%3Aissue+is%3Aclosed+label%3Aenhancement).
Include updated unit tests in the `test` directory as part of your pull request.
Dont worry about regenerating the documentation, lodash.js, or lodash.min.js.
## Pull Requests
Before running the unit tests youll need to install, `npm i`, [development dependencies](https://docs.npmjs.com/files/package.json#devdependencies).
Run unit tests from the command-line via `node test/test`, or open `test/index.html` in a web browser.
For additions or bug fixes you should only need to modify `lodash.js`. Include
updated unit tests in the `test` directory as part of your pull request. Dont
worry about regenerating the `dist/` or `doc/` files.
Before running the unit tests youll need to install, `npm i`,
[development dependencies](https://docs.npmjs.com/files/package.json#devdependencies).
Run unit tests from the command-line via `npm test`, or open `test/index.html` &
`test/fp.html` in a web browser. The [Backbone](http://backbonejs.org/) &
[Underscore](http://underscorejs.org/) test suites are included as well.
The `test/run-test.sh` script attempts to run the tests in [Rhino](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino), [RingoJS](http://ringojs.org/), [PhantomJS](http://phantomjs.org/), & [Node](http://nodejs.org/), before running them in your default browser.
The [Backbone](http://backbonejs.org/) & [Underscore](http://underscorejs.org/) test suites are included as well.
## Contributor License Agreement
Lodash is a member of the [Dojo Foundation](http://dojofoundation.org/).
As such, we request that all contributors sign the Dojo Foundation
[contributor license agreement (CLA)](http://dojofoundation.org/about/claForm).
lodash is a member of the [Dojo Foundation](http://dojofoundation.org/).
As such, we request that all contributors sign the Dojo Foundation [contributor license agreement](http://dojofoundation.org/about/claForm).
For more information about CLAs, please check out Alex Russells excellent post,
[“Why Do I Need to Sign This?”](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
For more information about CLAs, please check out Alex Russells excellent post, [“Why Do I Need to Sign This?”](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
## Coding Guidelines
In addition to the following guidelines, please follow the conventions already
established in the code.
In addition to the following guidelines, please follow the conventions already established in the code.
- **Spacing**:<br>
Use two spaces for indentation. No tabs.
- **Naming**:<br>
Keep variable & method names concise & descriptive.<br>
Variable names `index`, `collection`, & `callback` are preferable to
`i`, `arr`, & `fn`.
Variable names `index`, `collection`, & `callback` are preferable to `i`, `arr`, & `fn`.
- **Quotes**:<br>
Single-quoted strings are preferred to double-quoted strings; however,
please use a double-quoted string if the value contains a single-quote
character to avoid unnecessary escaping.
Single-quoted strings are preferred to double-quoted strings; however, please use a double-quoted string if the value contains a single-quote character to avoid unnecessary escaping.
- **Comments**:<br>
Please use single-line comments to annotate significant additions, &
[JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for
functions.
Guidelines are enforced using [JSCS](https://www.npmjs.com/package/jscs):
```bash
$ npm run style
```
Please use single-line comments to annotate significant additions, & [JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for new methods.

37
LICENSE
View File

@@ -1,23 +1,22 @@
The MIT License (MIT)
Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas,
Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
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:
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 above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.
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.

View File

@@ -1,55 +1,29 @@
# lodash v4.4.0
# lodash v3.10.0
The [lodash](https://lodash.com/) library exported as a [UMD](https://github.com/umdjs/umd) module.
The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) with packages for [Bower](http://bower.io/), [Component](http://component.github.io/), & [Volo](http://volojs.org/).
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
```bash
$ npm run build
$ lodash -o ./dist/lodash.js
$ lodash core -o ./dist/lodash.core.js
$ lodash modern -o ./lodash.js
```
## Why Lodash?
Lodash makes JavaScript easier by taking the hassle out of working with arrays,<br>
numbers, objects, strings, etc. Lodashs modular methods are great for:
* Iterating arrays, objects, & strings
* Manipulating & testing values
* Creating composite functions
## Community
[![Gitter](https://badges.gitter.im/lodash/lodash.svg)](https://gitter.im/lodash/lodash)
[![Join the chat at https://gitter.im/lodash/lodash](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lodash/lodash)
## Documentation
## Module formats
* [API Documentation](https://lodash.com/docs)
* [DevDocs *a searchable interface for our documentation*](https://devdocs.io/lodash/)
* [FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide)
lodash is also available in a variety of other builds & module formats.
## Download
Lodash is released under the [MIT license](https://raw.githubusercontent.com/lodash/lodash/4.4.0/LICENSE) & supports [modern environments](#support).<br>
Review the [build differences](https://github.com/lodash/lodash/wiki/build-differences) & pick the one thats right for you.
* [Core build](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.core.js) ([~4 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.core.min.js))
* [Full build](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.js) ([~20 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.min.js))
## Module Formats
Lodash is available in a variety of other builds & module formats.
* [lodash](https://www.npmjs.com/package/lodash) & [per method packages](https://www.npmjs.com/browse/keyword/lodash-modularized)
* [lodash-amd](https://www.npmjs.com/package/lodash-amd)
* [lodash-es](https://www.npmjs.com/package/lodash-es) & [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash)
* [lodash/fp](https://github.com/lodash/lodash/tree/4.4.0-npm/fp)
CDN copies are available on [cdnjs](https://cdnjs.com/) & [jsDelivr](http://www.jsdelivr.com/).<br>
Create [custom builds](https://lodash.com/custom-builds) with only the features you need.
* npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds
* AMD modules for [modern](https://github.com/lodash/lodash/tree/3.10.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.10.0-amd) builds
* ES modules for the [modern](https://github.com/lodash/lodash/tree/3.10.0-es) build
## Further Reading
* [Contributing](https://github.com/lodash/lodash/blob/master/CONTRIBUTING.md)
* [Release Notes](https://github.com/lodash/lodash/releases/tag/4.0.0)
* [Wiki (Changelog, Roadmap, etc.)](https://github.com/lodash/lodash/wiki)
* [API Documentation](https://lodash.com/docs)
* [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences)
* [Changelog](https://github.com/lodash/lodash/wiki/Changelog)
* [Release Notes](https://github.com/lodash/lodash/releases)
* [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap)
* [More Resources](https://github.com/lodash/lodash/wiki/Resources)

19
bower.json Normal file
View File

@@ -0,0 +1,19 @@
{
"name": "lodash",
"main": "lodash.js",
"ignore": [
".*",
"*.custom.*",
"*.log",
"*.map",
"*.md",
"lodash.src.js",
"component.json",
"package.json",
"doc",
"node_modules",
"perf",
"test",
"vendor"
]
}

10
component.json Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "lodash",
"repo": "lodash/lodash",
"version": "3.10.0",
"description": "The modern build of lodash.",
"license": "MIT",
"main": "lodash.js",
"keywords": ["stdlib", "util"],
"scripts": ["lodash.js"]
}

3823
dist/lodash.core.js vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
/**
* @license
* lodash 4.4.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
* Build: `lodash core -o ./dist/lodash.core.js`
*/
;(function(){function n(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function t(n,t,r){for(var e=-1,u=n.length;++e<u;){var o=n[e],i=t(o);if(null!=i&&(c===ln?i===i:r(i,c)))var c=i,f=o}return f}function r(n,t,r){var e;return r(n,function(n,r,u){return t(n,r,u)?(e=n,false):void 0}),e}function e(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function u(n,t){return O(t,function(t){return n[t]})}function o(n){return n&&n.Object===Object?n:null}function i(n){return yn[n];
}function c(n){var t=false;if(null!=n&&typeof n.toString!="function")try{t=!!(n+"")}catch(r){}return t}function f(n,t){return n=typeof n=="number"||vn.test(n)?+n:-1,n>-1&&0==n%1&&(null==t?9007199254740991:t)>n}function a(n){if(Z(n)&&!Un(n)){if(n instanceof l)return n;if(An.call(n,"__wrapped__")){var t=new l(n.__wrapped__,n.__chain__);return t.__actions__=N(n.__actions__),t}}return new l(n)}function l(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function p(n,t,r,e){return n===ln||H(n,En[r])&&!An.call(e,r)?t:n;
}function s(n){return Y(n)?Rn(n):{}}function h(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function");return setTimeout(function(){n.apply(ln,r)},t)}function v(n,t){var r=true;return qn(n,function(n,e,u){return r=!!t(n,e,u)}),r}function y(n,t){var r=[];return qn(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function _(t,r,e,u){u||(u=[]);for(var o=-1,i=t.length;++o<i;){var c=t[o];r>0&&Z(c)&&Q(c)&&(e||Un(c)||L(c))?r>1?_(c,r-1,e,u):n(u,c):e||(u[u.length]=c)}return u}function g(n,t){return n&&zn(n,t,un);
}function b(n,t){return y(t,function(t){return W(n[t])})}function j(n,t,r,e,u){return n===t?true:null==n||null==t||!Y(n)&&!Z(t)?n!==n&&t!==t:m(n,t,j,r,e,u)}function m(n,t,r,e,u,o){var i=Un(n),f=Un(t),a="[object Array]",l="[object Array]";i||(a=Nn.call(n),"[object Arguments]"==a&&(a="[object Object]")),f||(l=Nn.call(t),"[object Arguments]"==l&&(l="[object Object]"));var p="[object Object]"==a&&!c(n),f="[object Object]"==l&&!c(t);return!(l=a==l)||i||p?2&u||(a=p&&An.call(n,"__wrapped__"),f=f&&An.call(t,"__wrapped__"),
!a&&!f)?l?(o||(o=[]),(a=J(o,function(t){return t[0]===n}))&&a[1]?a[1]==t:(o.push([n,t]),t=(i?I:q)(n,t,r,e,u,o),o.pop(),t)):false:r(a?n.value():n,f?t.value():t,e,u,o):$(n,t,a)}function d(n){var t=typeof n;return"function"==t?n:null==n?fn:("object"==t?x:A)(n)}function w(n){n=null==n?n:Object(n);var t,r=[];for(t in n)r.push(t);return r}function O(n,t){var r=-1,e=Q(n)?Array(n.length):[];return qn(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function x(n){var t=un(n);return function(r){var e=t.length;if(null==r)return!e;
for(r=Object(r);e--;){var u=t[e];if(!(u in r&&j(n[u],r[u],ln,3)))return false}return true}}function E(n,t){return n=Object(n),P(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function A(n){return function(t){return null==t?ln:t[n]}}function k(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e<u;)r[e]=n[e+t];return r}function N(n){return k(n,0,n.length)}function S(n,t){var r;return qn(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function T(t,r){
return P(r,function(t,r){return r.func.apply(r.thisArg,n([t],r.args))},t)}function F(n,t,r,e){r||(r={});for(var u=-1,o=t.length;++u<o;){var i=t[u],c=e?e(r[i],n[i],i,r,n):n[i],f=r,a=f[i];(!H(a,c)||H(a,En[i])&&!An.call(f,i)||c===ln&&!(i in f))&&(f[i]=c)}return r}function R(n){return V(function(t,r){var e=-1,u=r.length,o=u>1?r[u-1]:ln,o=typeof o=="function"?(u--,o):ln;for(t=Object(t);++e<u;){var i=r[e];i&&n(t,i,e,o)}return t})}function B(n){return function(){var t=arguments,r=s(n.prototype),t=n.apply(r,t);
return Y(t)?t:r}}function D(n,t,r){function e(){for(var o=-1,i=arguments.length,c=-1,f=r.length,a=Array(f+i),l=this&&this!==On&&this instanceof e?u:n;++c<f;)a[c]=r[c];for(;i--;)a[c++]=arguments[++o];return l.apply(t,a)}if(typeof n!="function")throw new TypeError("Expected a function");var u=B(n);return e}function I(n,t,r,e,u,o){var i=-1,c=1&u,f=n.length,a=t.length;if(f!=a&&!(2&u&&a>f))return false;for(a=true;++i<f;){var l=n[i],p=t[i];if(void 0!==ln){a=false;break}if(c){if(!S(t,function(n){return l===n||r(l,n,e,u,o);
})){a=false;break}}else if(l!==p&&!r(l,p,e,u,o)){a=false;break}}return a}function $(n,t,r){switch(r){case"[object Boolean]":case"[object Date]":return+n==+t;case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object Number]":return n!=+n?t!=+t:n==+t;case"[object RegExp]":case"[object String]":return n==t+""}return false}function q(n,t,r,e,u,o){var i=2&u,c=un(n),f=c.length,a=un(t).length;if(f!=a&&!i)return false;for(var l=f;l--;){var p=c[l];if(!(i?p in t:An.call(t,p)))return false}for(a=true;++l<f;){
var p=c[l],s=n[p],h=t[p];if(void 0!==ln||s!==h&&!r(s,h,e,u,o)){a=false;break}i||(i="constructor"==p)}return a&&!i&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(a=false)),a}function z(n){var t=n?n.length:ln;if(X(t)&&(Un(n)||tn(n)||L(n))){n=String;for(var r=-1,e=Array(t);++r<t;)e[r]=n(r);t=e}else t=null;return t}function C(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||En);
}function G(n){return n?n[0]:ln}function J(n,t){return r(n,d(t),qn)}function M(n,t){return qn(n,typeof t=="function"?t:fn)}function P(n,t,r){return e(n,d(t),r,3>arguments.length,qn)}function U(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Vn(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=ln),r}}function V(n){var t;if(typeof n!="function")throw new TypeError("Expected a function");return t=$n(t===ln?n.length-1:Vn(t),0),function(){for(var r=arguments,e=-1,u=$n(r.length-t,0),o=Array(u);++e<u;)o[e]=r[t+e];
for(u=Array(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function H(n,t){return n===t||n!==n&&t!==t}function K(n,t){return n>t}function L(n){return Z(n)&&Q(n)&&An.call(n,"callee")&&(!Bn.call(n,"callee")||"[object Arguments]"==Nn.call(n))}function Q(n){return null!=n&&!(typeof n=="function"&&W(n))&&X(Cn(n))}function W(n){return n=Y(n)?Nn.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function X(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function Y(n){
var t=typeof n;return!!n&&("object"==t||"function"==t)}function Z(n){return!!n&&typeof n=="object"}function nn(n){return typeof n=="number"||Z(n)&&"[object Number]"==Nn.call(n)}function tn(n){return typeof n=="string"||!Un(n)&&Z(n)&&"[object String]"==Nn.call(n)}function rn(n,t){return t>n}function en(n){return typeof n=="string"?n:null==n?"":n+""}function un(n){var t=C(n);if(!t&&!Q(n))return In(Object(n));var r,e=z(n),u=!!e,e=e||[],o=e.length;for(r in n)!An.call(n,r)||u&&("length"==r||f(r,o))||t&&"constructor"==r||e.push(r);
return e}function on(n){for(var t=-1,r=C(n),e=w(n),u=e.length,o=z(n),i=!!o,o=o||[],c=o.length;++t<u;){var a=e[t];i&&("length"==a||f(a,c))||"constructor"==a&&(r||!An.call(n,a))||o.push(a)}return o}function cn(n){return n?u(n,un(n)):[]}function fn(n){return n}function an(t,r,e){var u=un(r),o=b(r,u);null!=e||Y(r)&&(o.length||!u.length)||(e=r,r=t,t=this,o=b(r,un(r)));var i=Y(e)&&"chain"in e?e.chain:true,c=W(t);return qn(o,function(e){var u=r[e];t[e]=u,c&&(t.prototype[e]=function(){var r=this.__chain__;if(i||r){
var e=t(this.__wrapped__);return(e.__actions__=N(this.__actions__)).push({func:u,args:arguments,thisArg:t}),e.__chain__=r,e}return u.apply(t,n([this.value()],arguments))})}),t}var ln,pn=1/0,sn=/[&<>"'`]/g,hn=RegExp(sn.source),vn=/^(?:0|[1-9]\d*)$/,yn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},_n={"function":true,object:true},gn=_n[typeof exports]&&exports&&!exports.nodeType?exports:ln,bn=_n[typeof module]&&module&&!module.nodeType?module:ln,jn=bn&&bn.exports===gn?gn:ln,mn=o(_n[typeof self]&&self),dn=o(_n[typeof window]&&window),wn=o(_n[typeof this]&&this),On=o(gn&&bn&&typeof global=="object"&&global)||dn!==(wn&&wn.window)&&dn||mn||wn||Function("return this")(),xn=Array.prototype,En=Object.prototype,An=En.hasOwnProperty,kn=0,Nn=En.toString,Sn=On._,Tn=On.Reflect,Fn=Tn?Tn.f:ln,Rn=Object.create,Bn=En.propertyIsEnumerable,Dn=On.isFinite,In=Object.keys,$n=Math.max,qn=function(n,t){
return function(r,e){if(null==r)return r;if(!Q(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}(g),zn=function(n){return function(t,r,e){var u=-1,o=Object(t);e=e(t);for(var i=e.length;i--;){var c=e[n?i:++u];if(false===r(o[c],c,o))break}return t}}();Fn&&!Bn.call({valueOf:1},"valueOf")&&(w=function(n){n=Fn(n);for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r});var Cn=A("length"),Gn=V(function(t,r){return Un(t)||(t=null==t?[]:[Object(t)]),_(r,1),
n(N(t),cn)}),Jn=V(function(n,t,r){return D(n,t,r)}),Mn=V(function(n,t){return h(n,1,t)}),Pn=V(function(n,t,r){return h(n,Hn(t)||0,r)}),Un=Array.isArray,Vn=Number,Hn=Number,Kn=R(function(n,t){F(t,un(t),n)}),Ln=R(function(n,t){F(t,on(t),n)}),Qn=R(function(n,t,r,e){F(t,on(t),n,e)}),Wn=V(function(n){return n.push(ln,p),Qn.apply(ln,n)}),Xn=V(function(n,t){return null==n?{}:E(n,_(t,1))}),Yn=d;l.prototype=s(a.prototype),l.prototype.constructor=l,a.assignIn=Ln,a.before=U,a.bind=Jn,a.chain=function(n){return n=a(n),
n.__chain__=true,n},a.compact=function(n){return y(n,Boolean)},a.concat=Gn,a.create=function(n,t){var r=s(n);return t?Kn(r,t):r},a.defaults=Wn,a.defer=Mn,a.delay=Pn,a.filter=function(n,t){return y(n,d(t))},a.flatten=function(n){return n&&n.length?_(n,1):[]},a.flattenDeep=function(n){return n&&n.length?_(n,pn):[]},a.iteratee=Yn,a.keys=un,a.map=function(n,t){return O(n,d(t))},a.matches=function(n){return x(Kn({},n))},a.mixin=an,a.negate=function(n){if(typeof n!="function")throw new TypeError("Expected a function");
return function(){return!n.apply(this,arguments)}},a.once=function(n){return U(2,n)},a.pick=Xn,a.slice=function(n,t,r){var e=n?n.length:0;return r=r===ln?e:+r,e?k(n,null==t?0:+t,r):[]},a.sortBy=function(n,t){var r=0;return t=d(t),O(O(n,function(n,e,u){return{c:n,b:r++,a:t(n,e,u)}}).sort(function(n,t){var r;n:{r=n.a;var e=t.a;if(r!==e){var u=null===r,o=r===ln,i=r===r,c=null===e,f=e===ln,a=e===e;if(r>e&&!c||!i||u&&!f&&a||o&&a){r=1;break n}if(e>r&&!u||!a||c&&!o&&i||f&&i){r=-1;break n}}r=0}return r||n.b-t.b;
}),A("c"))},a.tap=function(n,t){return t(n),n},a.thru=function(n,t){return t(n)},a.toArray=function(n){return Q(n)?n.length?N(n):[]:cn(n)},a.values=cn,a.extend=Ln,an(a,a),a.clone=function(n){return Y(n)?Un(n)?N(n):F(n,un(n)):n},a.escape=function(n){return(n=en(n))&&hn.test(n)?n.replace(sn,i):n},a.every=function(n,t,r){return t=r?ln:t,v(n,d(t))},a.find=J,a.forEach=M,a.has=function(n,t){return null!=n&&An.call(n,t)},a.head=G,a.identity=fn,a.indexOf=function(n,t,r){var e=n?n.length:0;r=typeof r=="number"?0>r?$n(e+r,0):r:0,
r=(r||0)-1;for(var u=t===t;++r<e;){var o=n[r];if(u?o===t:o!==o)return r}return-1},a.isArguments=L,a.isArray=Un,a.isBoolean=function(n){return true===n||false===n||Z(n)&&"[object Boolean]"==Nn.call(n)},a.isDate=function(n){return Z(n)&&"[object Date]"==Nn.call(n)},a.isEmpty=function(n){if(Q(n)&&(Un(n)||tn(n)||W(n.splice)||L(n)))return!n.length;for(var t in n)if(An.call(n,t))return false;return true},a.isEqual=function(n,t){return j(n,t)},a.isFinite=function(n){return typeof n=="number"&&Dn(n)},a.isFunction=W,a.isNaN=function(n){
return nn(n)&&n!=+n},a.isNull=function(n){return null===n},a.isNumber=nn,a.isObject=Y,a.isRegExp=function(n){return Y(n)&&"[object RegExp]"==Nn.call(n)},a.isString=tn,a.isUndefined=function(n){return n===ln},a.last=function(n){var t=n?n.length:0;return t?n[t-1]:ln},a.max=function(n){return n&&n.length?t(n,fn,K):ln},a.min=function(n){return n&&n.length?t(n,fn,rn):ln},a.noConflict=function(){return On._===this&&(On._=Sn),this},a.noop=function(){},a.reduce=P,a.result=function(n,t,r){return t=null==n?ln:n[t],
t===ln&&(t=r),W(t)?t.call(n):t},a.size=function(n){return null==n?0:(n=Q(n)?n:un(n),n.length)},a.some=function(n,t,r){return t=r?ln:t,S(n,d(t))},a.uniqueId=function(n){var t=++kn;return en(n)+t},a.each=M,a.first=G,an(a,function(){var n={};return g(a,function(t,r){An.call(a.prototype,r)||(n[r]=t)}),n}(),{chain:false}),a.VERSION="4.4.0",qn("pop join replace reverse split push shift sort splice unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?String.prototype:xn)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|join|replace|shift)$/.test(n);
a.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),a.prototype.toJSON=a.prototype.valueOf=a.prototype.value=function(){return T(this.__wrapped__,this.__actions__)},(dn||mn||{})._=a,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){return a}):gn&&bn?(jn&&((bn.exports=a)._=a),gn._=a):On._=a}).call(this);

608
dist/lodash.fp.js vendored
View File

@@ -1,608 +0,0 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["fp"] = factory();
else
root["fp"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
var baseConvert = __webpack_require__(1);
/**
* Converts `lodash` to an immutable auto-curried iteratee-first data-last version.
*
* @param {Function} lodash The lodash function.
* @param {Object} [options] The options object. See `baseConvert` for more details.
* @returns {Function} Returns the converted `lodash`.
*/
function browserConvert(lodash, options) {
return baseConvert(lodash, lodash, options);
}
if (typeof _ == 'function') {
_ = browserConvert(_.runInContext());
}
module.exports = browserConvert;
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
var mapping = __webpack_require__(2),
mutateMap = mapping.mutate,
placeholder = {};
/**
* The base implementation of `convert` which accepts a `util` object of methods
* required to perform conversions.
*
* @param {Object} util The util object.
* @param {string} name The name of the function to wrap.
* @param {Function} func The function to wrap.
* @param {Object} [options] The options object.
* @param {boolean} [options.cap=true] Specify capping iteratee arguments.
* @param {boolean} [options.curry=true] Specify currying.
* @param {boolean} [options.fixed=true] Specify fixed arity.
* @param {boolean} [options.immutable=true] Specify immutable operations.
* @param {boolean} [options.rearg=true] Specify rearranging arguments.
* @returns {Function|Object} Returns the converted function or object.
*/
function baseConvert(util, name, func, options) {
var setPlaceholder,
isLib = typeof name == 'function',
isObj = name === Object(name);
if (isObj) {
options = func;
func = name;
name = undefined;
}
if (func == null) {
throw new TypeError;
}
options || (options = {});
var config = {
'cap': 'cap' in options ? options.cap : true,
'curry': 'curry' in options ? options.curry : true,
'fixed': 'fixed' in options ? options.fixed : true,
'immutable': 'immutable' in options ? options.immutable : true,
'rearg': 'rearg' in options ? options.rearg : true
};
var forceRearg = ('rearg' in options) && options.rearg;
var helpers = isLib ? func : {
'ary': util.ary,
'cloneDeep': util.cloneDeep,
'curry': util.curry,
'forEach': util.forEach,
'isArray': util.isArray,
'isFunction': util.isFunction,
'iteratee': util.iteratee,
'keys': util.keys,
'rearg': util.rearg,
'spread': util.spread
};
var ary = helpers.ary,
cloneDeep = helpers.cloneDeep,
curry = helpers.curry,
each = helpers.forEach,
isArray = helpers.isArray,
isFunction = helpers.isFunction,
keys = helpers.keys,
rearg = helpers.rearg,
spread = helpers.spread;
var aryMethodKeys = keys(mapping.aryMethod);
var baseArity = function(func, n) {
return n == 2
? function(a, b) { return func.apply(undefined, arguments); }
: function(a) { return func.apply(undefined, arguments); };
};
var baseAry = function(func, n) {
return n == 2
? function(a, b) { return func(a, b); }
: function(a) { return func(a); };
};
var cloneArray = function(array) {
var length = array ? array.length : 0,
result = Array(length);
while (length--) {
result[length] = array[length];
}
return result;
};
var createCloner = function(func) {
return function(object) {
return func({}, object);
};
};
var immutWrap = function(func, cloner) {
return function() {
var length = arguments.length;
if (!length) {
return result;
}
var args = Array(length);
while (length--) {
args[length] = arguments[length];
}
var result = args[0] = cloner(args[0]);
func.apply(undefined, args);
return result;
};
};
var iterateeAry = function(func, n) {
return overArg(func, function(func) {
return baseAry(func, n);
});
};
var overArg = function(func, iteratee, retArg) {
return function() {
var length = arguments.length;
if (!length) {
return func();
}
var args = Array(length);
while (length--) {
args[length] = arguments[length];
}
var index = config.rearg ? 0 : (length - 1);
args[index] = iteratee(args[index]);
return func.apply(undefined, args);
};
};
var wrappers = {
'castArray': function(castArray) {
return function() {
var value = arguments[0];
return isArray(value)
? castArray(cloneArray(value))
: castArray.apply(undefined, arguments);
};
},
'iteratee': function(iteratee) {
return function() {
var func = arguments[0],
arity = arguments[1];
if (!config.cap) {
return iteratee(func, arity);
}
arity = arity > 2 ? (arity - 2) : 1;
func = iteratee(func);
var length = func.length;
return (length && length <= arity) ? func : baseAry(func, arity);
};
},
'mixin': function(mixin) {
return function(source) {
var func = this;
if (!isFunction(func)) {
return mixin(func, Object(source));
}
var methods = [],
methodNames = [];
each(keys(source), function(key) {
var value = source[key];
if (isFunction(value)) {
methodNames.push(key);
methods.push(func.prototype[key]);
}
});
mixin(func, Object(source));
each(methodNames, function(methodName, index) {
var method = methods[index];
if (isFunction(method)) {
func.prototype[methodName] = method;
} else {
delete func.prototype[methodName];
}
});
return func;
};
},
'runInContext': function(runInContext) {
return function(context) {
return baseConvert(util, runInContext(context), options);
};
}
};
var wrap = function(name, func) {
name = mapping.aliasToReal[name] || name;
var wrapper = wrappers[name];
if (wrapper) {
return wrapper(func);
}
var wrapped = func;
if (config.immutable) {
if (mutateMap.array[name]) {
wrapped = immutWrap(func, cloneArray);
}
else if (mutateMap.object[name]) {
wrapped = immutWrap(func, createCloner(func));
}
else if (mutateMap.set[name]) {
wrapped = immutWrap(func, cloneDeep);
}
}
var result;
each(aryMethodKeys, function(aryKey) {
each(mapping.aryMethod[aryKey], function(otherName) {
if (name == otherName) {
var aryN = !isLib && mapping.iterateeAry[name],
spreadStart = mapping.methodSpread[name];
result = wrapped;
if (config.fixed) {
result = spreadStart === undefined
? ary(result, aryKey)
: spread(result, spreadStart);
}
if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
}
if (config.cap && aryN) {
result = iterateeAry(result, aryN);
}
if (config.curry && aryKey > 1) {
result = curry(result, aryKey);
}
return false;
}
});
return !result;
});
result || (result = wrapped);
if (mapping.placeholder[name]) {
setPlaceholder = true;
func.placeholder = result.placeholder = placeholder;
}
return result;
};
if (!isObj) {
return wrap(name, func);
}
var _ = func;
// Iterate over methods for the current ary cap.
var pairs = [];
each(aryMethodKeys, function(aryKey) {
each(mapping.aryMethod[aryKey], function(key) {
var func = _[mapping.remap[key] || key];
if (func) {
pairs.push([key, wrap(key, func)]);
}
});
});
// Assign to `_` leaving `_.prototype` unchanged to allow chaining.
each(pairs, function(pair) {
_[pair[0]] = pair[1];
});
if (setPlaceholder) {
_.placeholder = placeholder;
}
// Wrap the lodash method and its aliases.
each(keys(_), function(key) {
each(mapping.realToAlias[key] || [], function(alias) {
_[alias] = _[key];
});
});
return _;
}
module.exports = baseConvert;
/***/ },
/* 2 */
/***/ function(module, exports) {
/** Used to map aliases to their real names. */
exports.aliasToReal = {
'__': 'placeholder',
'all': 'some',
'allPass': 'overEvery',
'apply': 'spread',
'assoc': 'set',
'assocPath': 'set',
'compose': 'flowRight',
'contains': 'includes',
'dissoc': 'unset',
'dissocPath': 'unset',
'each': 'forEach',
'eachRight': 'forEachRight',
'equals': 'isEqual',
'extend': 'assignIn',
'extendWith': 'assignInWith',
'first': 'head',
'init': 'initial',
'mapObj': 'mapValues',
'omitAll': 'omit',
'nAry': 'ary',
'path': 'get',
'pathEq': 'matchesProperty',
'pathOr': 'getOr',
'pickAll': 'pick',
'pipe': 'flow',
'prop': 'get',
'propOf': 'propertyOf',
'propOr': 'getOr',
'somePass': 'overSome',
'unapply': 'rest',
'unnest': 'flatten',
'useWith': 'overArgs',
'whereEq': 'filter',
'zipObj': 'zipObject'
};
/** Used to map ary to method names. */
exports.aryMethod = {
'1': [
'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor',
'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin',
'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext',
'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words'
],
'2': [
'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey',
'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every',
'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',
'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn',
'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has',
'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap',
'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map',
'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit',
'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile',
'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd',
'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset',
'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep'
],
'3': [
'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith',
'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace',
'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy',
'unionWith', 'xorBy', 'xorWith', 'zipWith'
],
'4': [
'fill', 'setWith'
]
};
/** Used to map ary to rearg configs. */
exports.aryRearg = {
'2': [1, 0],
'3': [2, 0, 1],
'4': [3, 2, 0, 1]
};
/** Used to map method names to their iteratee ary. */
exports.iterateeAry = {
'assignWith': 2,
'assignInWith': 2,
'cloneDeepWith': 1,
'cloneWith': 1,
'dropRightWhile': 1,
'dropWhile': 1,
'every': 1,
'filter': 1,
'find': 1,
'findIndex': 1,
'findKey': 1,
'findLast': 1,
'findLastIndex': 1,
'findLastKey': 1,
'flatMap': 1,
'forEach': 1,
'forEachRight': 1,
'forIn': 1,
'forInRight': 1,
'forOwn': 1,
'forOwnRight': 1,
'isEqualWith': 2,
'isMatchWith': 2,
'map': 1,
'mapKeys': 1,
'mapValues': 1,
'partition': 1,
'reduce': 2,
'reduceRight': 2,
'reject': 1,
'remove': 1,
'some': 1,
'takeRightWhile': 1,
'takeWhile': 1,
'times': 1,
'transform': 2
};
/** Used to map method names to rearg configs. */
exports.methodRearg = {
'assignInWith': [1, 2, 0],
'assignWith': [1, 2, 0],
'getOr': [2, 1, 0],
'isMatchWith': [2, 1, 0],
'mergeWith': [1, 2, 0],
'pullAllBy': [2, 1, 0],
'setWith': [3, 1, 2, 0],
'sortedIndexBy': [2, 1, 0],
'sortedLastIndexBy': [2, 1, 0],
'zipWith': [1, 2, 0]
};
/** Used to map method names to spread configs. */
exports.methodSpread = {
'partial': 1,
'partialRight': 1
};
/** Used to identify methods which mutate arrays or objects. */
exports.mutate = {
'array': {
'fill': true,
'pull': true,
'pullAll': true,
'pullAllBy': true,
'pullAt': true,
'remove': true,
'reverse': true
},
'object': {
'assign': true,
'assignIn': true,
'assignInWith': true,
'assignWith': true,
'defaults': true,
'defaultsDeep': true,
'merge': true,
'mergeWith': true
},
'set': {
'set': true,
'setWith': true,
'unset': true
}
};
/** Used to track methods with placeholder support */
exports.placeholder = {
'bind': true,
'bindKey': true,
'curry': true,
'curryRight': true,
'partial': true,
'partialRight': true
};
/** Used to map real names to their aliases. */
exports.realToAlias = (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
object = exports.aliasToReal,
result = {};
for (var key in object) {
var value = object[key];
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {
result[value] = [key];
}
}
return result;
}());
/** Used to map method names to other names. */
exports.remap = {
'curryN': 'curry',
'curryRightN': 'curryRight',
'getOr': 'get',
'trimChars': 'trim',
'trimCharsEnd': 'trimEnd',
'trimCharsStart': 'trimStart'
};
/** Used to track methods that skip `_.rearg`. */
exports.skipRearg = {
'add': true,
'assign': true,
'assignIn': true,
'concat': true,
'difference': true,
'gt': true,
'gte': true,
'lt': true,
'lte': true,
'matchesProperty': true,
'merge': true,
'partial': true,
'partialRight': true,
'random': true,
'range': true,
'rangeRight': true,
'subtract': true,
'zip': true,
'zipObject': true
};
/***/ }
/******/ ])
});
;

12
dist/lodash.fp.min.js vendored
View File

@@ -1,12 +0,0 @@
!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.fp=r():e.fp=r()}(this,function(){return function(e){function r(i){if(t[i])return t[i].exports;var n=t[i]={exports:{},id:i,loaded:!1};return e[i].call(n.exports,n,n.exports,r),n.loaded=!0,n.exports}var t={};return r.m=e,r.c=t,r.p="",r(0)}([function(e,r,t){function i(e,r){return n(e,e,r)}var n=t(1);"function"==typeof _&&(_=i(_.runInContext())),
e.exports=i},function(e,r,t){function i(e,r,t,s){var u,c="function"==typeof r,p=r===Object(r);if(p&&(s=t,t=r,r=void 0),null==t)throw new TypeError;s||(s={});var l={cap:"cap"in s?s.cap:!0,curry:"curry"in s?s.curry:!0,fixed:"fixed"in s?s.fixed:!0,immutable:"immutable"in s?s.immutable:!0,rearg:"rearg"in s?s.rearg:!0},f="rearg"in s&&s.rearg,h=c?t:{ary:e.ary,cloneDeep:e.cloneDeep,curry:e.curry,forEach:e.forEach,isArray:e.isArray,isFunction:e.isFunction,iteratee:e.iteratee,keys:e.keys,rearg:e.rearg,spread:e.spread
},d=h.ary,y=h.cloneDeep,g=h.curry,m=h.forEach,v=h.isArray,W=h.isFunction,x=h.keys,R=h.rearg,I=h.spread,O=x(n.aryMethod),b=function(e,r){return 2==r?function(r,t){return e(r,t)}:function(r){return e(r)}},A=function(e){for(var r=e?e.length:0,t=Array(r);r--;)t[r]=e[r];return t},B=function(e){return function(r){return e({},r)}},E=function(e,r){return function(){var t=arguments.length;if(!t)return n;for(var i=Array(t);t--;)i[t]=arguments[t];var n=i[0]=r(i[0]);return e.apply(void 0,i),n}},k=function(e,r){
return j(e,function(e){return b(e,r)})},j=function(e,r,t){return function(){var t=arguments.length;if(!t)return e();for(var i=Array(t);t--;)i[t]=arguments[t];var n=l.rearg?0:t-1;return i[n]=r(i[n]),e.apply(void 0,i)}},w={castArray:function(e){return function(){var r=arguments[0];return v(r)?e(A(r)):e.apply(void 0,arguments)}},iteratee:function(e){return function(){var r=arguments[0],t=arguments[1];if(!l.cap)return e(r,t);t=t>2?t-2:1,r=e(r);var i=r.length;return i&&t>=i?r:b(r,t)}},mixin:function(e){
return function(r){var t=this;if(!W(t))return e(t,Object(r));var i=[],n=[];return m(x(r),function(e){var a=r[e];W(a)&&(n.push(e),i.push(t.prototype[e]))}),e(t,Object(r)),m(n,function(e,r){var n=i[r];W(n)?t.prototype[e]=n:delete t.prototype[e]}),t}},runInContext:function(r){return function(t){return i(e,r(t),s)}}},q=function(e,r){e=n.aliasToReal[e]||e;var t=w[e];if(t)return t(r);var i=r;l.immutable&&(a.array[e]?i=E(r,A):a.object[e]?i=E(r,B(r)):a.set[e]&&(i=E(r,y)));var s;return m(O,function(r){return m(n.aryMethod[r],function(t){
if(e==t){var a=!c&&n.iterateeAry[e],o=n.methodSpread[e];return s=i,l.fixed&&(s=void 0===o?d(s,r):I(s,o)),l.rearg&&r>1&&(f||!n.skipRearg[e])&&(s=R(s,n.methodRearg[e]||n.aryRearg[r])),l.cap&&a&&(s=k(s,a)),l.curry&&r>1&&(s=g(s,r)),!1}}),!s}),s||(s=i),n.placeholder[e]&&(u=!0,r.placeholder=s.placeholder=o),s};if(!p)return q(r,t);var z=t,M=[];return m(O,function(e){m(n.aryMethod[e],function(e){var r=z[n.remap[e]||e];r&&M.push([e,q(e,r)])})}),m(M,function(e){z[e[0]]=e[1]}),u&&(z.placeholder=o),m(x(z),function(e){
m(n.realToAlias[e]||[],function(r){z[r]=z[e]})}),z}var n=t(2),a=n.mutate,o={};e.exports=i},function(e,r){r.aliasToReal={__:"placeholder",all:"some",allPass:"overEvery",apply:"spread",assoc:"set",assocPath:"set",compose:"flowRight",contains:"includes",dissoc:"unset",dissocPath:"unset",each:"forEach",eachRight:"forEachRight",equals:"isEqual",extend:"assignIn",extendWith:"assignInWith",first:"head",init:"initial",mapObj:"mapValues",omitAll:"omit",nAry:"ary",path:"get",pathEq:"matchesProperty",pathOr:"getOr",
pickAll:"pick",pipe:"flow",prop:"get",propOf:"propertyOf",propOr:"getOr",somePass:"overSome",unapply:"rest",unnest:"flatten",useWith:"overArgs",whereEq:"filter",zipObj:"zipObject"},r.aryMethod={1:["attempt","castArray","ceil","create","curry","curryRight","floor","fromPairs","invert","iteratee","memoize","method","methodOf","mixin","over","overEvery","overSome","rest","reverse","round","runInContext","spread","template","trim","trimEnd","trimStart","uniqueId","words"],2:["add","after","ary","assign","assignIn","at","before","bind","bindKey","chunk","cloneDeepWith","cloneWith","concat","countBy","curryN","curryRightN","debounce","defaults","defaultsDeep","delay","difference","drop","dropRight","dropRightWhile","dropWhile","endsWith","eq","every","filter","find","find","findIndex","findKey","findLast","findLastIndex","findLastKey","flatMap","flattenDepth","forEach","forEachRight","forIn","forInRight","forOwn","forOwnRight","get","groupBy","gt","gte","has","hasIn","includes","indexOf","intersection","invertBy","invoke","invokeMap","isEqual","isMatch","join","keyBy","lastIndexOf","lt","lte","map","mapKeys","mapValues","matchesProperty","maxBy","merge","minBy","omit","omitBy","orderBy","overArgs","pad","padEnd","padStart","parseInt","partial","partialRight","partition","pick","pickBy","pull","pullAll","pullAt","random","range","rangeRight","rearg","reject","remove","repeat","result","sampleSize","some","sortBy","sortedIndex","sortedIndexOf","sortedLastIndex","sortedLastIndexOf","sortedUniqBy","split","startsWith","subtract","sumBy","take","takeRight","takeRightWhile","takeWhile","tap","throttle","thru","times","trimChars","trimCharsEnd","trimCharsStart","truncate","union","uniqBy","uniqWith","unset","unzipWith","without","wrap","xor","zip","zipObject","zipObjectDeep"],
3:["assignInWith","assignWith","clamp","differenceBy","differenceWith","getOr","inRange","intersectionBy","intersectionWith","isEqualWith","isMatchWith","mergeWith","pullAllBy","reduce","reduceRight","replace","set","slice","sortedIndexBy","sortedLastIndexBy","transform","unionBy","unionWith","xorBy","xorWith","zipWith"],4:["fill","setWith"]},r.aryRearg={2:[1,0],3:[2,0,1],4:[3,2,0,1]},r.iterateeAry={assignWith:2,assignInWith:2,cloneDeepWith:1,cloneWith:1,dropRightWhile:1,dropWhile:1,every:1,filter:1,
find:1,findIndex:1,findKey:1,findLast:1,findLastIndex:1,findLastKey:1,flatMap:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,isEqualWith:2,isMatchWith:2,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},r.methodRearg={assignInWith:[1,2,0],assignWith:[1,2,0],getOr:[2,1,0],isMatchWith:[2,1,0],mergeWith:[1,2,0],pullAllBy:[2,1,0],setWith:[3,1,2,0],sortedIndexBy:[2,1,0],sortedLastIndexBy:[2,1,0],
zipWith:[1,2,0]},r.methodSpread={partial:1,partialRight:1},r.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignIn:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsDeep:!0,merge:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0}},r.placeholder={bind:!0,bindKey:!0,curry:!0,curryRight:!0,partial:!0,partialRight:!0},r.realToAlias=function(){var e=Object.prototype.hasOwnProperty,t=r.aliasToReal,i={};for(var n in t){var a=t[n];e.call(i,a)?i[a].push(n):i[a]=[n];
}return i}(),r.remap={curryN:"curry",curryRightN:"curryRight",getOr:"get",trimChars:"trim",trimCharsEnd:"trimEnd",trimCharsStart:"trimStart"},r.skipRearg={add:!0,assign:!0,assignIn:!0,concat:!0,difference:!0,gt:!0,gte:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,partial:!0,partialRight:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,zip:!0,zipObject:!0}}])});

120
dist/lodash.min.js vendored
View File

@@ -1,120 +0,0 @@
/**
* @license
* lodash 4.4.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
* Build: `lodash -o ./dist/lodash.js`
*/
;(function(){function n(n,t){return n.set(t[0],t[1]),n}function t(n,t){return n.add(t),n}function r(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function e(n,t,r,e){for(var u=-1,o=n.length;++u<o;){var i=n[u];t(e,i,r(i),n)}return e}function u(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););return n}function o(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;
return true}function i(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function f(n,t){return!!n.length&&-1<d(n,t,0)}function c(n,t,r){for(var e=-1,u=n.length;++e<u;)if(r(t,n[e]))return true;return false}function a(n,t){for(var r=-1,e=n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function l(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function s(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function h(n,t,r,e){
var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function p(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;return false}function _(n,t,r){for(var e=-1,u=n.length;++e<u;){var o=n[e],i=t(o);if(null!=i&&(f===Z?i===i:r(i,f)))var f=i,c=o}return c}function g(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function v(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function d(n,t,r){if(t!==t)return B(n,r);--r;for(var e=n.length;++r<e;)if(n[r]===t)return r;
return-1}function y(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function b(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function x(n,t){for(var r,e=-1,u=n.length;++e<u;){var o=t(n[e]);o!==Z&&(r=r===Z?o:r+o)}return r}function j(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function m(n,t){return a(t,function(t){return[t,n[t]]})}function w(n){return function(t){return n(t)}}function A(n,t){return a(t,function(t){return n[t]})}function O(n,t){for(var r=-1,e=n.length;++r<e&&-1<d(t,n[r],0););
return r}function k(n,t){for(var r=n.length;r--&&-1<d(t,n[r],0););return r}function E(n){return n&&n.Object===Object?n:null}function I(n,t){if(n!==t){var r=null===n,e=n===Z,u=n===n,o=null===t,i=t===Z,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)return 1;if(t>n&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function S(n){return Un[n]}function R(n){return zn[n]}function W(n){return"\\"+$n[n]}function B(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function C(n){var t=false;
if(null!=n&&typeof n.toString!="function")try{t=!!(n+"")}catch(r){}return t}function U(n,t){return n=typeof n=="number"||yn.test(n)?+n:-1,n>-1&&0==n%1&&(null==t?9007199254740991:t)>n}function z(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}function M(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function L(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]="__lodash_placeholder__",o[++u]=r);return o}function $(n){var t=-1,r=Array(n.size);return n.forEach(function(n){
r[++t]=n}),r}function F(n){if(!n||!En.test(n))return n.length;for(var t=kn.lastIndex=0;kn.test(n);)t++;return t}function N(n){return Mn[n]}function D(E){function yn(n){if(me(n)&&!Do(n)&&!(n instanceof An)){if(n instanceof wn)return n;if(au.call(n,"__wrapped__"))return qr(n)}return new wn(n)}function mn(){}function wn(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=Z}function An(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,
this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Un(){}function zn(n){var t=-1,r=n?n.length:0;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Mn(n){var t=-1,r=n?n.length:0;for(this.__data__=new zn;++t<r;)this.push(n[t])}function Ln(n,t){var r=n.__data__;return Lr(t)?(r=r.__data__,"__lodash_hash_undefined__"===(typeof t=="string"?r.string:r.hash)[t]):r.has(t)}function $n(n){var t=-1,r=n?n.length:0;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1]);
}}function Dn(n,t){var r=Pn(n,t);return 0>r?false:(r==n.length-1?n.pop():Eu.call(n,r,1),true)}function Zn(n,t){var r=Pn(n,t);return 0>r?Z:n[r][1]}function Pn(n,t){for(var r=n.length;r--;)if(he(n[r][0],t))return r;return-1}function Tn(n,t,r){var e=Pn(n,t);0>e?n.push([t,r]):n[e][1]=r}function Kn(n,t,r,e){return n===Z||he(n,fu[r])&&!au.call(e,r)?t:n}function Jn(n,t,r){(r!==Z&&!he(n[t],r)||typeof t=="number"&&r===Z&&!(t in n))&&(n[t]=r)}function Yn(n,t,r){var e=n[t];(!he(e,r)||he(e,fu[t])&&!au.call(n,t)||r===Z&&!(t in n))&&(n[t]=r);
}function Hn(n,t,r,e){return Yu(n,function(n,u,o){t(e,n,r(n),o)}),e}function Qn(n,t){return n&&nr(t,Ne(t),n)}function Xn(n,t){for(var r=-1,e=null==n,u=t.length,o=Array(u);++r<u;)o[r]=e?Z:Le(n,t[r]);return o}function nt(n){return ve(n)?n:[]}function tt(n){return typeof n=="function"?n:Je}function rt(n){return Do(n)?n:Zr(n)}function et(n,t,r){return n===n&&(r!==Z&&(n=n>r?r:n),t!==Z&&(n=t>n?t:n)),n}function ut(n,t,r,e,o,i){var f;if(r&&(f=o?r(n,e,o,i):r(n)),f!==Z)return f;if(!je(n))return n;if(e=Do(n)){
if(f=Wr(n),!t)return Xt(n,f)}else{var c=Sr(n),a="[object Function]"==c||"[object GeneratorFunction]"==c;if(Zo(n))return Jt(n,t);if("[object Object]"!=c&&"[object Arguments]"!=c&&(!a||o))return Cn[c]?Cr(n,c,t):o?n:{};if(C(n))return o?n:{};if(f=Br(a?{}:n),!t)return rr(n,Qn(f,n))}return i||(i=new $n),(o=i.get(n))?o:(i.set(n,f),(e?u:pt)(n,function(e,u){Yn(f,u,ut(e,t,r,u,n,i))}),e?f:rr(n,f))}function ot(n){var t=Ne(n),r=t.length;return function(e){if(null==e)return!r;for(var u=r;u--;){var o=t[u],i=n[o],f=e[o];
if(f===Z&&!(o in Object(e))||!i(f))return false}return true}}function it(n){return je(n)?Au(n):{}}function ft(n,t,r){if(typeof n!="function")throw new ou("Expected a function");return ku(function(){n.apply(Z,r)},t)}function ct(n,t,r,e){var u=-1,o=f,i=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=a(t,w(r))),e?(o=c,i=false):t.length>=200&&(o=Ln,i=false,t=new Mn(t));n:for(;++u<l;){var p=n[u],_=r?r(p):p;if(i&&_===_){for(var g=h;g--;)if(t[g]===_)continue n;s.push(p)}else o(t,_,e)||s.push(p)}return s}function at(n,t){
var r=true;return Yu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function lt(n,t){var r=[];return Yu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function st(n,t,r,e){e||(e=[]);for(var u=-1,o=n.length;++u<o;){var i=n[u];t>0&&ve(i)&&(r||Do(i)||_e(i))?t>1?st(i,t-1,r,e):l(e,i):r||(e[e.length]=i)}return e}function ht(n,t){null==n||Qu(n,t,De)}function pt(n,t){return n&&Qu(n,t,Ne)}function _t(n,t){return n&&Xu(n,t,Ne)}function gt(n,t){return i(t,function(t){return ye(n[t])})}function vt(n,t){t=Mr(t,n)?[t+""]:rt(t);
for(var r=0,e=t.length;null!=n&&e>r;)n=n[t[r++]];return r&&r==e?n:Z}function dt(n,t){return au.call(n,t)||typeof n=="object"&&t in n&&null===ju(n)}function yt(n,t){return t in Object(n)}function bt(n,t,r){for(var e=r?c:f,u=n.length,o=u,i=Array(u),l=[];o--;){var s=n[o];o&&t&&(s=a(s,w(t))),i[o]=r||!t&&120>s.length?Z:new Mn(o&&s)}var s=n[0],h=-1,p=s.length,_=i[0];n:for(;++h<p;){var g=s[h],v=t?t(g):g;if(_?!Ln(_,v):!e(l,v,r)){for(o=u;--o;){var d=i[o];if(d?!Ln(d,v):!e(n[o],v,r))continue n}_&&_.push(v),
l.push(g)}}return l}function xt(n,t,r){var e={};return pt(n,function(n,u,o){t(e,r(n),u,o)}),e}function jt(n,t,e){return Mr(t,n)||(t=rt(t),n=Dr(n,t),t=Gr(t)),t=null==n?n:n[t],null==t?Z:r(t,n,e)}function mt(n,t,r,e,u){if(n===t)n=true;else if(null==n||null==t||!je(n)&&!me(t))n=n!==n&&t!==t;else n:{var o=Do(n),i=Do(t),f="[object Array]",c="[object Array]";o||(f=Sr(n),"[object Arguments]"==f?f="[object Object]":"[object Object]"!=f&&(o=Se(n))),i||(c=Sr(t),"[object Arguments]"==c?c="[object Object]":"[object Object]"!=c&&Se(t));
var a="[object Object]"==f&&!C(n),i="[object Object]"==c&&!C(t),c=f==c;if(!c||o||a){if(!(2&e)&&(f=a&&au.call(n,"__wrapped__"),i=i&&au.call(t,"__wrapped__"),f||i)){n=mt(f?n.value():n,i?t.value():t,r,e,u);break n}c?(u||(u=new $n),n=(o?mr:Ar)(n,t,mt,r,e,u)):n=false}else n=wr(n,t,f,mt,r,e)}return n}function wt(n,t,r,e){var u=r.length,o=u,i=!e;if(null==n)return!o;for(n=Object(n);u--;){var f=r[u];if(i&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<o;){var f=r[u],c=f[0],a=n[c],l=f[1];if(i&&f[2]){if(a===Z&&!(c in n))return false;
}else if(f=new $n,c=e?e(a,l,c,n,t,f):Z,c===Z?!mt(l,a,e,3,f):!c)return false}return true}function At(n){var t=typeof n;return"function"==t?n:null==n?Je:"object"==t?Do(n)?It(n[0],n[1]):Et(n):Xe(n)}function Ot(n){n=null==n?n:Object(n);var t,r=[];for(t in n)r.push(t);return r}function kt(n,t){var r=-1,e=ge(n)?Array(n.length):[];return Yu(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function Et(n){var t=Er(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null==n?false:n[r]===e&&(e!==Z||r in Object(n));
}}return function(r){return r===n||wt(r,n,t)}}function It(n,t){return function(r){var e=Le(r,n);return e===Z&&e===t?Fe(r,n):mt(t,e,Z,3)}}function St(n,t,r,e,o){if(n!==t){var i=Do(t)||Se(t)?Z:De(t);u(i||t,function(u,f){if(i&&(f=u,u=t[f]),je(u)){o||(o=new $n);var c=f,a=o,l=n[c],s=t[c],h=a.get(s);if(h)Jn(n,c,h);else{var h=e?e(l,s,c+"",n,t,a):Z,p=h===Z;p&&(h=s,Do(s)||Se(s)?Do(l)?h=l:ve(l)?h=Xt(l):(p=false,h=ut(s,true)):Oe(s)||_e(s)?_e(l)?h=ze(l):!je(l)||r&&ye(l)?(p=false,h=ut(s,true)):h=l:p=false),a.set(s,h),p&&St(h,s,r,e,a),
Jn(n,c,h)}}else c=e?e(n[f],u,f+"",n,t,o):Z,c===Z&&(c=u),Jn(n,f,c)})}}function Rt(n,t,r){var e=-1,u=kr();return t=a(t.length?t:Array(1),function(n){return u(n)}),n=kt(n,function(n){return{a:a(t,function(t){return t(n)}),b:++e,c:n}}),b(n,function(n,t){var e;n:{e=-1;for(var u=n.a,o=t.a,i=u.length,f=r.length;++e<i;){var c=I(u[e],o[e]);if(c){e=f>e?c*("desc"==r[e]?-1:1):c;break n}}e=n.b-t.b}return e})}function Wt(n,t){return n=Object(n),s(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function Bt(n,t){
var r={};return ht(n,function(n,e){t(n,e)&&(r[e]=n)}),r}function Ct(n){return function(t){return null==t?Z:t[n]}}function Ut(n){return function(t){return vt(t,n)}}function zt(n,t,r){var e=-1,u=t.length,o=n;for(r&&(o=a(n,function(n){return r(n)}));++e<u;)for(var i=0,f=t[e],f=r?r(f):f;-1<(i=d(o,f,i));)o!==n&&Eu.call(o,i,1),Eu.call(n,i,1);return n}function Mt(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(e==r||u!=o){var o=u;if(U(u))Eu.call(n,u,1);else if(Mr(u,n))delete n[u];else{var u=rt(u),i=Dr(n,u);
null!=i&&delete i[Gr(u)]}}}}function Lt(n,t){return n+Su(Mu()*(t-n+1))}function $t(n,t,r,e){t=Mr(t,n)?[t+""]:rt(t);for(var u=-1,o=t.length,i=o-1,f=n;null!=f&&++u<o;){var c=t[u];if(je(f)){var a=r;if(u!=i){var l=f[c],a=e?e(l,c,f):Z;a===Z&&(a=null==l?U(t[u+1])?[]:{}:l)}Yn(f,c,a)}f=f[c]}return n}function Ft(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e<u;)r[e]=n[e+t];return r}function Nt(n,t){var r;return Yu(n,function(n,e,u){return r=t(n,e,u),
!r}),!!r}function Dt(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&2147483647>=u){for(;u>e;){var o=e+u>>>1,i=n[o];(r?t>=i:t>i)&&null!==i?e=o+1:u=o}return u}return Zt(n,t,Je,r)}function Zt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,c=t===Z;o>u;){var a=Su((u+o)/2),l=r(n[a]),s=l!==Z,h=l===l;(i?h||e:f?h&&s&&(e||null!=l):c?h&&(e||s):null==l?0:e?t>=l:t>l)?u=a+1:o=a}return Uu(o,4294967294)}function qt(n,t){for(var r=0,e=n.length,u=n[0],o=t?t(u):u,i=o,f=0,c=[u];++r<e;)u=n[r],
o=t?t(u):u,he(o,i)||(i=o,c[++f]=u);return c}function Pt(n,t,r){var e=-1,u=f,o=n.length,i=true,a=[],l=a;if(r)i=false,u=c;else if(o<200)l=t?[]:a;else{if(u=t?null:to(n))return $(u);i=false,u=Ln,l=new Mn}n:for(;++e<o;){var s=n[e],h=t?t(s):s;if(i&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function Tt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););return r?Ft(n,e?0:o,e?o+1:u):Ft(n,e?o+1:0,e?u:o)}function Kt(n,t){
var r=n;return r instanceof An&&(r=r.value()),s(t,function(n,t){return t.func.apply(t.thisArg,l([n],t.args))},r)}function Gt(n,t,r){for(var e=-1,u=n.length;++e<u;)var o=o?l(ct(o,n[e],t,r),ct(n[e],o,t,r)):n[e];return o&&o.length?Pt(o,t,r):[]}function Vt(n,t,r){for(var e=-1,u=n.length,o=t.length,i={};++e<u;)r(i,n[e],o>e?t[e]:Z);return i}function Jt(n,t){if(t)return n.slice();var r=new n.constructor(n.length);return n.copy(r),r}function Yt(n){var t=new n.constructor(n.byteLength);return new yu(t).set(new yu(n)),
t}function Ht(n,t,r){for(var e=r.length,u=-1,o=Cu(n.length-e,0),i=-1,f=t.length,c=Array(f+o);++i<f;)c[i]=t[i];for(;++u<e;)c[r[u]]=n[u];for(;o--;)c[i++]=n[u++];return c}function Qt(n,t,r){for(var e=-1,u=r.length,o=-1,i=Cu(n.length-u,0),f=-1,c=t.length,a=Array(i+c);++o<i;)a[o]=n[o];for(i=o;++f<c;)a[i+f]=t[f];for(;++e<u;)a[i+r[e]]=n[o++];return a}function Xt(n,t){var r=-1,e=n.length;for(t||(t=Array(e));++r<e;)t[r]=n[r];return t}function nr(n,t,r){return tr(n,t,r)}function tr(n,t,r,e){r||(r={});for(var u=-1,o=t.length;++u<o;){
var i=t[u],f=e?e(r[i],n[i],i,r,n):n[i];Yn(r,i,f)}return r}function rr(n,t){return nr(n,uo(n),t)}function er(n,t){return function(r,u){var o=Do(r)?e:Hn,i=t?t():{};return o(r,n,kr(u),i)}}function ur(n){return se(function(t,r){var e=-1,u=r.length,o=u>1?r[u-1]:Z,i=u>2?r[2]:Z,o=typeof o=="function"?(u--,o):Z;for(i&&zr(r[0],r[1],i)&&(o=3>u?Z:o,u=1),t=Object(t);++e<u;)(i=r[e])&&n(t,i,e,o);return t})}function or(n,t){return function(r,e){if(null==r)return r;if(!ge(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++o<u)&&false!==e(i[o],o,i););
return r}}function ir(n){return function(t,r,e){var u=-1,o=Object(t);e=e(t);for(var i=e.length;i--;){var f=e[n?i:++u];if(false===r(o[f],f,o))break}return t}}function fr(n,t,r){function e(){return(this&&this!==Gn&&this instanceof e?o:n).apply(u?r:this,arguments)}var u=1&t,o=lr(n);return e}function cr(n){return function(t){t=Me(t);var r=En.test(t)?t.match(kn):Z,e=r?r[0]:t.charAt(0);return t=r?r.slice(1).join(""):t.slice(1),e[n]()+t}}function ar(n){return function(t){return s(Ge(Te(t)),n,"")}}function lr(n){
return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=it(n.prototype),t=n.apply(r,t);return je(t)?t:r}}function sr(n,t,e){function u(){for(var i=arguments.length,f=i,c=Array(i),a=this&&this!==Gn&&this instanceof u?o:n,l=yn.placeholder||u.placeholder;f--;)c[f]=arguments[f];
return f=3>i&&c[0]!==l&&c[i-1]!==l?[]:L(c,l),i-=f.length,e>i?br(n,t,pr,l,Z,c,f,Z,Z,e-i):r(a,this,c)}var o=lr(n);return u}function hr(n){return se(function(t){t=st(t,1);var r=t.length,e=r,u=wn.prototype.thru;for(n&&t.reverse();e--;){var o=t[e];if(typeof o!="function")throw new ou("Expected a function");if(u&&!i&&"wrapper"==Or(o))var i=new wn([],true)}for(e=i?e:r;++e<r;)var o=t[e],u=Or(o),f="wrapper"==u?ro(o):Z,i=f&&$r(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?i[Or(f[0])].apply(i,f[3]):1==o.length&&$r(o)?i[u]():i.thru(o);
return function(){var n=arguments,e=n[0];if(i&&1==n.length&&Do(e)&&e.length>=200)return i.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function pr(n,t,r,e,u,o,i,f,c,a){function l(){for(var y=arguments.length,b=y,x=Array(y);b--;)x[b]=arguments[b];if(e&&(x=Ht(x,e,u)),o&&(x=Qt(x,o,i)),_||g){var b=yn.placeholder||l.placeholder,j=L(x,b),y=y-j.length;if(a>y)return br(n,t,pr,b,r,x,j,f,c,a-y)}if(y=h?r:this,b=p?y[n]:n,f)for(var j=x.length,m=Uu(f.length,j),w=Xt(x);m--;){
var A=f[m];x[m]=U(A,j)?w[A]:Z}else v&&x.length>1&&x.reverse();return s&&x.length>c&&(x.length=c),this&&this!==Gn&&this instanceof l&&(b=d||lr(b)),b.apply(y,x)}var s=128&t,h=1&t,p=2&t,_=8&t,g=16&t,v=512&t,d=p?Z:lr(n);return l}function _r(n,t){return function(r,e){return xt(r,n,t(e))}}function gr(n){return se(function(t){return t=a(st(t,1),kr()),se(function(e){var u=this;return n(t,function(n){return r(n,u,e)})})})}function vr(n,t,r){return t=Be(t),n=F(n),t&&t>n?(t-=n,r=r===Z?" ":r+"",n=Ke(r,Iu(t/F(r))),
En.test(r)?n.match(kn).slice(0,t).join(""):n.slice(0,t)):""}function dr(n,t,e,u){function o(){for(var t=-1,c=arguments.length,a=-1,l=u.length,s=Array(l+c),h=this&&this!==Gn&&this instanceof o?f:n;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++t];return r(h,i?e:this,s)}var i=1&t,f=lr(n);return o}function yr(n){return function(t,r,e){e&&typeof e!="number"&&zr(t,r,e)&&(r=e=Z),t=Ue(t),t=t===t?t:0,r===Z?(r=t,t=0):r=Ue(r)||0,e=e===Z?r>t?1:-1:Ue(e)||0;var u=-1;r=Cu(Iu((r-t)/(e||1)),0);for(var o=Array(r);r--;)o[n?r:++u]=t,
t+=e;return o}}function br(n,t,r,e,u,o,i,f,c,a){var l=8&t;f=f?Xt(f):Z;var s=l?i:Z;i=l?Z:i;var h=l?o:Z;return o=l?Z:o,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),t=[n,t,u,h,s,o,i,f,c,a],r=r.apply(Z,t),$r(n)&&oo(r,t),r.placeholder=e,r}function xr(n){var t=eu[n];return function(n,r){if(n=Ue(n),r=Be(r)){var e=(Me(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Me(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function jr(n,t,r,e,u,o,i,f){var c=2&t;if(!c&&typeof n!="function")throw new ou("Expected a function");
var a=e?e.length:0;if(a||(t&=-97,e=u=Z),i=i===Z?i:Cu(Be(i),0),f=f===Z?f:Be(f),a-=u?u.length:0,64&t){var l=e,s=u;e=u=Z}var h=c?Z:ro(n);return o=[n,t,r,e,u,l,s,o,i,f],h&&(r=o[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&h[8]>=o[7].length||384==n&&h[8]>=h[7].length&&8==r,131>t||e)&&(1&n&&(o[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=o[3],o[3]=e?Ht(e,r,h[4]):Xt(r),o[4]=e?L(o[3],"__lodash_placeholder__"):Xt(h[4])),(r=h[5])&&(e=o[5],o[5]=e?Qt(e,r,h[6]):Xt(r),o[6]=e?L(o[5],"__lodash_placeholder__"):Xt(h[6])),(r=h[7])&&(o[7]=Xt(r)),
128&n&&(o[8]=null==o[8]?h[8]:Uu(o[8],h[8])),null==o[9]&&(o[9]=h[9]),o[0]=h[0],o[1]=t),n=o[0],t=o[1],r=o[2],e=o[3],u=o[4],f=o[9]=null==o[9]?c?0:n.length:Cu(o[9]-a,0),!f&&24&t&&(t&=-25),(h?no:oo)(t&&1!=t?8==t||16==t?sr(n,t,f):32!=t&&33!=t||u.length?pr.apply(Z,o):dr(n,t,r,e):fr(n,t,r),o)}function mr(n,t,r,e,u,o){var i=-1,f=2&u,c=1&u,a=n.length,l=t.length;if(!(a==l||f&&l>a))return false;if(l=o.get(n))return l==t;for(l=true,o.set(n,t);++i<a;){var s=n[i],h=t[i];if(e)var _=f?e(h,s,i,t,n,o):e(s,h,i,n,t,o);if(_!==Z){
if(_)continue;l=false;break}if(c){if(!p(t,function(n){return s===n||r(s,n,e,u,o)})){l=false;break}}else if(s!==h&&!r(s,h,e,u,o)){l=false;break}}return o["delete"](n),l}function wr(n,t,r,e,u,o){switch(r){case"[object ArrayBuffer]":if(n.byteLength!=t.byteLength||!e(new yu(n),new yu(t)))break;return true;case"[object Boolean]":case"[object Date]":return+n==+t;case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object Number]":return n!=+n?t!=+t:n==+t;case"[object RegExp]":case"[object String]":
return n==t+"";case"[object Map]":var i=M;case"[object Set]":return i||(i=$),(2&o||n.size==t.size)&&e(i(n),i(t),u,1|o);case"[object Symbol]":return!!du&&Gu.call(n)==Gu.call(t)}return false}function Ar(n,t,r,e,u,o){var i=2&u,f=Ne(n),c=f.length,a=Ne(t).length;if(c!=a&&!i)return false;for(var l=c;l--;){var s=f[l];if(!(i?s in t:dt(t,s)))return false}if(a=o.get(n))return a==t;a=true,o.set(n,t);for(var h=i;++l<c;){var s=f[l],p=n[s],_=t[s];if(e)var g=i?e(_,p,s,t,n,o):e(p,_,s,n,t,o);if(g===Z?p!==_&&!r(p,_,e,u,o):!g){a=false;
break}h||(h="constructor"==s)}return a&&!h&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(a=false)),o["delete"](n),a}function Or(n){for(var t=n.name+"",r=Ju[t],e=au.call(Ju,t)?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}function kr(){var n=yn.iteratee||Ye,n=n===Ye?At:n;return arguments.length?n(arguments[0],arguments[1]):n}function Er(n){n=Ze(n);for(var t=n.length;t--;){
var r=n[t][1];n[t][2]=r===r&&!je(r)}return n}function Ir(n,t){var r=null==n?Z:n[t];return we(r)?r:Z}function Sr(n){return hu.call(n)}function Rr(n,t,r){if(null==n)return false;var e=r(n,t);return e||Mr(t)||(t=rt(t),n=Dr(n,t),null!=n&&(t=Gr(t),e=r(n,t))),r=n?n.length:Z,e||!!r&&xe(r)&&U(t,r)&&(Do(n)||Ee(n)||_e(n))}function Wr(n){var t=n.length,r=n.constructor(t);return t&&"string"==typeof n[0]&&au.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Br(n){return Fr(n)?{}:(n=n.constructor,it(ye(n)?n.prototype:Z));
}function Cr(r,e,u){var o=r.constructor;switch(e){case"[object ArrayBuffer]":return Yt(r);case"[object Boolean]":case"[object Date]":return new o(+r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return e=r.buffer,u=u?Yt(e):e,new r.constructor(u,r.byteOffset,r.length);case"[object Map]":return u=r.constructor,
s(M(r),n,new u);case"[object Number]":case"[object String]":return new o(r);case"[object RegExp]":return u=new r.constructor(r.source,hn.exec(r)),u.lastIndex=r.lastIndex,u;case"[object Set]":return u=r.constructor,s($(r),t,new u);case"[object Symbol]":return du?Object(Gu.call(r)):{}}}function Ur(n){var t=n?n.length:Z;return xe(t)&&(Do(n)||Ee(n)||_e(n))?j(t,String):null}function zr(n,t,r){if(!je(r))return false;var e=typeof t;return("number"==e?ge(r)&&U(t,r.length):"string"==e&&t in r)?he(r[t],n):false}function Mr(n,t){
return typeof n=="number"?true:!Do(n)&&(rn.test(n)||!tn.test(n)||null!=t&&n in Object(t))}function Lr(n){var t=typeof n;return"number"==t||"boolean"==t||"string"==t&&"__proto__"!=n||null==n}function $r(n){var t=Or(n),r=yn[t];return typeof r=="function"&&t in An.prototype?n===r?true:(t=ro(r),!!t&&n===t[0]):false}function Fr(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||fu)}function Nr(n,t,r,e,u,o){return je(n)&&je(t)&&(o.set(t,n),St(n,t,Z,Nr,o)),n}function Dr(n,t){return 1==t.length?n:Le(n,Ft(t,0,-1));
}function Zr(n){var t=[];return Me(n).replace(en,function(n,r,e,u){t.push(e?u.replace(ln,"$1"):r||n)}),t}function qr(n){if(n instanceof An)return n.clone();var t=new wn(n.__wrapped__,n.__chain__);return t.__actions__=Xt(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Pr(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:Be(t),Ft(n,0>t?0:t,e)):[]}function Tr(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:Be(t),t=e-t,Ft(n,0,0>t?0:t)):[]}function Kr(n){return n?n[0]:Z}function Gr(n){
var t=n?n.length:0;return t?n[t-1]:Z}function Vr(n,t){return n&&n.length&&t&&t.length?zt(n,t):n}function Jr(n){return n?Lu.call(n):n}function Yr(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){return ve(n)?(t=Cu(n.length,t),true):void 0}),j(t,function(t){return a(n,Ct(t))})}function Hr(n,t){if(!n||!n.length)return[];var e=Yr(n);return null==t?e:a(e,function(n){return r(t,Z,n)})}function Qr(n){return n=yn(n),n.__chain__=true,n}function Xr(n,t){return t(n)}function ne(){return this}function te(n,t){
return typeof t=="function"&&Do(n)?u(n,t):Yu(n,tt(t))}function re(n,t){var r;if(typeof t=="function"&&Do(n)){for(r=n.length;r--&&false!==t(n[r],r,n););r=n}else r=Hu(n,tt(t));return r}function ee(n,t){return(Do(n)?a:kt)(n,kr(t,3))}function ue(n,t){var r=-1,e=We(n),u=e.length,o=u-1;for(t=et(Be(t),0,u);++r<t;){var u=Lt(r,o),i=e[u];e[u]=e[r],e[r]=i}return e.length=t,e}function oe(n,t,r){return t=r?Z:t,t=n&&null==t?n.length:t,jr(n,128,Z,Z,Z,Z,t)}function ie(n,t){var r;if(typeof t!="function")throw new ou("Expected a function");
return n=Be(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=Z),r}}function fe(n,t,r){return t=r?Z:t,n=jr(n,8,Z,Z,Z,Z,Z,t),n.placeholder=yn.placeholder||fe.placeholder,n}function ce(n,t,r){return t=r?Z:t,n=jr(n,16,Z,Z,Z,Z,Z,t),n.placeholder=yn.placeholder||ce.placeholder,n}function ae(n,t,r){function e(){p&&bu(p),a&&bu(a),g=0,c=a=h=p=_=Z}function u(t,r){r&&bu(r),a=p=_=Z,t&&(g=Bo(),l=n.apply(h,c),p||a||(c=h=Z))}function o(){var n=t-(Bo()-s);0>=n||n>t?u(_,a):p=ku(o,n)}function i(){u(y,p);
}function f(){if(c=arguments,s=Bo(),h=this,_=y&&(p||!v),false===d)var r=v&&!p;else{g||a||v||(g=s);var e=d-(s-g),u=(0>=e||e>d)&&(v||a);u?(a&&(a=bu(a)),g=s,l=n.apply(h,c)):a||(a=ku(i,e))}return u&&p?p=bu(p):p||t===d||(p=ku(o,t)),r&&(u=true,l=n.apply(h,c)),!u||p||a||(c=h=Z),l}var c,a,l,s,h,p,_,g=0,v=false,d=false,y=true;if(typeof n!="function")throw new ou("Expected a function");return t=Ue(t)||0,je(r)&&(v=!!r.leading,d="maxWait"in r&&Cu(Ue(r.maxWait)||0,t),y="trailing"in r?!!r.trailing:y),f.cancel=e,f.flush=function(){
return(p&&_||a&&y)&&(l=n.apply(h,c)),e(),l},f}function le(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new ou("Expected a function");return r.cache=new le.Cache,r}function se(n,t){if(typeof n!="function")throw new ou("Expected a function");return t=Cu(t===Z?n.length-1:Be(t),0),function(){for(var e=arguments,u=-1,o=Cu(e.length-t,0),i=Array(o);++u<o;)i[u]=e[t+u];
switch(t){case 0:return n.call(this,i);case 1:return n.call(this,e[0],i);case 2:return n.call(this,e[0],e[1],i)}for(o=Array(t+1),u=-1;++u<t;)o[u]=e[u];return o[t]=i,r(n,this,o)}}function he(n,t){return n===t||n!==n&&t!==t}function pe(n,t){return n>t}function _e(n){return ve(n)&&au.call(n,"callee")&&(!Ou.call(n,"callee")||"[object Arguments]"==hu.call(n))}function ge(n){return null!=n&&!(typeof n=="function"&&ye(n))&&xe(eo(n))}function ve(n){return me(n)&&ge(n)}function de(n){if(!me(n))return false;var t=n.constructor;
return"[object Error]"==hu.call(n)||typeof t=="function"&&"[object Error]"==hu.call(t.prototype)}function ye(n){return n=je(n)?hu.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function be(n){return typeof n=="number"&&n==Be(n)}function xe(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function je(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function me(n){return!!n&&typeof n=="object"}function we(n){return null==n?false:ye(n)?_u.test(cu.call(n)):me(n)&&(C(n)?_u:vn).test(n);
}function Ae(n){return typeof n=="number"||me(n)&&"[object Number]"==hu.call(n)}function Oe(n){if(!me(n)||"[object Object]"!=hu.call(n)||C(n))return false;var t=fu;return typeof n.constructor=="function"&&(t=ju(n)),null===t?true:(n=t.constructor,typeof n=="function"&&n instanceof n&&cu.call(n)==su)}function ke(n){return je(n)&&"[object RegExp]"==hu.call(n)}function Ee(n){return typeof n=="string"||!Do(n)&&me(n)&&"[object String]"==hu.call(n)}function Ie(n){return typeof n=="symbol"||me(n)&&"[object Symbol]"==hu.call(n);
}function Se(n){return me(n)&&xe(n.length)&&!!Bn[hu.call(n)]}function Re(n,t){return t>n}function We(n){if(!n)return[];if(ge(n))return Ee(n)?n.match(kn):Xt(n);if(wu&&n[wu])return z(n[wu]());var t=Sr(n);return("[object Map]"==t?M:"[object Set]"==t?$:qe)(n)}function Be(n){if(!n)return 0===n?n:0;if(n=Ue(n),n===q||n===-q)return 1.7976931348623157e308*(0>n?-1:1);var t=n%1;return n===n?t?n-t:n:0}function Ce(n){return n?et(Be(n),0,4294967295):0}function Ue(n){if(je(n)&&(n=ye(n.valueOf)?n.valueOf():n,n=je(n)?n+"":n),
typeof n!="string")return 0===n?n:+n;n=n.replace(fn,"");var t=gn.test(n);return t||dn.test(n)?Nn(n.slice(2),t?2:8):_n.test(n)?P:+n}function ze(n){return nr(n,De(n))}function Me(n){if(typeof n=="string")return n;if(null==n)return"";if(Ie(n))return du?Vu.call(n):"";var t=n+"";return"0"==t&&1/n==-q?"-0":t}function Le(n,t,r){return n=null==n?Z:vt(n,t),n===Z?r:n}function $e(n,t){return Rr(n,t,dt)}function Fe(n,t){return Rr(n,t,yt)}function Ne(n){var t=Fr(n);if(!t&&!ge(n))return Bu(Object(n));var r,e=Ur(n),u=!!e,e=e||[],o=e.length;
for(r in n)!dt(n,r)||u&&("length"==r||U(r,o))||t&&"constructor"==r||e.push(r);return e}function De(n){for(var t=-1,r=Fr(n),e=Ot(n),u=e.length,o=Ur(n),i=!!o,o=o||[],f=o.length;++t<u;){var c=e[t];i&&("length"==c||U(c,f))||"constructor"==c&&(r||!au.call(n,c))||o.push(c)}return o}function Ze(n){return m(n,Ne(n))}function qe(n){return n?A(n,Ne(n)):[]}function Pe(n){return fi(Me(n).toLowerCase())}function Te(n){return(n=Me(n))&&n.replace(bn,S).replace(On,"")}function Ke(n,t){n=Me(n),t=Be(t);var r="";if(!n||1>t||t>9007199254740991)return r;
do t%2&&(r+=n),t=Su(t/2),n+=n;while(t);return r}function Ge(n,t,r){return n=Me(n),t=r?Z:t,t===Z&&(t=Rn.test(n)?Sn:In),n.match(t)||[]}function Ve(n){return function(){return n}}function Je(n){return n}function Ye(n){return At(typeof n=="function"?n:ut(n,true))}function He(n,t,r){var e=Ne(t),o=gt(t,e);null!=r||je(t)&&(o.length||!e.length)||(r=t,t=n,n=this,o=gt(t,Ne(t)));var i=je(r)&&"chain"in r?r.chain:true,f=ye(n);return u(o,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;
if(i||t){var r=n(this.__wrapped__);return(r.__actions__=Xt(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,l([this.value()],arguments))})}),n}function Qe(){}function Xe(n){return Mr(n)?Ct(n):Ut(n)}function nu(n){return n&&n.length?x(n,Je):0}E=E?Vn.defaults({},E,Vn.pick(Gn,Wn)):Gn;var tu=E.Date,ru=E.Error,eu=E.Math,uu=E.RegExp,ou=E.TypeError,iu=E.Array.prototype,fu=E.Object.prototype,cu=E.Function.prototype.toString,au=fu.hasOwnProperty,lu=0,su=cu.call(Object),hu=fu.toString,pu=Gn._,_u=uu("^"+cu.call(au).replace(un,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),gu=qn?E.Buffer:Z,vu=E.Reflect,du=E.Symbol,yu=E.Uint8Array,bu=E.clearTimeout,xu=vu?vu.f:Z,ju=Object.getPrototypeOf,mu=Object.getOwnPropertySymbols,wu=typeof(wu=du&&du.iterator)=="symbol"?wu:Z,Au=Object.create,Ou=fu.propertyIsEnumerable,ku=E.setTimeout,Eu=iu.splice,Iu=eu.ceil,Su=eu.floor,Ru=E.isFinite,Wu=iu.join,Bu=Object.keys,Cu=eu.max,Uu=eu.min,zu=E.parseInt,Mu=eu.random,Lu=iu.reverse,$u=Ir(E,"Map"),Fu=Ir(E,"Set"),Nu=Ir(E,"WeakMap"),Du=Ir(Object,"create"),Zu=Nu&&new Nu,qu=$u?cu.call($u):"",Pu=Fu?cu.call(Fu):"",Tu=Nu?cu.call(Nu):"",Ku=du?du.prototype:Z,Gu=du?Ku.valueOf:Z,Vu=du?Ku.toString:Z,Ju={};
yn.templateSettings={escape:Q,evaluate:X,interpolate:nn,variable:"",imports:{_:yn}};var Yu=or(pt),Hu=or(_t,true),Qu=ir(),Xu=ir(true);xu&&!Ou.call({valueOf:1},"valueOf")&&(Ot=function(n){return z(xu(n))});var no=Zu?function(n,t){return Zu.set(n,t),n}:Je,to=Fu&&2===new Fu([1,2]).size?function(n){return new Fu(n)}:Qe,ro=Zu?function(n){return Zu.get(n)}:Qe,eo=Ct("length"),uo=mu||function(){return[]};($u&&"[object Map]"!=Sr(new $u)||Fu&&"[object Set]"!=Sr(new Fu)||Nu&&"[object WeakMap]"!=Sr(new Nu))&&(Sr=function(n){
var t=hu.call(n);if(n="[object Object]"==t?n.constructor:null,n=typeof n=="function"?cu.call(n):"")switch(n){case qu:return"[object Map]";case Pu:return"[object Set]";case Tu:return"[object WeakMap]"}return t});var oo=function(){var n=0,t=0;return function(r,e){var u=Bo(),o=16-(u-t);if(t=u,o>0){if(150<=++n)return r}else n=0;return no(r,e)}}(),io=se(function(n,t){Do(n)||(n=null==n?[]:[Object(n)]),t=st(t,1);for(var r=n,e=t,u=-1,o=r.length,i=-1,f=e.length,c=Array(o+f);++u<o;)c[u]=r[u];for(;++i<f;)c[u++]=e[i];
return c}),fo=se(function(n,t){return ve(n)?ct(n,st(t,1,true)):[]}),co=se(function(n,t){var r=Gr(t);return ve(r)&&(r=Z),ve(n)?ct(n,st(t,1,true),kr(r)):[]}),ao=se(function(n,t){var r=Gr(t);return ve(r)&&(r=Z),ve(n)?ct(n,st(t,1,true),Z,r):[]}),lo=se(function(n){var t=a(n,nt);return t.length&&t[0]===n[0]?bt(t):[]}),so=se(function(n){var t=Gr(n),r=a(n,nt);return t===Gr(r)?t=Z:r.pop(),r.length&&r[0]===n[0]?bt(r,kr(t)):[]}),ho=se(function(n){var t=Gr(n),r=a(n,nt);return t===Gr(r)?t=Z:r.pop(),r.length&&r[0]===n[0]?bt(r,Z,t):[];
}),po=se(Vr),_o=se(function(n,t){t=a(st(t,1),String);var r=Xn(n,t);return Mt(n,t.sort(I)),r}),go=se(function(n){return Pt(st(n,1,true))}),vo=se(function(n){var t=Gr(n);return ve(t)&&(t=Z),Pt(st(n,1,true),kr(t))}),yo=se(function(n){var t=Gr(n);return ve(t)&&(t=Z),Pt(st(n,1,true),Z,t)}),bo=se(function(n,t){return ve(n)?ct(n,t):[]}),xo=se(function(n){return Gt(i(n,ve))}),jo=se(function(n){var t=Gr(n);return ve(t)&&(t=Z),Gt(i(n,ve),kr(t))}),mo=se(function(n){var t=Gr(n);return ve(t)&&(t=Z),Gt(i(n,ve),Z,t)}),wo=se(Yr),Ao=se(function(n){
var t=n.length,t=t>1?n[t-1]:Z,t=typeof t=="function"?(n.pop(),t):Z;return Hr(n,t)}),Oo=se(function(n){function t(t){return Xn(t,n)}n=st(n,1);var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return 1>=r&&!this.__actions__.length&&u instanceof An&&U(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Xr,args:[t],thisArg:Z}),new wn(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(Z),n})):this.thru(t)}),ko=er(function(n,t,r){au.call(n,r)?++n[r]:n[r]=1}),Eo=er(function(n,t,r){au.call(n,r)?n[r].push(t):n[r]=[t];
}),Io=se(function(n,t,e){var u=-1,o=typeof t=="function",i=Mr(t),f=ge(n)?Array(n.length):[];return Yu(n,function(n){var c=o?t:i&&null!=n?n[t]:Z;f[++u]=c?r(c,n,e):jt(n,t,e)}),f}),So=er(function(n,t,r){n[r]=t}),Ro=er(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Wo=se(function(n,t){if(null==n)return[];var r=t.length;return r>1&&zr(n,t[0],t[1])?t=[]:r>2&&zr(t[0],t[1],t[2])&&(t.length=1),Rt(n,st(t,1),[])}),Bo=tu.now,Co=se(function(n,t,r){var e=1;if(r.length)var u=L(r,yn.placeholder||Co.placeholder),e=32|e;
return jr(n,e,t,r,u)}),Uo=se(function(n,t,r){var e=3;if(r.length)var u=L(r,yn.placeholder||Uo.placeholder),e=32|e;return jr(t,e,n,r,u)}),zo=se(function(n,t){return ft(n,1,t)}),Mo=se(function(n,t,r){return ft(n,Ue(t)||0,r)}),Lo=se(function(n,t){t=a(st(t,1),kr());var e=t.length;return se(function(u){for(var o=-1,i=Uu(u.length,e);++o<i;)u[o]=t[o].call(this,u[o]);return r(n,this,u)})}),$o=se(function(n,t){var r=L(t,yn.placeholder||$o.placeholder);return jr(n,32,Z,t,r)}),Fo=se(function(n,t){var r=L(t,yn.placeholder||Fo.placeholder);
return jr(n,64,Z,t,r)}),No=se(function(n,t){return jr(n,256,Z,Z,Z,st(t,1))}),Do=Array.isArray,Zo=gu?function(n){return n instanceof gu}:Ve(false),qo=ur(function(n,t){nr(t,Ne(t),n)}),Po=ur(function(n,t){nr(t,De(t),n)}),To=ur(function(n,t,r,e){tr(t,De(t),n,e)}),Ko=ur(function(n,t,r,e){tr(t,Ne(t),n,e)}),Go=se(function(n,t){return Xn(n,st(t,1))}),Vo=se(function(n){return n.push(Z,Kn),r(To,Z,n)}),Jo=se(function(n){return n.push(Z,Nr),r(ni,Z,n)}),Yo=_r(function(n,t,r){n[t]=r},Ve(Je)),Ho=_r(function(n,t,r){
au.call(n,t)?n[t].push(r):n[t]=[r]},kr),Qo=se(jt),Xo=ur(function(n,t,r){St(n,t,r)}),ni=ur(function(n,t,r,e){St(n,t,r,e)}),ti=se(function(n,t){return null==n?{}:(t=a(st(t,1),String),Wt(n,ct(De(n),t)))}),ri=se(function(n,t){return null==n?{}:Wt(n,st(t,1))}),ei=ar(function(n,t,r){return t=t.toLowerCase(),n+(r?Pe(t):t)}),ui=ar(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),oi=ar(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),ii=cr("toLowerCase"),fi=cr("toUpperCase"),ci=ar(function(n,t,r){
return n+(r?"_":"")+t.toLowerCase()}),ai=ar(function(n,t,r){return n+(r?" ":"")+Pe(t)}),li=ar(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),si=se(function(n,t){try{return r(n,Z,t)}catch(e){return de(e)?e:new ru(e)}}),hi=se(function(n,t){return u(st(t,1),function(t){n[t]=Co(n[t],n)}),n}),pi=hr(),_i=hr(true),gi=se(function(n,t){return function(r){return jt(r,n,t)}}),vi=se(function(n,t){return function(r){return jt(n,r,t)}}),di=gr(a),yi=gr(o),bi=gr(p),xi=yr(),ji=yr(true),mi=xr("ceil"),wi=xr("floor"),Ai=xr("round");
return yn.prototype=mn.prototype,wn.prototype=it(mn.prototype),wn.prototype.constructor=wn,An.prototype=it(mn.prototype),An.prototype.constructor=An,Un.prototype=Du?Du(null):fu,zn.prototype.clear=function(){this.__data__={hash:new Un,map:$u?new $u:[],string:new Un}},zn.prototype["delete"]=function(n){var t=this.__data__;return Lr(n)?(t=typeof n=="string"?t.string:t.hash,n=(Du?t[n]!==Z:au.call(t,n))&&delete t[n]):n=$u?t.map["delete"](n):Dn(t.map,n),n},zn.prototype.get=function(n){var t=this.__data__;
return Lr(n)?(t=typeof n=="string"?t.string:t.hash,Du?(n=t[n],n="__lodash_hash_undefined__"===n?Z:n):n=au.call(t,n)?t[n]:Z):n=$u?t.map.get(n):Zn(t.map,n),n},zn.prototype.has=function(n){var t=this.__data__;return Lr(n)?(t=typeof n=="string"?t.string:t.hash,n=Du?t[n]!==Z:au.call(t,n)):n=$u?t.map.has(n):-1<Pn(t.map,n),n},zn.prototype.set=function(n,t){var r=this.__data__;return Lr(n)?(typeof n=="string"?r.string:r.hash)[n]=Du&&t===Z?"__lodash_hash_undefined__":t:$u?r.map.set(n,t):Tn(r.map,n,t),this;
},Mn.prototype.push=function(n){var t=this.__data__;Lr(n)?(t=t.__data__,(typeof n=="string"?t.string:t.hash)[n]="__lodash_hash_undefined__"):t.set(n,"__lodash_hash_undefined__")},$n.prototype.clear=function(){this.__data__={array:[],map:null}},$n.prototype["delete"]=function(n){var t=this.__data__,r=t.array;return r?Dn(r,n):t.map["delete"](n)},$n.prototype.get=function(n){var t=this.__data__,r=t.array;return r?Zn(r,n):t.map.get(n)},$n.prototype.has=function(n){var t=this.__data__,r=t.array;return r?-1<Pn(r,n):t.map.has(n);
},$n.prototype.set=function(n,t){var r=this.__data__,e=r.array;return e&&(199>e.length?Tn(e,n,t):(r.array=null,r.map=new zn(e))),(r=r.map)&&r.set(n,t),this},le.Cache=zn,yn.after=function(n,t){if(typeof t!="function")throw new ou("Expected a function");return n=Be(n),function(){return 1>--n?t.apply(this,arguments):void 0}},yn.ary=oe,yn.assign=qo,yn.assignIn=Po,yn.assignInWith=To,yn.assignWith=Ko,yn.at=Go,yn.before=ie,yn.bind=Co,yn.bindAll=hi,yn.bindKey=Uo,yn.castArray=function(){if(!arguments.length)return[];
var n=arguments[0];return Do(n)?n:[n]},yn.chain=Qr,yn.chunk=function(n,t){t=Cu(Be(t),0);var r=n?n.length:0;if(!r||1>t)return[];for(var e=0,u=-1,o=Array(Iu(r/t));r>e;)o[++u]=Ft(n,e,e+=t);return o},yn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){var o=n[t];o&&(u[++e]=o)}return u},yn.concat=io,yn.cond=function(n){var t=n?n.length:0,e=kr();return n=t?a(n,function(n){if("function"!=typeof n[1])throw new ou("Expected a function");return[e(n[0]),n[1]]}):[],se(function(e){for(var u=-1;++u<t;){
var o=n[u];if(r(o[0],this,e))return r(o[1],this,e)}})},yn.conforms=function(n){return ot(ut(n,true))},yn.constant=Ve,yn.countBy=ko,yn.create=function(n,t){var r=it(n);return t?Qn(r,t):r},yn.curry=fe,yn.curryRight=ce,yn.debounce=ae,yn.defaults=Vo,yn.defaultsDeep=Jo,yn.defer=zo,yn.delay=Mo,yn.difference=fo,yn.differenceBy=co,yn.differenceWith=ao,yn.drop=Pr,yn.dropRight=Tr,yn.dropRightWhile=function(n,t){return n&&n.length?Tt(n,kr(t,3),true,true):[]},yn.dropWhile=function(n,t){return n&&n.length?Tt(n,kr(t,3),true):[];
},yn.fill=function(n,t,r,e){var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&zr(n,t,r)&&(r=0,e=u),u=n.length,r=Be(r),0>r&&(r=-r>u?0:u+r),e=e===Z||e>u?u:Be(e),0>e&&(e+=u),e=r>e?0:Ce(e);e>r;)n[r++]=t;return n},yn.filter=function(n,t){return(Do(n)?i:lt)(n,kr(t,3))},yn.flatMap=function(n,t){return st(ee(n,t),1)},yn.flatten=function(n){return n&&n.length?st(n,1):[]},yn.flattenDeep=function(n){return n&&n.length?st(n,q):[]},yn.flattenDepth=function(n,t){return n&&n.length?(t=t===Z?1:Be(t),st(n,t)):[];
},yn.flip=function(n){return jr(n,512)},yn.flow=pi,yn.flowRight=_i,yn.fromPairs=function(n){for(var t=-1,r=n?n.length:0,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},yn.functions=function(n){return null==n?[]:gt(n,Ne(n))},yn.functionsIn=function(n){return null==n?[]:gt(n,De(n))},yn.groupBy=Eo,yn.initial=function(n){return Tr(n,1)},yn.intersection=lo,yn.intersectionBy=so,yn.intersectionWith=ho,yn.invert=Yo,yn.invertBy=Ho,yn.invokeMap=Io,yn.iteratee=Ye,yn.keyBy=So,yn.keys=Ne,yn.keysIn=De,yn.map=ee,
yn.mapKeys=function(n,t){var r={};return t=kr(t,3),pt(n,function(n,e,u){r[t(n,e,u)]=n}),r},yn.mapValues=function(n,t){var r={};return t=kr(t,3),pt(n,function(n,e,u){r[e]=t(n,e,u)}),r},yn.matches=function(n){return Et(ut(n,true))},yn.matchesProperty=function(n,t){return It(n,ut(t,true))},yn.memoize=le,yn.merge=Xo,yn.mergeWith=ni,yn.method=gi,yn.methodOf=vi,yn.mixin=He,yn.negate=function(n){if(typeof n!="function")throw new ou("Expected a function");return function(){return!n.apply(this,arguments)}},yn.nthArg=function(n){
return n=Be(n),function(){return arguments[n]}},yn.omit=ti,yn.omitBy=function(n,t){return t=kr(t,2),Bt(n,function(n,r){return!t(n,r)})},yn.once=function(n){return ie(2,n)},yn.orderBy=function(n,t,r,e){return null==n?[]:(Do(t)||(t=null==t?[]:[t]),r=e?Z:r,Do(r)||(r=null==r?[]:[r]),Rt(n,t,r))},yn.over=di,yn.overArgs=Lo,yn.overEvery=yi,yn.overSome=bi,yn.partial=$o,yn.partialRight=Fo,yn.partition=Ro,yn.pick=ri,yn.pickBy=function(n,t){return null==n?{}:Bt(n,kr(t,2))},yn.property=Xe,yn.propertyOf=function(n){
return function(t){return null==n?Z:vt(n,t)}},yn.pull=po,yn.pullAll=Vr,yn.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?zt(n,t,kr(r)):n},yn.pullAt=_o,yn.range=xi,yn.rangeRight=ji,yn.rearg=No,yn.reject=function(n,t){var r=Do(n)?i:lt;return t=kr(t,3),r(n,function(n,r,e){return!t(n,r,e)})},yn.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],o=n.length;for(t=kr(t,3);++e<o;){var i=n[e];t(i,e,n)&&(r.push(i),u.push(e))}return Mt(n,u),r},yn.rest=se,yn.reverse=Jr,yn.sampleSize=ue,
yn.set=function(n,t,r){return null==n?n:$t(n,t,r)},yn.setWith=function(n,t,r,e){return e=typeof e=="function"?e:Z,null==n?n:$t(n,t,r,e)},yn.shuffle=function(n){return ue(n,4294967295)},yn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&zr(n,t,r)?(t=0,r=e):(t=null==t?0:Be(t),r=r===Z?e:Be(r)),Ft(n,t,r)):[]},yn.sortBy=Wo,yn.sortedUniq=function(n){return n&&n.length?qt(n):[]},yn.sortedUniqBy=function(n,t){return n&&n.length?qt(n,kr(t)):[]},yn.split=function(n,t,r){return Me(n).split(t,r);
},yn.spread=function(n,t){if(typeof n!="function")throw new ou("Expected a function");return t=t===Z?0:Cu(Be(t),0),se(function(e){var u=e[t];return e=e.slice(0,t),u&&l(e,u),r(n,this,e)})},yn.tail=function(n){return Pr(n,1)},yn.take=function(n,t,r){return n&&n.length?(t=r||t===Z?1:Be(t),Ft(n,0,0>t?0:t)):[]},yn.takeRight=function(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:Be(t),t=e-t,Ft(n,0>t?0:t,e)):[]},yn.takeRightWhile=function(n,t){return n&&n.length?Tt(n,kr(t,3),false,true):[]},yn.takeWhile=function(n,t){
return n&&n.length?Tt(n,kr(t,3)):[]},yn.tap=function(n,t){return t(n),n},yn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ou("Expected a function");return je(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ae(n,t,{leading:e,maxWait:t,trailing:u})},yn.thru=Xr,yn.toArray=We,yn.toPairs=Ze,yn.toPairsIn=function(n){return m(n,De(n))},yn.toPath=function(n){return Do(n)?a(n,String):Zr(n)},yn.toPlainObject=ze,yn.transform=function(n,t,r){var e=Do(n)||Se(n);if(t=kr(t,4),
null==r)if(e||je(n)){var o=n.constructor;r=e?Do(n)?new o:[]:it(ye(o)?o.prototype:Z)}else r={};return(e?u:pt)(n,function(n,e,u){return t(r,n,e,u)}),r},yn.unary=function(n){return oe(n,1)},yn.union=go,yn.unionBy=vo,yn.unionWith=yo,yn.uniq=function(n){return n&&n.length?Pt(n):[]},yn.uniqBy=function(n,t){return n&&n.length?Pt(n,kr(t)):[]},yn.uniqWith=function(n,t){return n&&n.length?Pt(n,Z,t):[]},yn.unset=function(n,t){var r;if(null==n)r=true;else{r=n;var e=t,e=Mr(e,r)?[e+""]:rt(e);r=Dr(r,e),e=Gr(e),r=null!=r&&$e(r,e)?delete r[e]:true;
}return r},yn.unzip=Yr,yn.unzipWith=Hr,yn.values=qe,yn.valuesIn=function(n){return null==n?[]:A(n,De(n))},yn.without=bo,yn.words=Ge,yn.wrap=function(n,t){return t=null==t?Je:t,$o(t,n)},yn.xor=xo,yn.xorBy=jo,yn.xorWith=mo,yn.zip=wo,yn.zipObject=function(n,t){return Vt(n||[],t||[],Yn)},yn.zipObjectDeep=function(n,t){return Vt(n||[],t||[],$t)},yn.zipWith=Ao,yn.extend=Po,yn.extendWith=To,He(yn,yn),yn.add=function(n,t){var r;return n===Z&&t===Z?0:(n!==Z&&(r=n),t!==Z&&(r=r===Z?t:r+t),r)},yn.attempt=si,
yn.camelCase=ei,yn.capitalize=Pe,yn.ceil=mi,yn.clamp=function(n,t,r){return r===Z&&(r=t,t=Z),r!==Z&&(r=Ue(r),r=r===r?r:0),t!==Z&&(t=Ue(t),t=t===t?t:0),et(Ue(n),t,r)},yn.clone=function(n){return ut(n)},yn.cloneDeep=function(n){return ut(n,true)},yn.cloneDeepWith=function(n,t){return ut(n,true,t)},yn.cloneWith=function(n,t){return ut(n,false,t)},yn.deburr=Te,yn.endsWith=function(n,t,r){n=Me(n),t=typeof t=="string"?t:t+"";var e=n.length;return r=r===Z?e:et(Be(r),0,e),r-=t.length,r>=0&&n.indexOf(t,r)==r},yn.eq=he,
yn.escape=function(n){return(n=Me(n))&&H.test(n)?n.replace(J,R):n},yn.escapeRegExp=function(n){return(n=Me(n))&&on.test(n)?n.replace(un,"\\$&"):n},yn.every=function(n,t,r){var e=Do(n)?o:at;return r&&zr(n,t,r)&&(t=Z),e(n,kr(t,3))},yn.find=function(n,t){if(t=kr(t,3),Do(n)){var r=v(n,t);return r>-1?n[r]:Z}return g(n,t,Yu)},yn.findIndex=function(n,t){return n&&n.length?v(n,kr(t,3)):-1},yn.findKey=function(n,t){return g(n,kr(t,3),pt,true)},yn.findLast=function(n,t){if(t=kr(t,3),Do(n)){var r=v(n,t,true);return r>-1?n[r]:Z;
}return g(n,t,Hu)},yn.findLastIndex=function(n,t){return n&&n.length?v(n,kr(t,3),true):-1},yn.findLastKey=function(n,t){return g(n,kr(t,3),_t,true)},yn.floor=wi,yn.forEach=te,yn.forEachRight=re,yn.forIn=function(n,t){return null==n?n:Qu(n,tt(t),De)},yn.forInRight=function(n,t){return null==n?n:Xu(n,tt(t),De)},yn.forOwn=function(n,t){return n&&pt(n,tt(t))},yn.forOwnRight=function(n,t){return n&&_t(n,tt(t))},yn.get=Le,yn.gt=pe,yn.gte=function(n,t){return n>=t},yn.has=$e,yn.hasIn=Fe,yn.head=Kr,yn.identity=Je,
yn.includes=function(n,t,r,e){return n=ge(n)?n:qe(n),r=r&&!e?Be(r):0,e=n.length,0>r&&(r=Cu(e+r,0)),Ee(n)?e>=r&&-1<n.indexOf(t,r):!!e&&-1<d(n,t,r)},yn.indexOf=function(n,t,r){var e=n?n.length:0;return e?(r=Be(r),0>r&&(r=Cu(e+r,0)),d(n,t,r)):-1},yn.inRange=function(n,t,r){return t=Ue(t)||0,r===Z?(r=t,t=0):r=Ue(r)||0,n=Ue(n),n>=Uu(t,r)&&n<Cu(t,r)},yn.invoke=Qo,yn.isArguments=_e,yn.isArray=Do,yn.isArrayBuffer=function(n){return me(n)&&"[object ArrayBuffer]"==hu.call(n)},yn.isArrayLike=ge,yn.isArrayLikeObject=ve,
yn.isBoolean=function(n){return true===n||false===n||me(n)&&"[object Boolean]"==hu.call(n)},yn.isBuffer=Zo,yn.isDate=function(n){return me(n)&&"[object Date]"==hu.call(n)},yn.isElement=function(n){return!!n&&1===n.nodeType&&me(n)&&!Oe(n)},yn.isEmpty=function(n){if(ge(n)&&(Do(n)||Ee(n)||ye(n.splice)||_e(n)))return!n.length;for(var t in n)if(au.call(n,t))return false;return true},yn.isEqual=function(n,t){return mt(n,t)},yn.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:Z)?r(n,t):Z;return e===Z?mt(n,t,r):!!e;
},yn.isError=de,yn.isFinite=function(n){return typeof n=="number"&&Ru(n)},yn.isFunction=ye,yn.isInteger=be,yn.isLength=xe,yn.isMap=function(n){return me(n)&&"[object Map]"==Sr(n)},yn.isMatch=function(n,t){return n===t||wt(n,t,Er(t))},yn.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:Z,wt(n,t,Er(t),r)},yn.isNaN=function(n){return Ae(n)&&n!=+n},yn.isNative=we,yn.isNil=function(n){return null==n},yn.isNull=function(n){return null===n},yn.isNumber=Ae,yn.isObject=je,yn.isObjectLike=me,yn.isPlainObject=Oe,
yn.isRegExp=ke,yn.isSafeInteger=function(n){return be(n)&&n>=-9007199254740991&&9007199254740991>=n},yn.isSet=function(n){return me(n)&&"[object Set]"==Sr(n)},yn.isString=Ee,yn.isSymbol=Ie,yn.isTypedArray=Se,yn.isUndefined=function(n){return n===Z},yn.isWeakMap=function(n){return me(n)&&"[object WeakMap]"==Sr(n)},yn.isWeakSet=function(n){return me(n)&&"[object WeakSet]"==hu.call(n)},yn.join=function(n,t){return n?Wu.call(n,t):""},yn.kebabCase=ui,yn.last=Gr,yn.lastIndexOf=function(n,t,r){var e=n?n.length:0;
if(!e)return-1;var u=e;if(r!==Z&&(u=Be(r),u=(0>u?Cu(e+u,0):Uu(u,e-1))+1),t!==t)return B(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},yn.lowerCase=oi,yn.lowerFirst=ii,yn.lt=Re,yn.lte=function(n,t){return t>=n},yn.max=function(n){return n&&n.length?_(n,Je,pe):Z},yn.maxBy=function(n,t){return n&&n.length?_(n,kr(t),pe):Z},yn.mean=function(n){return nu(n)/(n?n.length:0)},yn.min=function(n){return n&&n.length?_(n,Je,Re):Z},yn.minBy=function(n,t){return n&&n.length?_(n,kr(t),Re):Z},yn.noConflict=function(){
return Gn._===this&&(Gn._=pu),this},yn.noop=Qe,yn.now=Bo,yn.pad=function(n,t,r){n=Me(n),t=Be(t);var e=F(n);return t&&t>e?(e=(t-e)/2,t=Su(e),e=Iu(e),vr("",t,r)+n+vr("",e,r)):n},yn.padEnd=function(n,t,r){return n=Me(n),n+vr(n,t,r)},yn.padStart=function(n,t,r){return n=Me(n),vr(n,t,r)+n},yn.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),n=Me(n).replace(fn,""),zu(n,t||(pn.test(n)?16:10))},yn.random=function(n,t,r){if(r&&typeof r!="boolean"&&zr(n,t,r)&&(t=r=Z),r===Z&&(typeof t=="boolean"?(r=t,
t=Z):typeof n=="boolean"&&(r=n,n=Z)),n===Z&&t===Z?(n=0,t=1):(n=Ue(n)||0,t===Z?(t=n,n=0):t=Ue(t)||0),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Mu(),Uu(n+r*(t-n+Fn("1e-"+((r+"").length-1))),t)):Lt(n,t)},yn.reduce=function(n,t,r){var e=Do(n)?s:y,u=3>arguments.length;return e(n,kr(t,4),r,u,Yu)},yn.reduceRight=function(n,t,r){var e=Do(n)?h:y,u=3>arguments.length;return e(n,kr(t,4),r,u,Hu)},yn.repeat=Ke,yn.replace=function(){var n=arguments,t=Me(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},yn.result=function(n,t,r){
if(Mr(t,n))e=null==n?Z:n[t];else{t=rt(t);var e=Le(n,t);n=Dr(n,t)}return e===Z&&(e=r),ye(e)?e.call(n):e},yn.round=Ai,yn.runInContext=D,yn.sample=function(n){n=ge(n)?n:qe(n);var t=n.length;return t>0?n[Lt(0,t-1)]:Z},yn.size=function(n){if(null==n)return 0;if(ge(n)){var t=n.length;return t&&Ee(n)?F(n):t}return Ne(n).length},yn.snakeCase=ci,yn.some=function(n,t,r){var e=Do(n)?p:Nt;return r&&zr(n,t,r)&&(t=Z),e(n,kr(t,3))},yn.sortedIndex=function(n,t){return Dt(n,t)},yn.sortedIndexBy=function(n,t,r){return Zt(n,t,kr(r));
},yn.sortedIndexOf=function(n,t){var r=n?n.length:0;if(r){var e=Dt(n,t);if(r>e&&he(n[e],t))return e}return-1},yn.sortedLastIndex=function(n,t){return Dt(n,t,true)},yn.sortedLastIndexBy=function(n,t,r){return Zt(n,t,kr(r),true)},yn.sortedLastIndexOf=function(n,t){if(n&&n.length){var r=Dt(n,t,true)-1;if(he(n[r],t))return r}return-1},yn.startCase=ai,yn.startsWith=function(n,t,r){return n=Me(n),r=et(Be(r),0,n.length),n.lastIndexOf(t,r)==r},yn.subtract=function(n,t){var r;return n===Z&&t===Z?0:(n!==Z&&(r=n),
t!==Z&&(r=r===Z?t:r-t),r)},yn.sum=nu,yn.sumBy=function(n,t){return n&&n.length?x(n,kr(t)):0},yn.template=function(n,t,r){var e=yn.templateSettings;r&&zr(n,t,r)&&(t=Z),n=Me(n),t=To({},t,e,Kn),r=To({},t.imports,e.imports,Kn);var u,o,i=Ne(r),f=A(r,i),c=0;r=t.interpolate||xn;var a="__p+='";r=uu((t.escape||xn).source+"|"+r.source+"|"+(r===nn?sn:xn).source+"|"+(t.evaluate||xn).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,i,f,l){return e||(e=i),
a+=n.slice(c,l).replace(jn,W),r&&(u=true,a+="'+__e("+r+")+'"),f&&(o=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(o?a.replace(T,""):a).replace(K,"$1").replace(G,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=si(function(){return Function(i,l+"return "+a).apply(Z,f);
}),t.source=a,de(t))throw t;return t},yn.times=function(n,t){if(n=Be(n),1>n||n>9007199254740991)return[];var r=4294967295,e=Uu(n,4294967295);for(t=tt(t),n-=4294967295,e=j(e,t);++r<n;)t(r);return e},yn.toInteger=Be,yn.toLength=Ce,yn.toLower=function(n){return Me(n).toLowerCase()},yn.toNumber=Ue,yn.toSafeInteger=function(n){return et(Be(n),-9007199254740991,9007199254740991)},yn.toString=Me,yn.toUpper=function(n){return Me(n).toUpperCase()},yn.trim=function(n,t,r){return(n=Me(n))?r||t===Z?n.replace(fn,""):(t+="")?(n=n.match(kn),
t=t.match(kn),n.slice(O(n,t),k(n,t)+1).join("")):n:n},yn.trimEnd=function(n,t,r){return(n=Me(n))?r||t===Z?n.replace(an,""):(t+="")?(n=n.match(kn),n.slice(0,k(n,t.match(kn))+1).join("")):n:n},yn.trimStart=function(n,t,r){return(n=Me(n))?r||t===Z?n.replace(cn,""):(t+="")?(n=n.match(kn),n.slice(O(n,t.match(kn))).join("")):n:n},yn.truncate=function(n,t){var r=30,e="...";if(je(t))var u="separator"in t?t.separator:u,r="length"in t?Be(t.length):r,e="omission"in t?Me(t.omission):e;n=Me(n);var o=n.length;if(En.test(n))var i=n.match(kn),o=i.length;
if(r>=o)return n;if(o=r-F(e),1>o)return e;if(r=i?i.slice(0,o).join(""):n.slice(0,o),u===Z)return r+e;if(i&&(o+=r.length-o),ke(u)){if(n.slice(o).search(u)){var f=r;for(u.global||(u=uu(u.source,Me(hn.exec(u))+"g")),u.lastIndex=0;i=u.exec(f);)var c=i.index;r=r.slice(0,c===Z?o:c)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),u>-1&&(r=r.slice(0,u)));return r+e},yn.unescape=function(n){return(n=Me(n))&&Y.test(n)?n.replace(V,N):n},yn.uniqueId=function(n){var t=++lu;return Me(n)+t},yn.upperCase=li,yn.upperFirst=fi,
yn.each=te,yn.eachRight=re,yn.first=Kr,He(yn,function(){var n={};return pt(yn,function(t,r){au.call(yn.prototype,r)||(n[r]=t)}),n}(),{chain:false}),yn.VERSION="4.4.0",u("bind bindKey curry curryRight partial partialRight".split(" "),function(n){yn[n].placeholder=yn}),u(["drop","take"],function(n,t){An.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new An(this);r=r===Z?1:Cu(Be(r),0);var u=this.clone();return e?u.__takeCount__=Uu(r,u.__takeCount__):u.__views__.push({size:Uu(r,4294967295),
type:n+(0>u.__dir__?"Right":"")}),u},An.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),u(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;An.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:kr(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),u(["head","last"],function(n,t){var r="take"+(t?"Right":"");An.prototype[n]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");
An.prototype[n]=function(){return this.__filtered__?new An(this):this[r](1)}}),An.prototype.compact=function(){return this.filter(Je)},An.prototype.find=function(n){return this.filter(n).head()},An.prototype.findLast=function(n){return this.reverse().find(n)},An.prototype.invokeMap=se(function(n,t){return typeof n=="function"?new An(this):this.map(function(r){return jt(r,n,t)})}),An.prototype.reject=function(n){return n=kr(n,3),this.filter(function(t){return!n(t)})},An.prototype.slice=function(n,t){
n=Be(n);var r=this;return r.__filtered__&&(n>0||0>t)?new An(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==Z&&(t=Be(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},An.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},An.prototype.toArray=function(){return this.take(4294967295)},pt(An.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=yn[e?"take"+("last"==t?"Right":""):t],o=e||/^find/.test(t);u&&(yn.prototype[t]=function(){
function t(n){return n=u.apply(yn,l([n],f)),e&&h?n[0]:n}var i=this.__wrapped__,f=e?[1]:arguments,c=i instanceof An,a=f[0],s=c||Do(i);s&&r&&typeof a=="function"&&1!=a.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,a=o&&!h,c=c&&!p;return!o&&s?(i=c?i:new An(this),i=n.apply(i,f),i.__actions__.push({func:Xr,args:[t],thisArg:Z}),new wn(i,h)):a&&c?n.apply(this,f):(i=this.thru(t),a?e?i.value()[0]:i.value():i)})}),u("pop push shift sort splice unshift".split(" "),function(n){var t=iu[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);
yn.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),pt(An.prototype,function(n,t){var r=yn[t];if(r){var e=r.name+"";(Ju[e]||(Ju[e]=[])).push({name:t,func:r})}}),Ju[pr(Z,2).name]=[{name:"wrapper",func:Z}],An.prototype.clone=function(){var n=new An(this.__wrapped__);return n.__actions__=Xt(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Xt(this.__iteratees__),n.__takeCount__=this.__takeCount__,
n.__views__=Xt(this.__views__),n},An.prototype.reverse=function(){if(this.__filtered__){var n=new An(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},An.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=Do(t),u=0>r,o=e?t.length:0;n=o;for(var i=this.__views__,f=0,c=-1,a=i.length;++c<a;){var l=i[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Uu(n,f+s);break;case"takeRight":f=Cu(f,n-s)}}if(n={start:f,
end:n},i=n.start,f=n.end,n=f-i,u=u?f:i-1,i=this.__iteratees__,f=i.length,c=0,a=Uu(n,this.__takeCount__),!e||200>o||o==n&&a==n)return Kt(t,this.__actions__);e=[];n:for(;n--&&a>c;){for(u+=r,o=-1,l=t[u];++o<f;){var h=i[o],s=h.type,h=(0,h.iteratee)(l);if(2==s)l=h;else if(!h){if(1==s)continue n;break n}}e[c++]=l}return e},yn.prototype.at=Oo,yn.prototype.chain=function(){return Qr(this)},yn.prototype.commit=function(){return new wn(this.value(),this.__chain__)},yn.prototype.flatMap=function(n){return this.map(n).flatten();
},yn.prototype.next=function(){this.__values__===Z&&(this.__values__=We(this.value()));var n=this.__index__>=this.__values__.length,t=n?Z:this.__values__[this.__index__++];return{done:n,value:t}},yn.prototype.plant=function(n){for(var t,r=this;r instanceof mn;){var e=qr(r);e.__index__=0,e.__values__=Z,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},yn.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof An?(this.__actions__.length&&(n=new An(this)),n=n.reverse(),
n.__actions__.push({func:Xr,args:[Jr],thisArg:Z}),new wn(n,this.__chain__)):this.thru(Jr)},yn.prototype.toJSON=yn.prototype.valueOf=yn.prototype.value=function(){return Kt(this.__wrapped__,this.__actions__)},wu&&(yn.prototype[wu]=ne),yn}var Z,q=1/0,P=NaN,T=/\b__p\+='';/g,K=/\b(__p\+=)''\+/g,G=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39|#96);/g,J=/[&<>"'`]/g,Y=RegExp(V.source),H=RegExp(J.source),Q=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,nn=/<%=([\s\S]+?)%>/g,tn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,rn=/^\w*$/,en=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,un=/[\\^$.*+?()[\]{}|]/g,on=RegExp(un.source),fn=/^\s+|\s+$/g,cn=/^\s+/,an=/\s+$/,ln=/\\(\\)?/g,sn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,hn=/\w*$/,pn=/^0x/i,_n=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,vn=/^\[object .+?Constructor\]$/,dn=/^0o[0-7]+$/i,yn=/^(?:0|[1-9]\d*)$/,bn=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,xn=/($^)/,jn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",wn="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,An="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",On=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]","g"),kn=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+An+mn,"g"),En=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),In=/[a-zA-Z0-9]+/g,Sn=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|\\d+",wn].join("|"),"g"),Rn=/[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={};
Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false;
var Cn={};Cn["[object Arguments]"]=Cn["[object Array]"]=Cn["[object ArrayBuffer]"]=Cn["[object Boolean]"]=Cn["[object Date]"]=Cn["[object Float32Array]"]=Cn["[object Float64Array]"]=Cn["[object Int8Array]"]=Cn["[object Int16Array]"]=Cn["[object Int32Array]"]=Cn["[object Map]"]=Cn["[object Number]"]=Cn["[object Object]"]=Cn["[object RegExp]"]=Cn["[object Set]"]=Cn["[object String]"]=Cn["[object Symbol]"]=Cn["[object Uint8Array]"]=Cn["[object Uint8ClampedArray]"]=Cn["[object Uint16Array]"]=Cn["[object Uint32Array]"]=true,
Cn["[object Error]"]=Cn["[object Function]"]=Cn["[object WeakMap]"]=false;var Un={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O",
"\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},zn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Mn={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},Ln={"function":true,object:true},$n={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"
},Fn=parseFloat,Nn=parseInt,Dn=Ln[typeof exports]&&exports&&!exports.nodeType?exports:Z,Zn=Ln[typeof module]&&module&&!module.nodeType?module:Z,qn=Zn&&Zn.exports===Dn?Dn:Z,Pn=E(Ln[typeof self]&&self),Tn=E(Ln[typeof window]&&window),Kn=E(Ln[typeof this]&&this),Gn=E(Dn&&Zn&&typeof global=="object"&&global)||Tn!==(Kn&&Kn.window)&&Tn||Pn||Kn||Function("return this")(),Vn=D();(Tn||Pn||{})._=Vn,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){return Vn}):Dn&&Zn?(qn&&((Zn.exports=Vn)._=Vn),
Dn._=Vn):Gn._=Vn}).call(this);

295
dist/mapping.fp.js vendored
View File

@@ -1,295 +0,0 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["mapping"] = factory();
else
root["mapping"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {
/** Used to map aliases to their real names. */
exports.aliasToReal = {
'__': 'placeholder',
'all': 'some',
'allPass': 'overEvery',
'apply': 'spread',
'assoc': 'set',
'assocPath': 'set',
'compose': 'flowRight',
'contains': 'includes',
'dissoc': 'unset',
'dissocPath': 'unset',
'each': 'forEach',
'eachRight': 'forEachRight',
'equals': 'isEqual',
'extend': 'assignIn',
'extendWith': 'assignInWith',
'first': 'head',
'init': 'initial',
'mapObj': 'mapValues',
'omitAll': 'omit',
'nAry': 'ary',
'path': 'get',
'pathEq': 'matchesProperty',
'pathOr': 'getOr',
'pickAll': 'pick',
'pipe': 'flow',
'prop': 'get',
'propOf': 'propertyOf',
'propOr': 'getOr',
'somePass': 'overSome',
'unapply': 'rest',
'unnest': 'flatten',
'useWith': 'overArgs',
'whereEq': 'filter',
'zipObj': 'zipObject'
};
/** Used to map ary to method names. */
exports.aryMethod = {
'1': [
'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor',
'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin',
'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext',
'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words'
],
'2': [
'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey',
'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every',
'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',
'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn',
'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has',
'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap',
'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map',
'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit',
'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile',
'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd',
'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset',
'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep'
],
'3': [
'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith',
'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace',
'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy',
'unionWith', 'xorBy', 'xorWith', 'zipWith'
],
'4': [
'fill', 'setWith'
]
};
/** Used to map ary to rearg configs. */
exports.aryRearg = {
'2': [1, 0],
'3': [2, 0, 1],
'4': [3, 2, 0, 1]
};
/** Used to map method names to their iteratee ary. */
exports.iterateeAry = {
'assignWith': 2,
'assignInWith': 2,
'cloneDeepWith': 1,
'cloneWith': 1,
'dropRightWhile': 1,
'dropWhile': 1,
'every': 1,
'filter': 1,
'find': 1,
'findIndex': 1,
'findKey': 1,
'findLast': 1,
'findLastIndex': 1,
'findLastKey': 1,
'flatMap': 1,
'forEach': 1,
'forEachRight': 1,
'forIn': 1,
'forInRight': 1,
'forOwn': 1,
'forOwnRight': 1,
'isEqualWith': 2,
'isMatchWith': 2,
'map': 1,
'mapKeys': 1,
'mapValues': 1,
'partition': 1,
'reduce': 2,
'reduceRight': 2,
'reject': 1,
'remove': 1,
'some': 1,
'takeRightWhile': 1,
'takeWhile': 1,
'times': 1,
'transform': 2
};
/** Used to map method names to rearg configs. */
exports.methodRearg = {
'assignInWith': [1, 2, 0],
'assignWith': [1, 2, 0],
'getOr': [2, 1, 0],
'isMatchWith': [2, 1, 0],
'mergeWith': [1, 2, 0],
'pullAllBy': [2, 1, 0],
'setWith': [3, 1, 2, 0],
'sortedIndexBy': [2, 1, 0],
'sortedLastIndexBy': [2, 1, 0],
'zipWith': [1, 2, 0]
};
/** Used to map method names to spread configs. */
exports.methodSpread = {
'partial': 1,
'partialRight': 1
};
/** Used to identify methods which mutate arrays or objects. */
exports.mutate = {
'array': {
'fill': true,
'pull': true,
'pullAll': true,
'pullAllBy': true,
'pullAt': true,
'remove': true,
'reverse': true
},
'object': {
'assign': true,
'assignIn': true,
'assignInWith': true,
'assignWith': true,
'defaults': true,
'defaultsDeep': true,
'merge': true,
'mergeWith': true
},
'set': {
'set': true,
'setWith': true,
'unset': true
}
};
/** Used to track methods with placeholder support */
exports.placeholder = {
'bind': true,
'bindKey': true,
'curry': true,
'curryRight': true,
'partial': true,
'partialRight': true
};
/** Used to map real names to their aliases. */
exports.realToAlias = (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
object = exports.aliasToReal,
result = {};
for (var key in object) {
var value = object[key];
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {
result[value] = [key];
}
}
return result;
}());
/** Used to map method names to other names. */
exports.remap = {
'curryN': 'curry',
'curryRightN': 'curryRight',
'getOr': 'get',
'trimChars': 'trim',
'trimCharsEnd': 'trimEnd',
'trimCharsStart': 'trimStart'
};
/** Used to track methods that skip `_.rearg`. */
exports.skipRearg = {
'add': true,
'assign': true,
'assignIn': true,
'concat': true,
'difference': true,
'gt': true,
'gte': true,
'lt': true,
'lte': true,
'matchesProperty': true,
'merge': true,
'partial': true,
'partialRight': true,
'random': true,
'range': true,
'rangeRight': true,
'subtract': true,
'zip': true,
'zipObject': true
};
/***/ }
/******/ ])
});
;

File diff suppressed because it is too large Load Diff

View File

@@ -1,284 +0,0 @@
var mapping = require('./_mapping'),
mutateMap = mapping.mutate,
placeholder = {};
/**
* The base implementation of `convert` which accepts a `util` object of methods
* required to perform conversions.
*
* @param {Object} util The util object.
* @param {string} name The name of the function to wrap.
* @param {Function} func The function to wrap.
* @param {Object} [options] The options object.
* @param {boolean} [options.cap=true] Specify capping iteratee arguments.
* @param {boolean} [options.curry=true] Specify currying.
* @param {boolean} [options.fixed=true] Specify fixed arity.
* @param {boolean} [options.immutable=true] Specify immutable operations.
* @param {boolean} [options.rearg=true] Specify rearranging arguments.
* @returns {Function|Object} Returns the converted function or object.
*/
function baseConvert(util, name, func, options) {
var setPlaceholder,
isLib = typeof name == 'function',
isObj = name === Object(name);
if (isObj) {
options = func;
func = name;
name = undefined;
}
if (func == null) {
throw new TypeError;
}
options || (options = {});
var config = {
'cap': 'cap' in options ? options.cap : true,
'curry': 'curry' in options ? options.curry : true,
'fixed': 'fixed' in options ? options.fixed : true,
'immutable': 'immutable' in options ? options.immutable : true,
'rearg': 'rearg' in options ? options.rearg : true
};
var forceRearg = ('rearg' in options) && options.rearg;
var helpers = isLib ? func : {
'ary': util.ary,
'cloneDeep': util.cloneDeep,
'curry': util.curry,
'forEach': util.forEach,
'isArray': util.isArray,
'isFunction': util.isFunction,
'iteratee': util.iteratee,
'keys': util.keys,
'rearg': util.rearg,
'spread': util.spread
};
var ary = helpers.ary,
cloneDeep = helpers.cloneDeep,
curry = helpers.curry,
each = helpers.forEach,
isArray = helpers.isArray,
isFunction = helpers.isFunction,
keys = helpers.keys,
rearg = helpers.rearg,
spread = helpers.spread;
var aryMethodKeys = keys(mapping.aryMethod);
var baseArity = function(func, n) {
return n == 2
? function(a, b) { return func.apply(undefined, arguments); }
: function(a) { return func.apply(undefined, arguments); };
};
var baseAry = function(func, n) {
return n == 2
? function(a, b) { return func(a, b); }
: function(a) { return func(a); };
};
var cloneArray = function(array) {
var length = array ? array.length : 0,
result = Array(length);
while (length--) {
result[length] = array[length];
}
return result;
};
var createCloner = function(func) {
return function(object) {
return func({}, object);
};
};
var immutWrap = function(func, cloner) {
return function() {
var length = arguments.length;
if (!length) {
return result;
}
var args = Array(length);
while (length--) {
args[length] = arguments[length];
}
var result = args[0] = cloner(args[0]);
func.apply(undefined, args);
return result;
};
};
var iterateeAry = function(func, n) {
return overArg(func, function(func) {
return baseAry(func, n);
});
};
var overArg = function(func, iteratee, retArg) {
return function() {
var length = arguments.length;
if (!length) {
return func();
}
var args = Array(length);
while (length--) {
args[length] = arguments[length];
}
var index = config.rearg ? 0 : (length - 1);
args[index] = iteratee(args[index]);
return func.apply(undefined, args);
};
};
var wrappers = {
'castArray': function(castArray) {
return function() {
var value = arguments[0];
return isArray(value)
? castArray(cloneArray(value))
: castArray.apply(undefined, arguments);
};
},
'iteratee': function(iteratee) {
return function() {
var func = arguments[0],
arity = arguments[1];
if (!config.cap) {
return iteratee(func, arity);
}
arity = arity > 2 ? (arity - 2) : 1;
func = iteratee(func);
var length = func.length;
return (length && length <= arity) ? func : baseAry(func, arity);
};
},
'mixin': function(mixin) {
return function(source) {
var func = this;
if (!isFunction(func)) {
return mixin(func, Object(source));
}
var methods = [],
methodNames = [];
each(keys(source), function(key) {
var value = source[key];
if (isFunction(value)) {
methodNames.push(key);
methods.push(func.prototype[key]);
}
});
mixin(func, Object(source));
each(methodNames, function(methodName, index) {
var method = methods[index];
if (isFunction(method)) {
func.prototype[methodName] = method;
} else {
delete func.prototype[methodName];
}
});
return func;
};
},
'runInContext': function(runInContext) {
return function(context) {
return baseConvert(util, runInContext(context), options);
};
}
};
var wrap = function(name, func) {
name = mapping.aliasToReal[name] || name;
var wrapper = wrappers[name];
if (wrapper) {
return wrapper(func);
}
var wrapped = func;
if (config.immutable) {
if (mutateMap.array[name]) {
wrapped = immutWrap(func, cloneArray);
}
else if (mutateMap.object[name]) {
wrapped = immutWrap(func, createCloner(func));
}
else if (mutateMap.set[name]) {
wrapped = immutWrap(func, cloneDeep);
}
}
var result;
each(aryMethodKeys, function(aryKey) {
each(mapping.aryMethod[aryKey], function(otherName) {
if (name == otherName) {
var aryN = !isLib && mapping.iterateeAry[name],
spreadStart = mapping.methodSpread[name];
result = wrapped;
if (config.fixed) {
result = spreadStart === undefined
? ary(result, aryKey)
: spread(result, spreadStart);
}
if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
}
if (config.cap && aryN) {
result = iterateeAry(result, aryN);
}
if (config.curry && aryKey > 1) {
result = curry(result, aryKey);
}
return false;
}
});
return !result;
});
result || (result = wrapped);
if (mapping.placeholder[name]) {
setPlaceholder = true;
func.placeholder = result.placeholder = placeholder;
}
return result;
};
if (!isObj) {
return wrap(name, func);
}
var _ = func;
// Iterate over methods for the current ary cap.
var pairs = [];
each(aryMethodKeys, function(aryKey) {
each(mapping.aryMethod[aryKey], function(key) {
var func = _[mapping.remap[key] || key];
if (func) {
pairs.push([key, wrap(key, func)]);
}
});
});
// Assign to `_` leaving `_.prototype` unchanged to allow chaining.
each(pairs, function(pair) {
_[pair[0]] = pair[1];
});
if (setPlaceholder) {
_.placeholder = placeholder;
}
// Wrap the lodash method and its aliases.
each(keys(_), function(key) {
each(mapping.realToAlias[key] || [], function(alias) {
_[alias] = _[key];
});
});
return _;
}
module.exports = baseConvert;

View File

@@ -1,17 +0,0 @@
var baseConvert = require('./_baseConvert');
/**
* Converts `lodash` to an immutable auto-curried iteratee-first data-last version.
*
* @param {Function} lodash The lodash function.
* @param {Object} [options] The options object. See `baseConvert` for more details.
* @returns {Function} Returns the converted `lodash`.
*/
function browserConvert(lodash, options) {
return baseConvert(lodash, lodash, options);
}
if (typeof _ == 'function') {
_ = browserConvert(_.runInContext());
}
module.exports = browserConvert;

View File

@@ -1,233 +0,0 @@
/** Used to map aliases to their real names. */
exports.aliasToReal = {
'__': 'placeholder',
'all': 'some',
'allPass': 'overEvery',
'apply': 'spread',
'assoc': 'set',
'assocPath': 'set',
'compose': 'flowRight',
'contains': 'includes',
'dissoc': 'unset',
'dissocPath': 'unset',
'each': 'forEach',
'eachRight': 'forEachRight',
'equals': 'isEqual',
'extend': 'assignIn',
'extendWith': 'assignInWith',
'first': 'head',
'init': 'initial',
'mapObj': 'mapValues',
'omitAll': 'omit',
'nAry': 'ary',
'path': 'get',
'pathEq': 'matchesProperty',
'pathOr': 'getOr',
'pickAll': 'pick',
'pipe': 'flow',
'prop': 'get',
'propOf': 'propertyOf',
'propOr': 'getOr',
'somePass': 'overSome',
'unapply': 'rest',
'unnest': 'flatten',
'useWith': 'overArgs',
'whereEq': 'filter',
'zipObj': 'zipObject'
};
/** Used to map ary to method names. */
exports.aryMethod = {
'1': [
'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor',
'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin',
'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext',
'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words'
],
'2': [
'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey',
'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every',
'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',
'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn',
'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has',
'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap',
'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map',
'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit',
'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile',
'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd',
'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset',
'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep'
],
'3': [
'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith',
'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace',
'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy',
'unionWith', 'xorBy', 'xorWith', 'zipWith'
],
'4': [
'fill', 'setWith'
]
};
/** Used to map ary to rearg configs. */
exports.aryRearg = {
'2': [1, 0],
'3': [2, 0, 1],
'4': [3, 2, 0, 1]
};
/** Used to map method names to their iteratee ary. */
exports.iterateeAry = {
'assignWith': 2,
'assignInWith': 2,
'cloneDeepWith': 1,
'cloneWith': 1,
'dropRightWhile': 1,
'dropWhile': 1,
'every': 1,
'filter': 1,
'find': 1,
'findIndex': 1,
'findKey': 1,
'findLast': 1,
'findLastIndex': 1,
'findLastKey': 1,
'flatMap': 1,
'forEach': 1,
'forEachRight': 1,
'forIn': 1,
'forInRight': 1,
'forOwn': 1,
'forOwnRight': 1,
'isEqualWith': 2,
'isMatchWith': 2,
'map': 1,
'mapKeys': 1,
'mapValues': 1,
'partition': 1,
'reduce': 2,
'reduceRight': 2,
'reject': 1,
'remove': 1,
'some': 1,
'takeRightWhile': 1,
'takeWhile': 1,
'times': 1,
'transform': 2
};
/** Used to map method names to rearg configs. */
exports.methodRearg = {
'assignInWith': [1, 2, 0],
'assignWith': [1, 2, 0],
'getOr': [2, 1, 0],
'isMatchWith': [2, 1, 0],
'mergeWith': [1, 2, 0],
'pullAllBy': [2, 1, 0],
'setWith': [3, 1, 2, 0],
'sortedIndexBy': [2, 1, 0],
'sortedLastIndexBy': [2, 1, 0],
'zipWith': [1, 2, 0]
};
/** Used to map method names to spread configs. */
exports.methodSpread = {
'partial': 1,
'partialRight': 1
};
/** Used to identify methods which mutate arrays or objects. */
exports.mutate = {
'array': {
'fill': true,
'pull': true,
'pullAll': true,
'pullAllBy': true,
'pullAt': true,
'remove': true,
'reverse': true
},
'object': {
'assign': true,
'assignIn': true,
'assignInWith': true,
'assignWith': true,
'defaults': true,
'defaultsDeep': true,
'merge': true,
'mergeWith': true
},
'set': {
'set': true,
'setWith': true,
'unset': true
}
};
/** Used to track methods with placeholder support */
exports.placeholder = {
'bind': true,
'bindKey': true,
'curry': true,
'curryRight': true,
'partial': true,
'partialRight': true
};
/** Used to map real names to their aliases. */
exports.realToAlias = (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
object = exports.aliasToReal,
result = {};
for (var key in object) {
var value = object[key];
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {
result[value] = [key];
}
}
return result;
}());
/** Used to map method names to other names. */
exports.remap = {
'curryN': 'curry',
'curryRightN': 'curryRight',
'getOr': 'get',
'trimChars': 'trim',
'trimCharsEnd': 'trimEnd',
'trimCharsStart': 'trimStart'
};
/** Used to track methods that skip `_.rearg`. */
exports.skipRearg = {
'add': true,
'assign': true,
'assignIn': true,
'concat': true,
'difference': true,
'gt': true,
'gte': true,
'lt': true,
'lte': true,
'matchesProperty': true,
'merge': true,
'partial': true,
'partialRight': true,
'random': true,
'range': true,
'rangeRight': true,
'subtract': true,
'zip': true,
'zipObject': true
};

View File

@@ -1,26 +0,0 @@
'use strict';
var _ = require('lodash'),
fs = require('fs-extra'),
uglify = require('uglify-js');
var uglifyOptions = require('./uglify.options.js');
/*----------------------------------------------------------------------------*/
function minify(inpath, outpath, callback, options) {
if (_.isFunction(outpath)) {
if (_.isObject(callback)) {
options = callback;
}
callback = outpath;
outpath = undefined;
}
if (!outpath) {
outpath = inpath.replace(/(?=\.js$)/, '.min');
}
var output = uglify.minify(inpath, _.defaults(options || {}, uglifyOptions));
fs.writeFile(outpath, output.code, 'utf-8', callback);
}
module.exports = minify;

View File

@@ -1,16 +0,0 @@
module.exports = {
'compress': {
'pure_getters': true,
'unsafe': true,
'unsafe_comps': true,
'warnings': false
},
'mangle': {
'except': ['define']
},
'output': {
'ascii_only': true,
'comments': /^!|@cc_on|@license|@preserve/i,
'max_line_len': 500
}
};

View File

@@ -1,18 +0,0 @@
'use strict';
var _ = require('lodash'),
fs = require('fs-extra'),
glob = require('glob'),
path = require('path');
/*----------------------------------------------------------------------------*/
function globTemplate(pattern) {
return _.transform(glob.sync(pattern), function(result, filePath) {
result[path.basename(filePath, path.extname(filePath))] = _.template(fs.readFileSync(filePath));
}, {});
}
module.exports = {
'globTemplate': globTemplate
};

View File

@@ -1,55 +0,0 @@
'use strict';
var _ = require('lodash'),
async = require('async'),
path = require('path'),
webpack = require('webpack');
var minify = require('../common/minify.js');
var basePath = path.join(__dirname, '..', '..'),
distPath = path.join(basePath, 'dist'),
fpPath = path.join(basePath, 'fp'),
filename = 'lodash.fp.js';
var fpConfig = {
'entry': path.join(fpPath, '_convertBrowser.js'),
'output': {
'path': distPath,
'filename': filename,
'library': 'fp',
'libraryTarget': 'umd'
},
'plugins': [
new webpack.optimize.OccurenceOrderPlugin,
new webpack.optimize.DedupePlugin
]
};
var mappingConfig = {
'entry': path.join(fpPath, '_mapping.js'),
'output': {
'path': distPath,
'filename': 'mapping.fp.js',
'library': 'mapping',
'libraryTarget': 'umd'
}
};
/*----------------------------------------------------------------------------*/
function onComplete(error) {
if (error) {
throw error;
}
}
function build() {
async.series([
_.partial(webpack, mappingConfig),
_.partial(webpack, fpConfig),
_.partial(minify, path.join(distPath, filename))
], onComplete);
}
build();

View File

@@ -1,62 +0,0 @@
'use strict';
var _ = require('lodash'),
fs = require('fs-extra'),
path = require('path'),
util = require('../common/util');
var mapping = require('../../fp/_mapping'),
templatePath = path.join(__dirname, 'template/doc'),
template = util.globTemplate(path.join(templatePath, '*.jst'));
var argNames = ['a', 'b', 'c', 'd'];
var templateData = {
'mapping': mapping,
'toArgOrder': toArgOrder,
'toFuncList': toFuncList
};
function toArgOrder(array) {
return '`(' + _.map(array, function(value) {
return argNames[value];
}).join(', ') + ')`';
}
function toFuncList(array) {
var chunks = _.chunk(array.slice().sort(), 5),
lastChunk = _.last(chunks),
last = lastChunk ? lastChunk.pop() : undefined;
chunks = _.reject(chunks, _.isEmpty);
lastChunk = _.last(chunks);
var result = '`' + _.map(chunks, function(chunk) {
return chunk.join('`, `') + '`';
}).join(',\n`');
if (last == null) {
return result;
}
if (_.size(chunks) > 1 || _.size(lastChunk) > 1) {
result += ',';
}
result += ' &';
result += _.size(lastChunk) < 5 ? ' ' : '\n';
return result + '`' + last + '`';
}
/*----------------------------------------------------------------------------*/
function onComplete(error) {
if (error) {
throw error;
}
}
function build(target) {
target = path.resolve(target);
fs.writeFile(target, template.wiki(templateData), onComplete);
}
build(_.last(process.argv));

View File

@@ -1,126 +0,0 @@
'use strict';
var _ = require('lodash'),
async = require('async'),
fs = require('fs-extra'),
glob = require('glob'),
path = require('path'),
util = require('../common/util');
var mapping = require('../../fp/_mapping'),
templatePath = path.join(__dirname, 'template/modules'),
template = util.globTemplate(path.join(templatePath, '*.jst'));
var aryMethods = _.union(
mapping.aryMethod[1],
mapping.aryMethod[2],
mapping.aryMethod[3],
mapping.aryMethod[4]
);
var categories = [
'array',
'collection',
'date',
'function',
'lang',
'math',
'number',
'object',
'seq',
'string',
'util'
];
var ignored = [
'_*.js',
'core.js',
'fp.js',
'index.js',
'lodash.js'
];
function copyFile(srcPath, destPath) {
return _.partial(fs.copy, srcPath, destPath);
}
function isAlias(funcName) {
return _.has(mapping.aliasToReal, funcName);
}
function isCategory(funcName) {
return _.includes(categories, funcName);
}
function isThru(funcName) {
return !_.includes(aryMethods, funcName);
}
function getTemplate(moduleName) {
var data = {
'name': _.result(mapping.aliasToReal, moduleName, moduleName),
'mapping': mapping
};
if (isAlias(moduleName)) {
return template.alias(data);
}
if (isCategory(moduleName)) {
return template.category(data);
}
if (isThru(moduleName)) {
return template.thru(data);
}
return template.module(data);
}
function writeFile(filePath, data) {
return _.partial(fs.writeFile, filePath, data);
}
/*----------------------------------------------------------------------------*/
function onComplete(error) {
if (error) {
throw error;
}
}
function build(target) {
target = path.resolve(target);
var fpPath = path.join(target, 'fp');
// Glob existing lodash module paths.
var modulePaths = glob.sync(path.join(target, '*.js'), {
'nodir': true,
'ignore': ignored.map(function(filename) {
return path.join(target, filename);
})
});
// Add FP alias and remapped module paths.
_.each([mapping.aliasToReal, mapping.remap], function(data) {
_.forOwn(data, function(realName, alias) {
var modulePath = path.join(target, alias + '.js');
if (!_.startsWith(alias, '_') &&
!_.includes(modulePaths, modulePath)) {
modulePaths.push(modulePath);
}
});
});
var actions = modulePaths.map(function(modulePath) {
var moduleName = path.basename(modulePath, '.js');
return writeFile(path.join(fpPath, moduleName + '.js'), getTemplate(moduleName));
});
actions.unshift(copyFile(path.join(__dirname, '../../fp'), fpPath));
actions.push(writeFile(path.join(target, 'fp.js'), template.fp()));
actions.push(writeFile(path.join(fpPath, 'convert.js'), template.convert()));
actions.push(writeFile(path.join(fpPath, '_util.js'), template._util()));
async.series(actions, onComplete);
}
build(_.last(process.argv));

View File

@@ -1,127 +0,0 @@
## lodash/fp
The `lodash/fp` module is an instance of `lodash` with its methods wrapped to
produce immutable auto-curried iteratee-first data-last methods.
## Installation
In a browser:
```html
<script src='path/to/lodash.js'></script>
<script src='path/to/lodash.fp.js'></script>
```
In Node.js:
```js
// Load the fp build.
var _ = require('lodash/fp');
// Load a method category.
var object = require('lodash/fp/object');
// Load a single method for smaller builds with browserify/rollup/webpack.
var extend = require('lodash/fp/extend');
```
## Convert
This module is used to convert Lodash methods to their `fp` counterparts.
```js
var convert = require('lodash/fp/convert');
// Convert by name.
var assign = convert('assign', require('lodash.assign'));
// Convert by object.
var fp = convert({
'assign': require('lodash.assign'),
'chunk': require('lodash.chunk')
});
// Convert by `lodash` instance.
var fp = convert(lodash.runInContext());
```
Its even customizable so you can create the `fp` function thats right for you.
```js
// Every option is `true` by default.
var filter = convert('filter', _.filter, {
// Specify capping iteratee arguments.
'cap': true,
// Specify currying.
'curry': true,
// Specify fixed arity.
'fixed': true,
// Specify immutable operations.
'immutable': true,
// Specify rearranging arguments.
'rearg': true
});
// Specify `cap` of `false` to create a function that doesnt cap iteratee arguments.
var filter = convert('filter', _.filter, { 'cap': false });
filter(function(value, index) {
return index % 2 == 0;
})(['a', 'b', 'c']);
// => ['a', 'c']
```
## Mapping
Immutable auto-curried iteratee-first data-last methods sound great, but whats
that really mean for each method? Below is a breakdown of the mapping used to
convert each method.
#### Capped Iteratee Arguments
Methods which provide iteratees one argument:<br>
<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 1)))) %>
Methods which provide iteratees two arguments:<br>
<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 2)))) %>
#### Fixed Arity
Methods with arity fixed to one argument:<br>
<%= toFuncList(mapping.aryMethod[1]) %>
Methods with arity fixed to two arguments:<br>
<%= toFuncList(mapping.aryMethod[2]) %>
Methods with arity fixed to three arguments:<br>
<%= toFuncList(mapping.aryMethod[3]) %>
Methods with arity fixed to four arguments:<br>
<%= toFuncList(mapping.aryMethod[4]) %>
#### Rearranged Arguments
Methods fixed to two arguments have an argument order of<br>
<%= toArgOrder(mapping.aryRearg[2]) %>
Methods fixed to three arguments have an argument order of<br>
<%= toArgOrder(mapping.aryRearg[3]) %>
Methods fixed to four arguments have an argument order of<br>
<%= toArgOrder(mapping.aryRearg[4]) %>
Methods with custom argument orders:<br>
<%= _.map(mapping.methodRearg, function(orders, methodName) {
return ' * `_.' + methodName + '` has an order of ' + toArgOrder(orders);
}).join('\n') %>
Methods with unchanged argument orders:<br>
<%= toFuncList(_.keys(mapping.skipRearg)) %>
#### New Methods
Methods created to accommodate Lodashs variadic methods:<br>
<%= toFuncList(_.keys(mapping.remap)) %>
#### Aliases
There are <%= _.size(mapping.aliasToReal) %> method aliases:<br>
<%= _.map(mapping.aliasToReal, function(realName, alias) {
return ' * Added `_.' + alias + '` as an alias of `_.' + realName + '`';
}).join('\n') %>

View File

@@ -1,12 +0,0 @@
module.exports = {
'ary': require('../ary'),
'cloneDeep': require('../cloneDeep'),
'curry': require('../curry'),
'forEach': require('../_arrayEach'),
'isArray': require('../isArray'),
'isFunction': require('../isFunction'),
'iteratee': require('../iteratee'),
'keys': require('../_baseKeys'),
'rearg': require('../rearg'),
'spread': require('../spread')
};

View File

@@ -1 +0,0 @@
module.exports = require('./<%= name %>');

View File

@@ -1,2 +0,0 @@
var convert = require('./convert');
module.exports = convert(require('../<%= name %>'));

View File

@@ -1,17 +0,0 @@
var baseConvert = require('./_baseConvert'),
util = require('./_util');
/**
* Converts `func` of `name` to an immutable auto-curried iteratee-first data-last
* version. If `name` is an object its methods will be converted.
*
* @param {string} name The name of the function to wrap.
* @param {Function} [func] The function to wrap.
* @param {Object} [options] The options object. See `baseConvert` for more details.
* @returns {Function|Object} Returns the converted function or object.
*/
function convert(name, func, options) {
return baseConvert(util, name, func, options);
}
module.exports = convert;

View File

@@ -1,2 +0,0 @@
var _ = require('./lodash').runInContext();
module.exports = require('./fp/convert')(_);

View File

@@ -1,2 +0,0 @@
var convert = require('./convert');
module.exports = convert('<%= name %>', require('../<%= _.result(mapping.remap, name, name) %>'));

View File

@@ -1 +0,0 @@
module.exports = require('../<%= name %>');

View File

@@ -1,32 +0,0 @@
'use strict';
var _ = require('lodash'),
async = require('async'),
fs = require('fs-extra'),
path = require('path');
var minify = require('../common/minify.js');
var basePath = path.join(__dirname, '..', '..'),
distPath = path.join(basePath, 'dist'),
filename = 'lodash.js';
var baseLodash = path.join(basePath, filename),
distLodash = path.join(distPath, filename);
/*----------------------------------------------------------------------------*/
function onComplete(error) {
if (error) {
throw error;
}
}
function build() {
async.series([
_.partial(fs.copy, baseLodash, distLodash),
_.partial(minify, distLodash)
], onComplete);
}
build();

View File

@@ -1,55 +0,0 @@
'use strict';
var _ = require('lodash'),
docdown = require('docdown'),
fs = require('fs-extra'),
path = require('path');
var basePath = path.join(__dirname, '..', '..'),
docPath = path.join(basePath, 'doc'),
readmePath = path.join(docPath, 'README.md');
var pkg = require('../../package.json'),
version = pkg.version;
var config = {
'base': {
'entryLinks': [
'<% if (name == "templateSettings" || !/^(?:methods|properties|seq)$/i.test(category)) {' +
'print("[&#x24C3;](https://www.npmjs.com/package/lodash." + name.toLowerCase() + " \\"See the npm package\\")")' +
'} %>'
],
'path': path.join(basePath, 'lodash.js'),
'title': '<a href="https://lodash.com/">lodash</a> <span>v' + version + '</span>',
'toc': 'categories',
'url': 'https://github.com/lodash/lodash/blob/' + version + '/lodash.js'
},
'github': {
'hash': 'github'
},
'site': {
'tocLink': '#docs'
}
};
function postprocess(string) {
// Fix docdown bug by wrapping symbol property identifiers in brackets.
return string.replace(/\.(Symbol\.(?:[a-z]+[A-Z]?)+)/g, '[$1]');
}
/*----------------------------------------------------------------------------*/
function onComplete(error) {
if (error) {
throw error;
}
}
function build(type) {
var options = _.defaults({}, config.base, config[type]),
markdown = docdown(options);
fs.writeFile(readmePath, postprocess(markdown), onComplete);
}
build(_.last(process.argv));

View File

@@ -1,23 +0,0 @@
'use strict';
var _ = require('lodash'),
fs = require('fs-extra'),
path = require('path');
var basePath = path.join(__dirname, '..', '..'),
distPath = path.join(basePath, 'dist'),
corePath = path.join(distPath, 'lodash.core.js');
/*----------------------------------------------------------------------------*/
function onComplete(error) {
if (error) {
throw error;
}
}
function build(target) {
fs.copy(corePath, path.join(target, 'core.js'), onComplete);
}
build(_.last(process.argv));

12062
lodash.js

File diff suppressed because it is too large Load Diff

99
lodash.min.js vendored Normal file
View File

@@ -0,0 +1,99 @@
/**
* @license
* lodash 3.10.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
* Build: `lodash modern -o ./lodash.js`
*/
;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===w,u=n===n,o=null===t,i=t===w,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)return 1;if(n<t&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return null==n?"":n+""}function o(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););
return r}function i(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function f(t,r){return n(t.a,r.a)||t.b-r.b}function a(n){return Nn[n]}function c(n){return Tn[n]}function l(n,t,r){return t?n=Bn[n]:r&&(n=Dn[n]),"\\"+n}function s(n){return"\\"+Dn[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&typeof n=="object"}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=z,o[++u]=r);return o}function g(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return Ln[n]}function m(_){function Nn(n){if(h(n)&&!(Oo(n)||n instanceof zn)){if(n instanceof Ln)return n;if(nu.call(n,"__chain__")&&nu.call(n,"__wrapped__"))return Mr(n)}return new Ln(n)}function Tn(){}function Ln(n,t,r){this.__wrapped__=n,this.__actions__=r||[],
this.__chain__=!!t}function zn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=Ru,this.__views__=[]}function Bn(){this.__data__={}}function Dn(n){var t=n?n.length:0;for(this.data={hash:gu(null),set:new lu};t--;)this.push(n[t])}function Mn(n,t){var r=n.data;return(typeof t=="string"||ge(t)?r.set.has(t):r.hash[t])?0:-1}function qn(n,t){var r=-1,e=n.length;for(t||(t=Be(e));++r<e;)t[r]=n[r];return t}function Pn(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););
return n}function Kn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Vn(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function Gn(n,t){for(var r=-1,e=n.length,u=Be(e);++r<e;)u[r]=t(n[r],r,n);return u}function Jn(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function Xn(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function Hn(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;
return false}function Qn(n,t,r,e){return n!==w&&nu.call(e,r)?n:t}function nt(n,t,r){for(var e=-1,u=zo(t),o=u.length;++e<o;){var i=u[e],f=n[i],a=r(f,t[i],i,n,t);(a===a?a===f:f!==f)&&(f!==w||i in n)||(n[i]=a)}return n}function tt(n,t){return null==t?n:et(t,zo(t),n)}function rt(n,t){for(var r=-1,e=null==n,u=!e&&Er(n),o=u?n.length:0,i=t.length,f=Be(i);++r<i;){var a=t[r];f[r]=u?Cr(a,o)?n[a]:w:e?w:n[a]}return f}function et(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var o=t[e];r[o]=n[o]}return r}function ut(n,t,r){
var e=typeof n;return"function"==e?t===w?n:Bt(n,t,r):null==n?Fe:"object"==e?bt(n):t===w?ze(n):xt(n,t)}function ot(n,t,r,e,u,o,i){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==w)return f;if(!ge(n))return n;if(e=Oo(n)){if(f=kr(n),!t)return qn(n,f)}else{var a=ru.call(n),c=a==K;if(a!=Z&&a!=B&&(!c||u))return Fn[a]?Rr(n,a,t):u?n:{};if(f=Ir(c?{}:n),!t)return tt(f,n)}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?Pn:_t)(n,function(e,u){f[u]=ot(e,t,r,u,n,o,i)}),f}function it(n,t,r){
if(typeof n!="function")throw new Ge(L);return su(function(){n.apply(w,r)},t)}function ft(n,t){var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=xr(),f=i==r,a=f&&t.length>=F&&gu&&lu?new Dn(t):null,c=t.length;a&&(i=Mn,f=false,t=a);n:for(;++o<e;)if(a=n[o],f&&a===a){for(var l=c;l--;)if(t[l]===a)continue n;u.push(a)}else 0>i(t,a,0)&&u.push(a);return u}function at(n,t){var r=true;return Su(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t,r,e){var u=e,o=u;return Su(n,function(n,i,f){i=+t(n,i,f),(r(i,u)||i===e&&i===o)&&(u=i,
o=n)}),o}function lt(n,t){var r=[];return Su(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function st(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function pt(n,t,r,e){e||(e=[]);for(var u=-1,o=n.length;++u<o;){var i=n[u];h(i)&&Er(i)&&(r||Oo(i)||pe(i))?t?pt(i,t,r,e):Jn(e,i):r||(e[e.length]=i)}return e}function ht(n,t){Nu(n,t,Re)}function _t(n,t){return Nu(n,t,zo)}function vt(n,t){return Tu(n,t,zo)}function gt(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){var i=t[r];
ve(n[i])&&(o[++u]=i)}return o}function yt(n,t,r){if(null!=n){r!==w&&r in Br(n)&&(t=[r]),r=0;for(var e=t.length;null!=n&&r<e;)n=n[t[r++]];return r&&r==e?n:w}}function dt(n,t,r,e,u,o){if(n===t)n=true;else if(null==n||null==t||!ge(n)&&!h(t))n=n!==n&&t!==t;else n:{var i=dt,f=Oo(n),a=Oo(t),c=D,l=D;f||(c=ru.call(n),c==B?c=Z:c!=Z&&(f=xe(n))),a||(l=ru.call(t),l==B?l=Z:l!=Z&&xe(t));var s=c==Z,a=l==Z,l=c==l;if(!l||f||s){if(!e&&(c=s&&nu.call(n,"__wrapped__"),a=a&&nu.call(t,"__wrapped__"),c||a)){n=i(c?n.value():n,a?t.value():t,r,e,u,o);
break n}if(l){for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n){n=o[c]==t;break n}u.push(n),o.push(t),n=(f?yr:mr)(n,t,i,r,e,u,o),u.pop(),o.pop()}else n=false}else n=dr(n,t,c)}return n}function mt(n,t,r){var e=t.length,u=e,o=!r;if(null==n)return!u;for(n=Br(n);e--;){var i=t[e];if(o&&i[2]?i[1]!==n[i[0]]:!(i[0]in n))return false}for(;++e<u;){var i=t[e],f=i[0],a=n[f],c=i[1];if(o&&i[2]){if(a===w&&!(f in n))return false}else if(i=r?r(a,c,f):w,i===w?!dt(c,a,r,true):!i)return false}return true}function wt(n,t){var r=-1,e=Er(n)?Be(n.length):[];
return Su(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function bt(n){var t=Ar(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null==n?false:n[r]===e&&(e!==w||r in Br(n))}}return function(n){return mt(n,t)}}function xt(n,t){var r=Oo(n),e=Wr(n)&&t===t&&!ge(t),u=n+"";return n=Dr(n),function(o){if(null==o)return false;var i=u;if(o=Br(o),!(!r&&e||i in o)){if(o=1==n.length?o:yt(o,Et(n,0,-1)),null==o)return false;i=Zr(n),o=Br(o)}return o[i]===t?t!==w||i in o:dt(t,o[i],w,true)}}function At(n,t,r,e,u){
if(!ge(n))return n;var o=Er(t)&&(Oo(t)||xe(t)),i=o?w:zo(t);return Pn(i||t,function(f,a){if(i&&(a=f,f=t[a]),h(f)){e||(e=[]),u||(u=[]);n:{for(var c=a,l=e,s=u,p=l.length,_=t[c];p--;)if(l[p]==_){n[c]=s[p];break n}var p=n[c],v=r?r(p,_,c,n,t):w,g=v===w;g&&(v=_,Er(_)&&(Oo(_)||xe(_))?v=Oo(p)?p:Er(p)?qn(p):[]:me(_)||pe(_)?v=pe(p)?ke(p):me(p)?p:{}:g=false),l.push(_),s.push(v),g?n[c]=At(v,_,r,l,s):(v===v?v!==p:p===p)&&(n[c]=v)}}else c=n[a],l=r?r(c,f,a,n,t):w,(s=l===w)&&(l=f),l===w&&(!o||a in n)||!s&&(l===l?l===c:c!==c)||(n[a]=l);
}),n}function jt(n){return function(t){return null==t?w:t[n]}}function kt(n){var t=n+"";return n=Dr(n),function(r){return yt(r,n,t)}}function It(n,t){for(var r=n?t.length:0;r--;){var e=t[r];if(e!=u&&Cr(e)){var u=e;pu.call(n,e,1)}}}function Rt(n,t){return n+yu(ku()*(t-n+1))}function Ot(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function Et(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Be(u);++e<u;)r[e]=n[e+t];
return r}function Ct(n,t){var r;return Su(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function Ut(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Wt(t,r,e){var u=wr(),o=-1;return r=Gn(r,function(n){return u(n)}),t=wt(t,function(n){return{a:Gn(r,function(t){return t(n)}),b:++o,c:n}}),Ut(t,function(t,r){var u;n:{for(var o=-1,i=t.a,f=r.a,a=i.length,c=e.length;++o<a;)if(u=n(i[o],f[o])){if(o>=c)break n;o=e[o],u*="asc"===o||true===o?1:-1;break n}u=t.b-r.b}return u})}function $t(n,t){
var r=0;return Su(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function St(n,t){var e=-1,u=xr(),o=n.length,i=u==r,f=i&&o>=F,a=f&&gu&&lu?new Dn(void 0):null,c=[];a?(u=Mn,i=false):(f=false,a=t?[]:c);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=a.length;p--;)if(a[p]===s)continue n;t&&a.push(s),c.push(l)}else 0>u(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Ft(n,t){for(var r=-1,e=t.length,u=Be(e);++r<e;)u[r]=n[t[r]];return u}function Nt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););
return r?Et(n,e?0:o,e?o+1:u):Et(n,e?o+1:0,e?u:o)}function Tt(n,t){var r=n;r instanceof zn&&(r=r.value());for(var e=-1,u=t.length;++e<u;)var o=t[e],r=o.func.apply(o.thisArg,Jn([r],o.args));return r}function Lt(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=Eu){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)&&null!==i?e=o+1:u=o}return u}return zt(n,t,Fe,r)}function zt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,a=t===w;u<o;){var c=yu((u+o)/2),l=r(n[c]),s=l!==w,p=l===l;
(i?p||e:f?p&&s&&(e||null!=l):a?p&&(e||s):null==l?0:e?l<=t:l<t)?u=c+1:o=c}return xu(o,Ou)}function Bt(n,t,r){if(typeof n!="function")return Fe;if(t===w)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Dt(n){var t=new ou(n.byteLength);return new hu(t).set(new hu(n)),
t}function Mt(n,t,r){for(var e=r.length,u=-1,o=bu(n.length-e,0),i=-1,f=t.length,a=Be(f+o);++i<f;)a[i]=t[i];for(;++u<e;)a[r[u]]=n[u];for(;o--;)a[i++]=n[u++];return a}function qt(n,t,r){for(var e=-1,u=r.length,o=-1,i=bu(n.length-u,0),f=-1,a=t.length,c=Be(i+a);++o<i;)c[o]=n[o];for(i=o;++f<a;)c[i+f]=t[f];for(;++e<u;)c[i+r[e]]=n[o++];return c}function Pt(n,t){return function(r,e,u){var o=t?t():{};if(e=wr(e,u,3),Oo(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r)}}else Su(r,function(t,r,u){
n(o,t,e(t,r,u),u)});return o}}function Kt(n){return le(function(t,r){var e=-1,u=null==t?0:r.length,o=2<u?r[u-2]:w,i=2<u?r[2]:w,f=1<u?r[u-1]:w;for(typeof o=="function"?(o=Bt(o,f,5),u-=2):(o=typeof f=="function"?f:w,u-=o?1:0),i&&Ur(r[0],r[1],i)&&(o=3>u?w:o,u=1);++e<u;)(i=r[e])&&n(t,i,o);return t})}function Vt(n,t){return function(r,e){var u=r?Bu(r):0;if(!Sr(u))return n(r,e);for(var o=t?u:-1,i=Br(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}function Zt(n){return function(t,r,e){var u=Br(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){
var f=e[i];if(false===r(u[f],f,u))break}return t}}function Yt(n,t){function r(){return(this&&this!==Zn&&this instanceof r?e:n).apply(t,arguments)}var e=Jt(n);return r}function Gt(n){return function(t){var r=-1;t=$e(Ce(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Jt(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:
return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=$u(n.prototype),t=n.apply(r,t);return ge(t)?t:r}}function Xt(n){function t(r,e,u){return u&&Ur(r,e,u)&&(e=w),r=gr(r,n,w,w,w,w,w,e),r.placeholder=t.placeholder,r}return t}function Ht(n,t){return le(function(r){var e=r[0];return null==e?e:(r.push(t),n.apply(w,r))})}function Qt(n,t){return function(r,e,u){if(u&&Ur(r,e,u)&&(e=w),e=wr(e,u,3),1==e.length){
u=r=Oo(r)?r:zr(r);for(var o=e,i=-1,f=u.length,a=t,c=a;++i<f;){var l=u[i],s=+o(l);n(s,a)&&(a=s,c=l)}if(u=c,!r.length||u!==t)return u}return ct(r,e,n,t)}}function nr(n,r){return function(e,u,o){return u=wr(u,o,3),Oo(e)?(u=t(e,u,r),-1<u?e[u]:w):st(e,u,n)}}function tr(n){return function(r,e,u){return r&&r.length?(e=wr(e,u,3),t(r,e,n)):-1}}function rr(n){return function(t,r,e){return r=wr(r,e,3),st(t,r,n,true)}}function er(n){return function(){for(var t,r=arguments.length,e=n?r:-1,u=0,o=Be(r);n?e--:++e<r;){
var i=o[u++]=arguments[e];if(typeof i!="function")throw new Ge(L);!t&&Ln.prototype.thru&&"wrapper"==br(i)&&(t=new Ln([],true))}for(e=t?-1:r;++e<r;){var i=o[e],u=br(i),f="wrapper"==u?zu(i):w;t=f&&$r(f[0])&&f[1]==(E|k|R|C)&&!f[4].length&&1==f[9]?t[br(f[0])].apply(t,f[3]):1==i.length&&$r(i)?t[u]():t.thru(i)}return function(){var n=arguments,e=n[0];if(t&&1==n.length&&Oo(e)&&e.length>=F)return t.plant(e).value();for(var u=0,n=r?o[u].apply(this,n):e;++u<r;)n=o[u].call(this,n);return n}}}function ur(n,t){
return function(r,e,u){return typeof e=="function"&&u===w&&Oo(r)?n(r,e):t(r,Bt(e,u,3))}}function or(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Bt(r,e,3)),n(t,r,Re)}}function ir(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Bt(r,e,3)),n(t,r)}}function fr(n){return function(t,r,e){var u={};return r=wr(r,e,3),_t(t,function(t,e,o){o=r(t,e,o),e=n?o:e,t=n?t:o,u[e]=t}),u}}function ar(n){return function(t,r,e){return t=u(t),(n?t:"")+pr(t,r,e)+(n?"":t)}}function cr(n){
var t=le(function(r,e){var u=v(e,t.placeholder);return gr(r,n,w,e,u)});return t}function lr(n,t){return function(r,e,u,o){var i=3>arguments.length;return typeof e=="function"&&o===w&&Oo(r)?n(r,e,u,i):Ot(r,wr(e,o,4),u,i,t)}}function sr(n,t,r,e,u,o,i,f,a,c){function l(){for(var m=arguments.length,b=m,j=Be(m);b--;)j[b]=arguments[b];if(e&&(j=Mt(j,e,u)),o&&(j=qt(j,o,i)),_||y){var b=l.placeholder,k=v(j,b),m=m-k.length;if(m<c){var I=f?qn(f):w,m=bu(c-m,0),E=_?k:w,k=_?w:k,C=_?j:w,j=_?w:j;return t|=_?R:O,t&=~(_?O:R),
g||(t&=~(x|A)),j=[n,t,r,C,E,j,k,I,a,m],I=sr.apply(w,j),$r(n)&&Du(I,j),I.placeholder=b,I}}if(b=p?r:this,I=h?b[n]:n,f)for(m=j.length,E=xu(f.length,m),k=qn(j);E--;)C=f[E],j[E]=Cr(C,m)?k[C]:w;return s&&a<j.length&&(j.length=a),this&&this!==Zn&&this instanceof l&&(I=d||Jt(n)),I.apply(b,j)}var s=t&E,p=t&x,h=t&A,_=t&k,g=t&j,y=t&I,d=h?w:Jt(n);return l}function pr(n,t,r){return n=n.length,t=+t,n<t&&mu(t)?(t-=n,r=null==r?" ":r+"",Ue(r,vu(t/r.length)).slice(0,t)):""}function hr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,a=-1,c=e.length,l=Be(c+f);++a<c;)l[a]=e[a];
for(;f--;)l[a++]=arguments[++t];return(this&&this!==Zn&&this instanceof u?i:n).apply(o?r:this,l)}var o=t&x,i=Jt(n);return u}function _r(n){var t=Pe[n];return function(n,r){return(r=r===w?0:+r||0)?(r=au(10,r),t(n*r)/r):t(n)}}function vr(n){return function(t,r,e,u){var o=wr(e);return null==e&&o===ut?Lt(t,r,n):zt(t,r,o(e,u,1),n)}}function gr(n,t,r,e,u,o,i,f){var a=t&A;if(!a&&typeof n!="function")throw new Ge(L);var c=e?e.length:0;if(c||(t&=~(R|O),e=u=w),c-=u?u.length:0,t&O){var l=e,s=u;e=u=w}var p=a?w:zu(n);
return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==E&&e==k||t==E&&e==C&&r[7].length<=p[8]||t==(E|C)&&e==k,(f<E||u)&&(t&x&&(r[2]=p[2],f|=e&x?0:j),(e=p[3])&&(u=r[3],r[3]=u?Mt(u,e,p[4]):qn(e),r[4]=u?v(r[3],z):qn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?qt(u,e,p[6]):qn(e),r[6]=u?v(r[5],z):qn(p[6])),(e=p[7])&&(r[7]=qn(e)),t&E&&(r[8]=null==r[8]?p[8]:xu(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?a?0:n.length:bu(f-c,0)||0,(p?Lu:Du)(t==x?Yt(r[0],r[2]):t!=R&&t!=(x|R)||r[4].length?sr.apply(w,r):hr.apply(w,r),r);
}function yr(n,t,r,e,u,o,i){var f=-1,a=n.length,c=t.length;if(a!=c&&(!u||c<=a))return false;for(;++f<a;){var l=n[f],c=t[f],s=e?e(u?c:l,u?l:c,f):w;if(s!==w){if(s)continue;return false}if(u){if(!Hn(t,function(n){return l===n||r(l,n,e,u,o,i)}))return false}else if(l!==c&&!r(l,c,e,u,o,i))return false}return true}function dr(n,t,r){switch(r){case M:case q:return+n==+t;case P:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:n==+t;case Y:case G:return n==t+""}return false}function mr(n,t,r,e,u,o,i){var f=zo(n),a=f.length,c=zo(t).length;
if(a!=c&&!u)return false;for(c=a;c--;){var l=f[c];if(!(u?l in t:nu.call(t,l)))return false}for(var s=u;++c<a;){var l=f[c],p=n[l],h=t[l],_=e?e(u?h:p,u?p:h,l):w;if(_===w?!r(p,h,e,u,o,i):!_)return false;s||(s="constructor"==l)}return s||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false}function wr(n,t,r){var e=Nn.callback||Se,e=e===Se?ut:e;return r?e(n,t,r):e}function br(n){for(var t=n.name,r=Wu[t],e=r?r.length:0;e--;){
var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}function xr(n,t,e){var u=Nn.indexOf||Vr,u=u===Vr?r:u;return n?u(n,t,e):u}function Ar(n){n=Oe(n);for(var t=n.length;t--;){var r=n[t][1];n[t][2]=r===r&&!ge(r)}return n}function jr(n,t){var r=null==n?w:n[t];return ye(r)?r:w}function kr(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&nu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ir(n){return n=n.constructor,typeof n=="function"&&n instanceof n||(n=Ve),
new n}function Rr(n,t,r){var e=n.constructor;switch(t){case J:return Dt(n);case M:case q:return new e(+n);case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return t=n.buffer,new e(r?Dt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Y:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u}function Or(n,t,r){return null==n||Wr(t,n)||(t=Dr(t),n=1==t.length?n:yt(n,Et(t,0,-1)),t=Zr(t)),t=null==n?n:n[t],null==t?w:t.apply(n,r)}function Er(n){return null!=n&&Sr(Bu(n));
}function Cr(n,t){return n=typeof n=="number"||On.test(n)?+n:-1,t=null==t?Cu:t,-1<n&&0==n%1&&n<t}function Ur(n,t,r){if(!ge(r))return false;var e=typeof t;return("number"==e?Er(r)&&Cr(t,r.length):"string"==e&&t in r)?(t=r[t],n===n?n===t:t!==t):false}function Wr(n,t){var r=typeof n;return"string"==r&&dn.test(n)||"number"==r?true:Oo(n)?false:!yn.test(n)||null!=t&&n in Br(t)}function $r(n){var t=br(n);return t in zn.prototype?(t=Nn[t],n===t?true:(t=zu(t),!!t&&n===t[0])):false}function Sr(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=Cu;
}function Fr(n,t){return n===w?t:Eo(n,t,Fr)}function Nr(n,t){n=Br(n);for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Tr(n,t){var r={};return ht(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function Lr(n){for(var t=Re(n),r=t.length,e=r&&n.length,u=!!e&&Sr(e)&&(Oo(n)||pe(n)),o=-1,i=[];++o<r;){var f=t[o];(u&&Cr(f,e)||nu.call(n,f))&&i.push(f)}return i}function zr(n){return null==n?[]:Er(n)?ge(n)?n:Ve(n):Ee(n)}function Br(n){return ge(n)?n:Ve(n)}function Dr(n){if(Oo(n))return n;
var t=[];return u(n).replace(mn,function(n,r,e,u){t.push(e?u.replace(An,"$1"):r||n)}),t}function Mr(n){return n instanceof zn?n.clone():new Ln(n.__wrapped__,n.__chain__,qn(n.__actions__))}function qr(n,t,r){return n&&n.length?((r?Ur(n,t,r):null==t)&&(t=1),Et(n,0>t?0:t)):[]}function Pr(n,t,r){var e=n?n.length:0;return e?((r?Ur(n,t,r):null==t)&&(t=1),t=e-(+t||0),Et(n,0,0>t?0:t)):[]}function Kr(n){return n?n[0]:w}function Vr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?bu(u+e,0):e;else if(e)return e=Lt(n,t),
e<u&&(t===t?t===n[e]:n[e]!==n[e])?e:-1;return r(n,t,e||0)}function Zr(n){var t=n?n.length:0;return t?n[t-1]:w}function Yr(n){return qr(n,1)}function Gr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=Ur(n,t,u)?w:t,t=false);var o=wr();if((null!=e||o!==ut)&&(e=o(e,u,3)),t&&xr()==r){t=e;var i;e=-1,u=n.length;for(var o=-1,f=[];++e<u;){var a=n[e],c=t?t(a,e,n):a;e&&i===c||(i=c,f[++o]=a)}n=f}else n=St(n,e);return n}function Jr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Vn(n,function(n){
return Er(n)?(r=bu(n.length,r),true):void 0});for(var e=Be(r);++t<r;)e[t]=Gn(n,jt(t));return e}function Xr(n,t,r){return n&&n.length?(n=Jr(n),null==t?n:(t=Bt(t,r,4),Gn(n,function(n){return Xn(n,t,w,true)}))):[]}function Hr(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||Oo(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1])}return u}function Qr(n){return n=Nn(n),n.__chain__=true,n}function ne(n,t,r){return t.call(r,n)}function te(n,t,r){var e=Oo(n)?Kn:at;return r&&Ur(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=wr(t,r,3)),
e(n,t)}function re(n,t,r){var e=Oo(n)?Vn:lt;return t=wr(t,r,3),e(n,t)}function ee(n,t,r,e){var u=n?Bu(n):0;return Sr(u)||(n=Ee(n),u=n.length),r=typeof r!="number"||e&&Ur(t,r,e)?0:0>r?bu(u+r,0):r||0,typeof n=="string"||!Oo(n)&&be(n)?r<=u&&-1<n.indexOf(t,r):!!u&&-1<xr(n,t,r)}function ue(n,t,r){var e=Oo(n)?Gn:wt;return t=wr(t,r,3),e(n,t)}function oe(n,t,r){if(r?Ur(n,t,r):null==t){n=zr(n);var e=n.length;return 0<e?n[Rt(0,e-1)]:w}r=-1,n=je(n);var e=n.length,u=e-1;for(t=xu(0>t?0:+t||0,e);++r<t;){var e=Rt(r,u),o=n[e];
n[e]=n[r],n[r]=o}return n.length=t,n}function ie(n,t,r){var e=Oo(n)?Hn:Ct;return r&&Ur(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=wr(t,r,3)),e(n,t)}function fe(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Ge(L);var e=n;n=t,t=e}return function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=w),r}}function ae(n,t,r){function e(t,r){r&&iu(r),a=p=h=w,t&&(_=ho(),c=n.apply(s,f),p||a||(f=s=w))}function u(){var n=t-(ho()-l);0>=n||n>t?e(h,a):p=su(u,n)}function o(){e(g,p);
}function i(){if(f=arguments,l=ho(),s=this,h=g&&(p||!y),false===v)var r=y&&!p;else{a||y||(_=l);var e=v-(l-_),i=0>=e||e>v;i?(a&&(a=iu(a)),_=l,c=n.apply(s,f)):a||(a=su(o,e))}return i&&p?p=iu(p):p||t===v||(p=su(u,t)),r&&(i=true,c=n.apply(s,f)),!i||p||a||(f=s=w),c}var f,a,c,l,s,p,h,_=0,v=false,g=true;if(typeof n!="function")throw new Ge(L);if(t=0>t?0:+t||0,true===r)var y=true,g=false;else ge(r)&&(y=!!r.leading,v="maxWait"in r&&bu(+r.maxWait||0,t),g="trailing"in r?!!r.trailing:g);return i.cancel=function(){p&&iu(p),a&&iu(a),
_=0,a=p=h=w},i}function ce(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Ge(L);return r.cache=new ce.Cache,r}function le(n,t){if(typeof n!="function")throw new Ge(L);return t=bu(t===w?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=bu(r.length-t,0),o=Be(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);
case 2:return n.call(this,r[0],r[1],o)}for(u=Be(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function se(n,t){return n>t}function pe(n){return h(n)&&Er(n)&&nu.call(n,"callee")&&!cu.call(n,"callee")}function he(n,t,r,e){return e=(r=typeof r=="function"?Bt(r,e,3):w)?r(n,t):w,e===w?dt(n,t,r):!!e}function _e(n){return h(n)&&typeof n.message=="string"&&ru.call(n)==P}function ve(n){return ge(n)&&ru.call(n)==K}function ge(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function ye(n){
return null==n?false:ve(n)?uu.test(Qe.call(n)):h(n)&&Rn.test(n)}function de(n){return typeof n=="number"||h(n)&&ru.call(n)==V}function me(n){var t;if(!h(n)||ru.call(n)!=Z||pe(n)||!(nu.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return ht(n,function(n,t){r=t}),r===w||nu.call(n,r)}function we(n){return ge(n)&&ru.call(n)==Y}function be(n){return typeof n=="string"||h(n)&&ru.call(n)==G}function xe(n){return h(n)&&Sr(n.length)&&!!Sn[ru.call(n)]}function Ae(n,t){
return n<t}function je(n){var t=n?Bu(n):0;return Sr(t)?t?qn(n):[]:Ee(n)}function ke(n){return et(n,Re(n))}function Ie(n){return gt(n,Re(n))}function Re(n){if(null==n)return[];ge(n)||(n=Ve(n));for(var t=n.length,t=t&&Sr(t)&&(Oo(n)||pe(n))&&t||0,r=n.constructor,e=-1,r=typeof r=="function"&&r.prototype===n,u=Be(t),o=0<t;++e<t;)u[e]=e+"";for(var i in n)o&&Cr(i,t)||"constructor"==i&&(r||!nu.call(n,i))||u.push(i);return u}function Oe(n){n=Br(n);for(var t=-1,r=zo(n),e=r.length,u=Be(e);++t<e;){var o=r[t];
u[t]=[o,n[o]]}return u}function Ee(n){return Ft(n,zo(n))}function Ce(n){return(n=u(n))&&n.replace(En,a).replace(xn,"")}function Ue(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!mu(t))return r;do t%2&&(r+=n),t=yu(t/2),n+=n;while(t);return r}function We(n,t,r){var e=n;return(n=u(n))?(r?Ur(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(o(n,t),i(n,t)+1)):n}function $e(n,t,r){return r&&Ur(n,t,r)&&(t=w),n=u(n),n.match(t||Wn)||[]}function Se(n,t,r){return r&&Ur(n,t,r)&&(t=w),h(n)?Ne(n):ut(n,t)}function Fe(n){
return n}function Ne(n){return bt(ot(n,true))}function Te(n,t,r){if(null==r){var e=ge(t),u=e?zo(t):w;((u=u&&u.length?gt(t,u):w)?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=gt(t,zo(t)));var o=true,e=-1,i=ve(n),f=u.length;false===r?o=false:ge(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var a=t[r];n[r]=a,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=qn(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return t.apply(n,Jn([this.value()],arguments));
}}(a))}return n}function Le(){}function ze(n){return Wr(n)?jt(n):kt(n)}_=_?Yn.defaults(Zn.Object(),_,Yn.pick(Zn,$n)):Zn;var Be=_.Array,De=_.Date,Me=_.Error,qe=_.Function,Pe=_.Math,Ke=_.Number,Ve=_.Object,Ze=_.RegExp,Ye=_.String,Ge=_.TypeError,Je=Be.prototype,Xe=Ve.prototype,He=Ye.prototype,Qe=qe.prototype.toString,nu=Xe.hasOwnProperty,tu=0,ru=Xe.toString,eu=Zn._,uu=Ze("^"+Qe.call(nu).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),ou=_.ArrayBuffer,iu=_.clearTimeout,fu=_.parseFloat,au=Pe.pow,cu=Xe.propertyIsEnumerable,lu=jr(_,"Set"),su=_.setTimeout,pu=Je.splice,hu=_.Uint8Array,_u=jr(_,"WeakMap"),vu=Pe.ceil,gu=jr(Ve,"create"),yu=Pe.floor,du=jr(Be,"isArray"),mu=_.isFinite,wu=jr(Ve,"keys"),bu=Pe.max,xu=Pe.min,Au=jr(De,"now"),ju=_.parseInt,ku=Pe.random,Iu=Ke.NEGATIVE_INFINITY,Ru=Ke.POSITIVE_INFINITY,Ou=4294967294,Eu=2147483647,Cu=9007199254740991,Uu=_u&&new _u,Wu={};
Nn.support={},Nn.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:Nn}};var $u=function(){function n(){}return function(t){if(ge(t)){n.prototype=t;var r=new n;n.prototype=w}return r||{}}}(),Su=Vt(_t),Fu=Vt(vt,true),Nu=Zt(),Tu=Zt(true),Lu=Uu?function(n,t){return Uu.set(n,t),n}:Fe,zu=Uu?function(n){return Uu.get(n)}:Le,Bu=jt("length"),Du=function(){var n=0,t=0;return function(r,e){var u=ho(),o=S-(u-t);if(t=u,0<o){if(++n>=$)return r}else n=0;return Lu(r,e)}}(),Mu=le(function(n,t){
return h(n)&&Er(n)?ft(n,pt(t,false,true)):[]}),qu=tr(),Pu=tr(true),Ku=le(function(n){for(var t=n.length,e=t,u=Be(l),o=xr(),i=o==r,f=[];e--;){var a=n[e]=Er(a=n[e])?a:[];u[e]=i&&120<=a.length&&gu&&lu?new Dn(e&&a):null}var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c<l;)if(a=i[c],0>(s?Mn(s,a):o(f,a,0))){for(e=t;--e;){var p=u[e];if(0>(p?Mn(p,a):o(n[e],a,0)))continue n}s&&s.push(a),f.push(a)}return f}),Vu=le(function(t,r){r=pt(r);var e=rt(t,r);return It(t,r.sort(n)),e}),Zu=vr(),Yu=vr(true),Gu=le(function(n){return St(pt(n,false,true));
}),Ju=le(function(n,t){return Er(n)?ft(n,t):[]}),Xu=le(Jr),Hu=le(function(n){var t=n.length,r=2<t?n[t-2]:w,e=1<t?n[t-1]:w;return 2<t&&typeof r=="function"?t-=2:(r=1<t&&typeof e=="function"?(--t,e):w,e=w),n.length=t,Xr(n,r,e)}),Qu=le(function(n){return n=pt(n),this.thru(function(t){t=Oo(t)?t:[Br(t)];for(var r=n,e=-1,u=t.length,o=-1,i=r.length,f=Be(u+i);++e<u;)f[e]=t[e];for(;++o<i;)f[e++]=r[o];return f})}),no=le(function(n,t){return rt(n,pt(t))}),to=Pt(function(n,t,r){nu.call(n,r)?++n[r]:n[r]=1}),ro=nr(Su),eo=nr(Fu,true),uo=ur(Pn,Su),oo=ur(function(n,t){
for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Fu),io=Pt(function(n,t,r){nu.call(n,r)?n[r].push(t):n[r]=[t]}),fo=Pt(function(n,t,r){n[r]=t}),ao=le(function(n,t,r){var e=-1,u=typeof t=="function",o=Wr(t),i=Er(n)?Be(n.length):[];return Su(n,function(n){var f=u?t:o&&null!=n?n[t]:w;i[++e]=f?f.apply(n,r):Or(n,t,r)}),i}),co=Pt(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),lo=lr(Xn,Su),so=lr(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Fu),po=le(function(n,t){
if(null==n)return[];var r=t[2];return r&&Ur(t[0],t[1],r)&&(t.length=1),Wt(n,pt(t),[])}),ho=Au||function(){return(new De).getTime()},_o=le(function(n,t,r){var e=x;if(r.length)var u=v(r,_o.placeholder),e=e|R;return gr(n,e,t,r,u)}),vo=le(function(n,t){t=t.length?pt(t):Ie(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=gr(n[u],x,n)}return n}),go=le(function(n,t,r){var e=x|A;if(r.length)var u=v(r,go.placeholder),e=e|R;return gr(t,e,n,r,u)}),yo=Xt(k),mo=Xt(I),wo=le(function(n,t){return it(n,1,t)}),bo=le(function(n,t,r){
return it(n,t,r)}),xo=er(),Ao=er(true),jo=le(function(n,t){if(t=pt(t),typeof n!="function"||!Kn(t,e))throw new Ge(L);var r=t.length;return le(function(e){for(var u=xu(e.length,r);u--;)e[u]=t[u](e[u]);return n.apply(this,e)})}),ko=cr(R),Io=cr(O),Ro=le(function(n,t){return gr(n,C,w,w,w,pt(t))}),Oo=du||function(n){return h(n)&&Sr(n.length)&&ru.call(n)==D},Eo=Kt(At),Co=Kt(function(n,t,r){return r?nt(n,t,r):tt(n,t)}),Uo=Ht(Co,function(n,t){return n===w?t:n}),Wo=Ht(Eo,Fr),$o=rr(_t),So=rr(vt),Fo=or(Nu),No=or(Tu),To=ir(_t),Lo=ir(vt),zo=wu?function(n){
var t=null==n?w:n.constructor;return typeof t=="function"&&t.prototype===n||typeof n!="function"&&Er(n)?Lr(n):ge(n)?wu(n):[]}:Lr,Bo=fr(true),Do=fr(),Mo=le(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Gn(pt(t),Ye),Nr(n,ft(Re(n),t));var r=Bt(t[0],t[1],3);return Tr(n,function(n,t,e){return!r(n,t,e)})}),qo=le(function(n,t){return null==n?{}:"function"==typeof t[0]?Tr(n,Bt(t[0],t[1],3)):Nr(n,pt(t))}),Po=Gt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t);
}),Ko=Gt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Vo=ar(),Zo=ar(true),Yo=Gt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Go=Gt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),Jo=le(function(n,t){try{return n.apply(w,t)}catch(r){return _e(r)?r:new Me(r)}}),Xo=le(function(n,t){return function(r){return Or(r,n,t)}}),Ho=le(function(n,t){return function(r){return Or(n,r,t)}}),Qo=_r("ceil"),ni=_r("floor"),ti=Qt(se,Iu),ri=Qt(Ae,Ru),ei=_r("round");return Nn.prototype=Tn.prototype,
Ln.prototype=$u(Tn.prototype),Ln.prototype.constructor=Ln,zn.prototype=$u(Tn.prototype),zn.prototype.constructor=zn,Bn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Bn.prototype.get=function(n){return"__proto__"==n?w:this.__data__[n]},Bn.prototype.has=function(n){return"__proto__"!=n&&nu.call(this.__data__,n)},Bn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Dn.prototype.push=function(n){var t=this.data;typeof n=="string"||ge(n)?t.set.add(n):t.hash[n]=true;
},ce.Cache=Bn,Nn.after=function(n,t){if(typeof t!="function"){if(typeof n!="function")throw new Ge(L);var r=n;n=t,t=r}return n=mu(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&Ur(n,t,r)&&(t=w),t=n&&null==t?n.length:bu(+t||0,0),gr(n,E,w,w,w,w,t)},Nn.assign=Co,Nn.at=no,Nn.before=fe,Nn.bind=_o,Nn.bindAll=vo,Nn.bindKey=go,Nn.callback=Se,Nn.chain=Qr,Nn.chunk=function(n,t,r){t=(r?Ur(n,t,r):null==t)?1:bu(yu(t)||1,1),r=0;for(var e=n?n.length:0,u=-1,o=Be(vu(e/t));r<e;)o[++u]=Et(n,r,r+=t);
return o},Nn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){var o=n[t];o&&(u[++e]=o)}return u},Nn.constant=function(n){return function(){return n}},Nn.countBy=to,Nn.create=function(n,t,r){var e=$u(n);return r&&Ur(n,t,r)&&(t=w),t?tt(e,t):e},Nn.curry=yo,Nn.curryRight=mo,Nn.debounce=ae,Nn.defaults=Uo,Nn.defaultsDeep=Wo,Nn.defer=wo,Nn.delay=bo,Nn.difference=Mu,Nn.drop=qr,Nn.dropRight=Pr,Nn.dropRightWhile=function(n,t,r){return n&&n.length?Nt(n,wr(t,r,3),true,true):[]},Nn.dropWhile=function(n,t,r){
return n&&n.length?Nt(n,wr(t,r,3),true):[]},Nn.fill=function(n,t,r,e){var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&Ur(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;return n},Nn.filter=re,Nn.flatten=function(n,t,r){var e=n?n.length:0;return r&&Ur(n,t,r)&&(t=false),e?pt(n,t):[]},Nn.flattenDeep=function(n){return n&&n.length?pt(n,true):[]},Nn.flow=xo,Nn.flowRight=Ao,Nn.forEach=uo,Nn.forEachRight=oo,Nn.forIn=Fo,
Nn.forInRight=No,Nn.forOwn=To,Nn.forOwnRight=Lo,Nn.functions=Ie,Nn.groupBy=io,Nn.indexBy=fo,Nn.initial=function(n){return Pr(n,1)},Nn.intersection=Ku,Nn.invert=function(n,t,r){r&&Ur(n,t,r)&&(t=w),r=-1;for(var e=zo(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?nu.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},Nn.invoke=ao,Nn.keys=zo,Nn.keysIn=Re,Nn.map=ue,Nn.mapKeys=Bo,Nn.mapValues=Do,Nn.matches=Ne,Nn.matchesProperty=function(n,t){return xt(n,ot(t,true))},Nn.memoize=ce,Nn.merge=Eo,Nn.method=Xo,Nn.methodOf=Ho,
Nn.mixin=Te,Nn.modArgs=jo,Nn.negate=function(n){if(typeof n!="function")throw new Ge(L);return function(){return!n.apply(this,arguments)}},Nn.omit=Mo,Nn.once=function(n){return fe(2,n)},Nn.pairs=Oe,Nn.partial=ko,Nn.partialRight=Io,Nn.partition=co,Nn.pick=qo,Nn.pluck=function(n,t){return ue(n,ze(t))},Nn.property=ze,Nn.propertyOf=function(n){return function(t){return yt(n,Dr(t),t+"")}},Nn.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=xr(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)pu.call(t,o,1);
return t},Nn.pullAt=Vu,Nn.range=function(n,t,r){r&&Ur(n,t,r)&&(t=r=w),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=bu(vu((t-n)/(r||1)),0);for(var u=Be(t);++e<t;)u[e]=n,n+=r;return u},Nn.rearg=Ro,Nn.reject=function(n,t,r){var e=Oo(n)?Vn:lt;return t=wr(t,r,3),e(n,function(n,r,e){return!t(n,r,e)})},Nn.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,o=[],i=n.length;for(t=wr(t,r,3);++u<i;)r=n[u],t(r,u,n)&&(e.push(r),o.push(u));return It(n,o),e},Nn.rest=Yr,Nn.restParam=le,
Nn.set=function(n,t,r){if(null==n)return n;var e=t+"";t=null!=n[e]||Wr(t,n)?[e]:Dr(t);for(var e=-1,u=t.length,o=u-1,i=n;null!=i&&++e<u;){var f=t[e];ge(i)&&(e==o?i[f]=r:null==i[f]&&(i[f]=Cr(t[e+1])?[]:{})),i=i[f]}return n},Nn.shuffle=function(n){return oe(n,Ru)},Nn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&Ur(n,t,r)&&(t=0,r=e),Et(n,t,r)):[]},Nn.sortBy=function(n,t,r){if(null==n)return[];r&&Ur(n,t,r)&&(t=w);var e=-1;return t=wr(t,r,3),n=wt(n,function(n,r,u){return{a:t(n,r,u),
b:++e,c:n}}),Ut(n,f)},Nn.sortByAll=po,Nn.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&Ur(t,r,e)&&(r=w),Oo(t)||(t=null==t?[]:[t]),Oo(r)||(r=null==r?[]:[r]),Wt(n,t,r))},Nn.spread=function(n){if(typeof n!="function")throw new Ge(L);return function(t){return n.apply(this,t)}},Nn.take=function(n,t,r){return n&&n.length?((r?Ur(n,t,r):null==t)&&(t=1),Et(n,0,0>t?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Ur(n,t,r):null==t)&&(t=1),t=e-(+t||0),Et(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){
return n&&n.length?Nt(n,wr(t,r,3),false,true):[]},Nn.takeWhile=function(n,t,r){return n&&n.length?Nt(n,wr(t,r,3)):[]},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Ge(L);return false===r?e=false:ge(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ae(n,t,{leading:e,maxWait:+t,trailing:u})},Nn.thru=ne,Nn.times=function(n,t,r){if(n=yu(n),1>n||!mu(n))return[];var e=-1,u=Be(xu(n,4294967295));for(t=Bt(t,r,1);++e<n;)4294967295>e?u[e]=t(e):t(e);
return u},Nn.toArray=je,Nn.toPlainObject=ke,Nn.transform=function(n,t,r,e){var u=Oo(n)||xe(n);return t=wr(t,e,4),null==r&&(u||ge(n)?(e=n.constructor,r=u?Oo(n)?new e:[]:$u(ve(e)?e.prototype:w)):r={}),(u?Pn:_t)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=Gu,Nn.uniq=Gr,Nn.unzip=Jr,Nn.unzipWith=Xr,Nn.values=Ee,Nn.valuesIn=function(n){return Ft(n,Re(n))},Nn.where=function(n,t){return re(n,bt(t))},Nn.without=Ju,Nn.wrap=function(n,t){return t=null==t?Fe:t,gr(t,R,w,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++n<t;){
var r=arguments[n];if(Er(r))var e=e?Jn(ft(e,r),ft(r,e)):r}return e?St(e):[]},Nn.zip=Xu,Nn.zipObject=Hr,Nn.zipWith=Hu,Nn.backflow=Ao,Nn.collect=ue,Nn.compose=Ao,Nn.each=uo,Nn.eachRight=oo,Nn.extend=Co,Nn.iteratee=Se,Nn.methods=Ie,Nn.object=Hr,Nn.select=re,Nn.tail=Yr,Nn.unique=Gr,Te(Nn,Nn),Nn.add=function(n,t){return(+n||0)+(+t||0)},Nn.attempt=Jo,Nn.camelCase=Po,Nn.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},Nn.ceil=Qo,Nn.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&Ur(n,t,r)?t=false:typeof t=="function"&&(e=r,
r=t,t=false),typeof r=="function"?ot(n,t,Bt(r,e,1)):ot(n,t)},Nn.cloneDeep=function(n,t,r){return typeof t=="function"?ot(n,true,Bt(t,r,1)):ot(n,true)},Nn.deburr=Ce,Nn.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===w?e:xu(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,c):n},Nn.escapeRegExp=function(n){return(n=u(n))&&bn.test(n)?n.replace(wn,l):n||"(?:)"},Nn.every=te,Nn.find=ro,Nn.findIndex=qu,Nn.findKey=$o,Nn.findLast=eo,
Nn.findLastIndex=Pu,Nn.findLastKey=So,Nn.findWhere=function(n,t){return ro(n,bt(t))},Nn.first=Kr,Nn.floor=ni,Nn.get=function(n,t,r){return n=null==n?w:yt(n,Dr(t),t+""),n===w?r:n},Nn.gt=se,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=nu.call(n,t);if(!r&&!Wr(t)){if(t=Dr(t),n=1==t.length?n:yt(n,Et(t,0,-1)),null==n)return false;t=Zr(t),r=nu.call(n,t)}return r||Sr(n.length)&&Cr(t,n.length)&&(Oo(n)||pe(n))},Nn.identity=Fe,Nn.includes=ee,Nn.indexOf=Vr,Nn.inRange=function(n,t,r){
return t=+t||0,r===w?(r=t,t=0):r=+r||0,n>=xu(t,r)&&n<bu(t,r)},Nn.isArguments=pe,Nn.isArray=Oo,Nn.isBoolean=function(n){return true===n||false===n||h(n)&&ru.call(n)==M},Nn.isDate=function(n){return h(n)&&ru.call(n)==q},Nn.isElement=function(n){return!!n&&1===n.nodeType&&h(n)&&!me(n)},Nn.isEmpty=function(n){return null==n?true:Er(n)&&(Oo(n)||be(n)||pe(n)||h(n)&&ve(n.splice))?!n.length:!zo(n).length},Nn.isEqual=he,Nn.isError=_e,Nn.isFinite=function(n){return typeof n=="number"&&mu(n)},Nn.isFunction=ve,Nn.isMatch=function(n,t,r,e){
return r=typeof r=="function"?Bt(r,e,3):w,mt(n,Ar(t),r)},Nn.isNaN=function(n){return de(n)&&n!=+n},Nn.isNative=ye,Nn.isNull=function(n){return null===n},Nn.isNumber=de,Nn.isObject=ge,Nn.isPlainObject=me,Nn.isRegExp=we,Nn.isString=be,Nn.isTypedArray=xe,Nn.isUndefined=function(n){return n===w},Nn.kebabCase=Ko,Nn.last=Zr,Nn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?bu(e+r,0):xu(r||0,e-1))+1;else if(r)return u=Lt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;
if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=Ae,Nn.lte=function(n,t){return n<=t},Nn.max=ti,Nn.min=ri,Nn.noConflict=function(){return Zn._=eu,this},Nn.noop=Le,Nn.now=ho,Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&mu(t)?(e=(t-e)/2,t=yu(e),e=vu(e),r=pr("",e,r),r.slice(0,t)+n+r):n},Nn.padLeft=Vo,Nn.padRight=Zo,Nn.parseInt=function(n,t,r){return(r?Ur(n,t,r):null==t)?t=0:t&&(t=+t),n=We(n),ju(n,t||(In.test(n)?16:10))},Nn.random=function(n,t,r){r&&Ur(n,t,r)&&(t=r=w);
var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=ku(),xu(n+r*(t-n+fu("1e-"+((r+"").length-1))),t)):Rt(n,t)},Nn.reduce=lo,Nn.reduceRight=so,Nn.repeat=Ue,Nn.result=function(n,t,r){var e=null==n?w:n[t];return e===w&&(null==n||Wr(t,n)||(t=Dr(t),n=1==t.length?n:yt(n,Et(t,0,-1)),e=null==n?w:n[Zr(t)]),e=e===w?r:e),ve(e)?e.call(n):e},Nn.round=ei,Nn.runInContext=m,Nn.size=function(n){var t=n?Bu(n):0;
return Sr(t)?t:zo(n).length},Nn.snakeCase=Yo,Nn.some=ie,Nn.sortedIndex=Zu,Nn.sortedLastIndex=Yu,Nn.startCase=Go,Nn.startsWith=function(n,t,r){return n=u(n),r=null==r?0:xu(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){if(r&&Ur(n,t,r)&&(t=w),t=wr(t,r,3),1==t.length){n=Oo(n)?n:zr(n),r=n.length;for(var e=0;r--;)e+=+t(n[r])||0;n=e}else n=$t(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&Ur(n,t,r)&&(t=r=w),n=u(n),t=nt(tt({},r||t),e,Qn),r=nt(tt({},t.imports),e.imports,Qn);
var o,i,f=zo(r),a=Ft(r,f),c=0;r=t.interpolate||Cn;var l="__p+='";r=Ze((t.escape||Cn).source+"|"+r.source+"|"+(r===gn?jn:Cn).source+"|"+(t.evaluate||Cn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Un,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"),
l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=Jo(function(){return qe(f,p+"return "+l).apply(w,a)}),t.source=l,_e(t))throw t;return t},Nn.trim=We,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Ur(e,t,r):null==t)?g(n):o(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Ur(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,i(n,t+"")+1):n;
},Nn.trunc=function(n,t,r){r&&Ur(n,t,r)&&(t=w);var e=U;if(r=W,null!=t)if(ge(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(we(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ze(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),
-1<o&&(t=t.slice(0,o)));return t+r},Nn.unescape=function(n){return(n=u(n))&&pn.test(n)?n.replace(ln,d):n},Nn.uniqueId=function(n){var t=++tu;return u(n)+t},Nn.words=$e,Nn.all=te,Nn.any=ie,Nn.contains=ee,Nn.eq=he,Nn.detect=ro,Nn.foldl=lo,Nn.foldr=so,Nn.head=Kr,Nn.include=ee,Nn.inject=lo,Te(Nn,function(){var n={};return _t(Nn,function(t,r){Nn.prototype[r]||(n[r]=t)}),n}(),false),Nn.sample=oe,Nn.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return oe(t,n)}):oe(this.value());
},Nn.VERSION=b,Pn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nn[n].placeholder=Nn}),Pn(["drop","take"],function(n,t){zn.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new zn(this);r=null==r?1:bu(yu(r)||0,0);var u=this.clone();return e?u.__takeCount__=xu(u.__takeCount__,r):u.__views__.push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},zn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Pn(["filter","map","takeWhile"],function(n,t){
var r=t+1,e=r!=T;zn.prototype[n]=function(n,t){var u=this.clone();return u.__iteratees__.push({iteratee:wr(n,t,1),type:r}),u.__filtered__=u.__filtered__||e,u}}),Pn(["first","last"],function(n,t){var r="take"+(t?"Right":"");zn.prototype[n]=function(){return this[r](1).value()[0]}}),Pn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");zn.prototype[n]=function(){return this.__filtered__?new zn(this):this[r](1)}}),Pn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?bt:ze;zn.prototype[n]=function(n){
return this[r](e(n))}}),zn.prototype.compact=function(){return this.filter(Fe)},zn.prototype.reject=function(n,t){return n=wr(n,t,1),this.filter(function(t){return!n(t)})},zn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return r.__filtered__&&(0<n||0>t)?new zn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r)},zn.prototype.takeRightWhile=function(n,t){return this.reverse().takeWhile(n,t).reverse()},zn.prototype.toArray=function(){return this.take(Ru);
},_t(zn.prototype,function(n,t){var r=/^(?:filter|map|reject)|While$/.test(t),e=/^(?:first|last)$/.test(t),u=Nn[e?"take"+("last"==t?"Right":""):t];u&&(Nn.prototype[t]=function(){function t(n){return e&&i?u(n,1)[0]:u.apply(w,Jn([n],o))}var o=e?[1]:arguments,i=this.__chain__,f=this.__wrapped__,a=!!this.__actions__.length,c=f instanceof zn,l=o[0],s=c||Oo(f);return s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false),l={func:ne,args:[t],thisArg:w},a=c&&!a,e&&!i?a?(f=f.clone(),f.__actions__.push(l),n.call(f)):u.call(w,this.value())[0]:!e&&s?(f=a?f:new zn(this),
f=n.apply(f,o),f.__actions__.push(l),new Ln(f,i)):this.thru(t)})}),Pn("join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?He:Je)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);Nn.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),_t(zn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name;(Wu[e]||(Wu[e]=[])).push({
name:t,func:r})}}),Wu[sr(w,A).name]=[{name:"wrapper",func:w}],zn.prototype.clone=function(){var n=new zn(this.__wrapped__);return n.__actions__=qn(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=qn(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=qn(this.__views__),n},zn.prototype.reverse=function(){if(this.__filtered__){var n=new zn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},zn.prototype.value=function(){
var n,t=this.__wrapped__.value(),r=this.__dir__,e=Oo(t),u=0>r,o=e?t.length:0;n=o;for(var i=this.__views__,f=0,a=-1,c=i.length;++a<c;){var l=i[a],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=xu(n,f+s);break;case"takeRight":f=bu(f,n-s)}}if(n={start:f,end:n},i=n.start,f=n.end,n=f-i,i=u?f:i-1,f=this.__iteratees__,a=f.length,c=0,l=xu(n,this.__takeCount__),!e||o<F||o==n&&l==n)return Tt(u&&e?t.reverse():t,this.__actions__);e=[];n:for(;n--&&c<l;){for(i+=r,u=-1,o=t[i];++u<a;){
var p=f[u],s=p.type,p=p.iteratee(o);if(s==T)o=p;else if(!p){if(s==N)continue n;break n}}e[c++]=o}return e},Nn.prototype.chain=function(){return Qr(this)},Nn.prototype.commit=function(){return new Ln(this.value(),this.__chain__)},Nn.prototype.concat=Qu,Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Tn;){var e=Mr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){function n(n){return r&&0>r.__dir__?n:n.reverse()}var t=this.__wrapped__;
if(t instanceof zn){var r=t;return this.__actions__.length&&(r=new zn(this)),r=r.reverse(),r.__actions__.push({func:ne,args:[n],thisArg:w}),new Ln(r,this.__chain__)}return this.thru(n)},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){return Tt(this.__wrapped__,this.__actions__)},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,
Nn}var w,b="3.10.0",x=1,A=2,j=4,k=8,I=16,R=32,O=64,E=128,C=256,U=30,W="...",$=150,S=16,F=200,N=1,T=2,L="Expected a function",z="__lodash_placeholder__",B="[object Arguments]",D="[object Array]",M="[object Boolean]",q="[object Date]",P="[object Error]",K="[object Function]",V="[object Number]",Z="[object Object]",Y="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,bn=RegExp(wn.source),xn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,In=/^0[xX]/,Rn=/^\[object .+?Constructor\]$/,On=/^\d+$/,En=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Cn=/($^)/,Un=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),$n="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap".split(" "),Sn={};
Sn[X]=Sn[H]=Sn[Q]=Sn[nn]=Sn[tn]=Sn[rn]=Sn[en]=Sn[un]=Sn[on]=true,Sn[B]=Sn[D]=Sn[J]=Sn[M]=Sn[q]=Sn[P]=Sn[K]=Sn["[object Map]"]=Sn[V]=Sn[Z]=Sn[Y]=Sn["[object Set]"]=Sn[G]=Sn["[object WeakMap]"]=false;var Fn={};Fn[B]=Fn[D]=Fn[J]=Fn[M]=Fn[q]=Fn[X]=Fn[H]=Fn[Q]=Fn[nn]=Fn[tn]=Fn[V]=Fn[Z]=Fn[Y]=Fn[G]=Fn[rn]=Fn[en]=Fn[un]=Fn[on]=true,Fn[P]=Fn[K]=Fn["[object Map]"]=Fn["[object Set]"]=Fn["[object WeakMap]"]=false;var Nn={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a",
"\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y",
"\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Tn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Ln={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},zn={"function":true,object:true},Bn={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Dn={"\\":"\\",
"'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Mn=zn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=zn[typeof module]&&module&&!module.nodeType&&module,Pn=zn[typeof self]&&self&&self.Object&&self,Kn=zn[typeof window]&&window&&window.Object&&window,Vn=qn&&qn.exports===Mn&&Mn,Zn=Mn&&qn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||Pn||this,Yn=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Zn._=Yn, define(function(){
return Yn})):Mn&&qn?Vn?(qn.exports=Yn)._=Yn:Mn._=Yn:Zn._=Yn}).call(this);

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +1,33 @@
{
"name": "lodash",
"version": "4.4.0",
"main": "lodash.js",
"version": "3.10.0",
"main": "lodash.src.js",
"private": true,
"devDependencies": {
"async": "^1.5.2",
"benchmark": "^2.1.0",
"chalk": "^1.1.1",
"codecov.io": "~0.1.6",
"coveralls": "^2.11.6",
"curl-amd": "~0.8.12",
"docdown": "~0.4.1",
"dojo": "^1.10.4",
"ecstatic": "^1.4.0",
"fs-extra": "~0.26.5",
"glob": "^7.0.0",
"istanbul": "0.4.2",
"jquery": "^2.2.0",
"jscs": "^2.10.1",
"lodash": "^3.10.1",
"platform": "^1.3.1",
"qunit-extras": "^1.4.5",
"qunitjs": "~1.21.0",
"request": "^2.69.0",
"requirejs": "^2.1.22",
"sauce-tunnel": "^2.4.0",
"uglify-js": "2.6.1",
"webpack": "^1.12.13"
"curl-amd": "0.8.12",
"dojo": "~1.10.0",
"jquery": "~1.11.0",
"platform": "~1.3.0",
"qunit-extras": "~1.4.0",
"qunitjs": "~1.18.0",
"requirejs": "~2.1.0"
},
"scripts": {
"build": "npm run build:main & npm run build:fp",
"build:fp": "node lib/fp/build-dist.js",
"build:fp-modules": "node lib/fp/build-modules.js",
"build:main": "node lib/main/build-dist.js",
"build:main-modules": "node lib/main/build-modules.js",
"doc": "node lib/main/build-doc github",
"doc:fp": "node lib/fp/build-doc",
"doc:site": "node lib/main/build-doc site",
"prepublish": "npm run style",
"pretest": "npm run build",
"style": "npm run style:main & npm run style:fp & npm run style:perf & npm run style:test",
"style:fp": "jscs fp/*.js lib/**/*.js",
"style:main": "jscs lodash.js",
"style:perf": "jscs perf/*.js perf/**/*.js",
"style:test": "jscs test/*.js test/**/*.js",
"test": "npm run test:main && npm run test:fp && npm run test:docs",
"test:fp": "node test/test-fp",
"test:main": "node test/test"
"volo": {
"type": "directory",
"ignore": [
".*",
"*.custom.*",
"*.log",
"*.map",
"*.md",
"lodash.src.js",
"bower.json",
"component.json",
"doc",
"node_modules",
"perf",
"test",
"vendor"
]
}
}

View File

@@ -58,7 +58,10 @@
span1.innerHTML =
'<label for="perf-build">Build: </label>' +
'<select id="perf-build">' +
'<option value="lodash">lodash</option>' +
'<option value="lodash-compat">lodash (compat)</option>' +
'<option value="lodash-modern">lodash (modern)</option>' +
'<option value="lodash-custom-dev">lodash (custom development)</option>' +
'<option value="lodash-custom">lodash (custom production)</option>' +
'</select>';
var span2 = document.createElement('span');
@@ -68,7 +71,10 @@
'<select id="perf-other">' +
'<option value="underscore-dev">Underscore (development)</option>' +
'<option value="underscore">Underscore (production)</option>' +
'<option value="lodash">lodash</option>' +
'<option value="lodash-compat">lodash (compat)</option>' +
'<option value="lodash-modern">lodash (modern)</option>' +
'<option value="lodash-custom-dev">lodash (custom development)</option>' +
'<option value="lodash-custom">lodash (custom production)</option>' +
'</select>';
var buildList = span1.lastChild,
@@ -80,8 +86,11 @@
buildList.selectedIndex = (function() {
switch (build) {
case 'lodash':
case null: return 0;
case 'lodash-compat': return 0;
case 'lodash-custom-dev': return 2;
case 'lodash-custom': return 3;
case 'lodash-modern':
case null: return 1;
}
return -1;
}());
@@ -89,7 +98,10 @@
otherList.selectedIndex = (function() {
switch (other) {
case 'underscore-dev': return 0;
case 'lodash': return 2;
case 'lodash-compat': return 2;
case 'lodash-modern': return 3;
case 'lodash-custom-dev': return 4;
case 'lodash-custom': return 5;
case 'underscore':
case null: return 1;
}
@@ -104,8 +116,11 @@
ui.buildPath = (function() {
var result;
switch (build) {
case null: build = 'lodash';
case 'lodash': result = 'dist/lodash.min.js'; break;
case 'lodash-compat': result = 'lodash.compat.min.js'; break;
case 'lodash-custom-dev': result = 'lodash.custom.js'; break;
case 'lodash-custom': result = 'lodash.custom.min.js'; break;
case null: build = 'lodash-modern';
case 'lodash-modern': result = 'lodash.min.js'; break;
default: return build;
}
return basePath + result;
@@ -115,7 +130,10 @@
ui.otherPath = (function() {
var result;
switch (other) {
case 'lodash': result = 'dist/lodash.min.js'; break;
case 'lodash-compat': result = 'lodash.compat.min.js'; break;
case 'lodash-modern': result = 'lodash.min.js'; break;
case 'lodash-custom-dev': result = 'lodash.custom.js'; break;
case 'lodash-custom': result = 'lodash.custom.min.js'; break;
case 'underscore-dev': result = 'vendor/underscore/underscore.js'; break;
case null: other = 'underscore';
case 'underscore': result = 'vendor/underscore/underscore-min.js'; break;

View File

@@ -9,6 +9,10 @@
padding: 0;
height: 100%;
}
applet {
position: absolute;
left: -9999em;
}
#FirebugUI {
top: 2em;
}
@@ -24,9 +28,9 @@
</head>
<body>
<div id="perf-toolbar"></div>
<script src="../lodash.js"></script>
<script src="../node_modules/platform/platform.js"></script>
<script src="../node_modules/benchmark/benchmark.js"></script>
<script src="../lodash.src.js"></script>
<script src="../vendor/benchmark.js/benchmark.js"></script>
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
<script src="./asset/perf-ui.js"></script>
<script>
@@ -62,6 +66,15 @@
setTimeout(run, 15);
}
// is the applet permitted?
if (!/[?&]nojava=true(?:&|$)/.test(location.search)) {
// is the applet really needed?
while (!(measured = new Date - begin)) {}
if (measured > 1 && !((perfNow = window.performance) && typeof (perfNow.now || perfNow.webkitNow) == 'function')) {
// load applet
document.write('<applet code="nano" archive="../vendor/benchmark.js/nano.jar"></applet>');
}
}
window.onload = init;
}());
</script>

View File

@@ -38,16 +38,16 @@
result = params;
}
var last = result[result.length - 1];
result = (result.length > min && !/perf(?:\.js)?$/.test(last)) ? last : '../lodash.js';
result = (result.length > min && !/perf(?:\.js)?$/.test(last)) ? last : '../lodash.src.js';
if (!amd) {
try {
result = require('fs').realpathSync(result);
} catch (e) {}
} catch(e) {}
try {
result = require.resolve(result);
} catch (e) {}
} catch(e) {}
}
return result;
}());
@@ -88,10 +88,13 @@
/** Detect if in a browser environment. */
var isBrowser = isHostType(root, 'document') && isHostType(root, 'navigator');
/** Detect if in a Java environment. */
var isJava = !isBrowser && /Java/.test(toString.call(root.java));
/** Use a single "load" function. */
var load = (typeof require == 'function' && !amd)
? require
: noop;
: (isJava && root.load) || noop;
/** Load lodash. */
var lodash = root.lodash || (root.lodash = (
@@ -101,19 +104,19 @@
lodash.noConflict()
));
/** Load Underscore. */
var _ = root.underscore || (root.underscore = (
_ = load('../vendor/underscore/underscore.js') || root._,
_._ || _
));
/** Load Benchmark.js. */
var Benchmark = root.Benchmark || (root.Benchmark = (
Benchmark = load('../node_modules/benchmark/benchmark.js') || root.Benchmark,
Benchmark = load('../vendor/benchmark.js/benchmark.js') || root.Benchmark,
Benchmark = Benchmark.Benchmark || Benchmark,
Benchmark.runInContext(lodash.extend({}, root, { '_': lodash }))
));
/** Load Underscore. */
var _ = root._ || (root._ = (
_ = load('../vendor/underscore/underscore.js') || root._,
_._ || _
));
/*--------------------------------------------------------------------------*/
/**
@@ -202,7 +205,7 @@
fbPanel.getElementById('fbPanel1');
log('\nSit back and relax, this may take a while.');
suites[0].run({ 'async': true });
suites[0].run({ 'async': !isJava });
}
/*--------------------------------------------------------------------------*/
@@ -255,7 +258,7 @@
if (suites.length) {
// Run next suite.
suites[0].run({ 'async': true });
suites[0].run({ 'async': !isJava });
}
else {
var aMeanHz = getGeometricMean(score.a),
@@ -281,7 +284,7 @@
lodash.extend(Benchmark.options, {
'async': true,
'setup': '\
var _ = global.underscore,\
var _ = global._,\
lodash = global.lodash,\
belt = this.name == buildName ? lodash : _;\
\
@@ -348,8 +351,8 @@
square = function(v) { return v * v; };\
\
var largeArray = belt.range(10000),\
_chaining = _(largeArray).chain(),\
lodashChaining = lodash(largeArray).chain();\
_chaining = _.chain ? _(largeArray).chain() : _(largeArray),\
lodashChaining = lodash(largeArray);\
}\
if (typeof compact != "undefined") {\
var uncompacted = numbers.slice();\
@@ -357,13 +360,13 @@
uncompacted[6] = null;\
uncompacted[18] = "";\
}\
if (typeof flowRight != "undefined") {\
if (typeof compose != "undefined") {\
var compAddOne = function(n) { return n + 1; },\
compAddTwo = function(n) { return n + 2; },\
compAddThree = function(n) { return n + 3; };\
\
var _composed = _.flowRight && _.flowRight(compAddThree, compAddTwo, compAddOne),\
lodashComposed = lodash.flowRight && lodash.flowRight(compAddThree, compAddTwo, compAddOne);\
var _composed = _.compose(compAddThree, compAddTwo, compAddOne),\
lodashComposed = lodash.compose(compAddThree, compAddTwo, compAddOne);\
}\
if (typeof countBy != "undefined" || typeof omit != "undefined") {\
var wordToNumber = {\
@@ -458,8 +461,11 @@
if (typeof matches != "undefined") {\
var source = { "num": 9 };\
\
var _matcher = (_.matches || _.noop)(source),\
lodashMatcher = (lodash.matches || lodash.noop)(source);\
var _findWhere = _.findWhere || _.find,\
_matcher = (_.matches || _.createCallback || _.noop)(source);\
\
var lodashFindWhere = lodash.findWhere || lodash.find,\
lodashMatcher = (lodash.matches || lodash.createCallback || lodash.noop)(source);\
}\
if (typeof multiArrays != "undefined") {\
var twentyValues = belt.shuffle(belt.range(20)),\
@@ -639,13 +645,25 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.bindAll`')
Benchmark.Suite('`_.bindAll` iterating arguments')
.add(buildName, {
'fn': 'lodash.bindAll(bindAllObjects[++bindAllCount], funcNames)',
'fn': 'lodash.bindAll.apply(lodash, [bindAllObjects[++bindAllCount]].concat(funcNames))',
'teardown': 'function bindAll(){}'
})
.add(otherName, {
'fn': '_.bindAll(bindAllObjects[++bindAllCount], funcNames)',
'fn': '_.bindAll.apply(_, [bindAllObjects[++bindAllCount]].concat(funcNames))',
'teardown': 'function bindAll(){}'
})
);
suites.push(
Benchmark.Suite('`_.bindAll` iterating the `object`')
.add(buildName, {
'fn': 'lodash.bindAll(bindAllObjects[++bindAllCount])',
'teardown': 'function bindAll(){}'
})
.add(otherName, {
'fn': '_.bindAll(bindAllObjects[++bindAllCount])',
'teardown': 'function bindAll(){}'
})
);
@@ -688,6 +706,32 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.compose`')
.add(buildName, {
'fn': 'lodash.compose(compAddThree, compAddTwo, compAddOne)',
'teardown': 'function compose(){}'
})
.add(otherName, {
'fn': '_.compose(compAddThree, compAddTwo, compAddOne)',
'teardown': 'function compose(){}'
})
);
suites.push(
Benchmark.Suite('composed call')
.add(buildName, {
'fn': 'lodashComposed(0)',
'teardown': 'function compose(){}'
})
.add(otherName, {
'fn': '_composed(0)',
'teardown': 'function compose(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.countBy` with `callback` iterating an array')
.add(buildName, '\
@@ -788,6 +832,22 @@
)
);
suites.push(
Benchmark.Suite('`_.each` iterating an array with `thisArg` (slow path)')
.add(buildName, '\
var result = [];\
lodash.each(numbers, function(num, index) {\
result.push(num + this["key" + index]);\
}, object)'
)
.add(otherName, '\
var result = [];\
_.each(numbers, function(num, index) {\
result.push(num + this["key" + index]);\
}, object)'
)
);
suites.push(
Benchmark.Suite('`_.each` iterating an object')
.add(buildName, '\
@@ -850,6 +910,20 @@
)
);
suites.push(
Benchmark.Suite('`_.filter` iterating an array with `thisArg` (slow path)')
.add(buildName, '\
lodash.filter(numbers, function(num, index) {\
return this["key" + index] % 2;\
}, object)'
)
.add(otherName, '\
_.filter(numbers, function(num, index) {\
return this["key" + index] % 2;\
}, object)'
)
);
suites.push(
Benchmark.Suite('`_.filter` iterating an object')
.add(buildName, '\
@@ -864,18 +938,6 @@
)
);
suites.push(
Benchmark.Suite('`_.filter` with `_.matches` shorthand')
.add(buildName, {
'fn': 'lodash.filter(objects, source)',
'teardown': 'function matches(){}'
})
.add(otherName, {
'fn': '_.filter(objects, source)',
'teardown': 'function matches(){}'
})
);
suites.push(
Benchmark.Suite('`_.filter` with `_.matches` predicate')
.add(buildName, {
@@ -919,17 +981,19 @@
);
// Avoid Underscore induced `OutOfMemoryError` in Rhino and Ringo.
suites.push(
Benchmark.Suite('`_.find` with `_.matches` shorthand')
.add(buildName, {
'fn': 'lodash.find(objects, source)',
'teardown': 'function matches(){}'
})
.add(otherName, {
'fn': '_.find(objects, source)',
'teardown': 'function matches(){}'
})
);
if (!isJava) {
suites.push(
Benchmark.Suite('`_.find` with `_.matches` shorthand')
.add(buildName, {
'fn': 'lodashFindWhere(objects, source)',
'teardown': 'function matches(){}'
})
.add(otherName, {
'fn': '_findWhere(objects, source)',
'teardown': 'function matches(){}'
})
);
}
/*--------------------------------------------------------------------------*/
@@ -945,60 +1009,32 @@
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.flattenDeep` nested arrays of numbers')
Benchmark.Suite('`_.flatten` nested arrays of numbers with `isDeep`')
.add(buildName, {
'fn': 'lodash.flattenDeep(nestedNumbers)',
'fn': 'lodash.flatten(nestedNumbers, lodashFlattenDeep)',
'teardown': 'function flatten(){}'
})
.add(otherName, {
'fn': '_.flattenDeep(nestedNumbers)',
'fn': '_.flatten(nestedNumbers, _flattenDeep)',
'teardown': 'function flatten(){}'
})
);
suites.push(
Benchmark.Suite('`_.flattenDeep` nest arrays of objects')
Benchmark.Suite('`_.flatten` nest arrays of objects with `isDeep`')
.add(buildName, {
'fn': 'lodash.flattenDeep(nestedObjects)',
'fn': 'lodash.flatten(nestedObjects, lodashFlattenDeep)',
'teardown': 'function flatten(){}'
})
.add(otherName, {
'fn': '_.flattenDeep(nestedObjects)',
'fn': '_.flatten(nestedObjects, _flattenDeep)',
'teardown': 'function flatten(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.flowRight`')
.add(buildName, {
'fn': 'lodash.flowRight(compAddThree, compAddTwo, compAddOne)',
'teardown': 'function flowRight(){}'
})
.add(otherName, {
'fn': '_.flowRight(compAddThree, compAddTwo, compAddOne)',
'teardown': 'function flowRight(){}'
})
);
suites.push(
Benchmark.Suite('composed call')
.add(buildName, {
'fn': 'lodashComposed(0)',
'teardown': 'function flowRight(){}'
})
.add(otherName, {
'fn': '_composed(0)',
'teardown': 'function flowRight(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.functions`')
.add(buildName, '\
@@ -1050,37 +1086,73 @@
suites.push(
Benchmark.Suite('`_.includes` searching an array')
.add(buildName, '\
lodash.includes(numbers, limit - 1)'
lodash.include(numbers, limit - 1)'
)
.add(otherName, '\
_.includes(numbers, limit - 1)'
_.include(numbers, limit - 1)'
)
);
suites.push(
Benchmark.Suite('`_.includes` searching an object')
.add(buildName, '\
lodash.includes(object, limit - 1)'
lodash.include(object, limit - 1)'
)
.add(otherName, '\
_.includes(object, limit - 1)'
_.include(object, limit - 1)'
)
);
if (lodash.includes('ab', 'ab') && _.includes('ab', 'ab')) {
if (lodash.include('ab', 'ab') && _.include('ab', 'ab')) {
suites.push(
Benchmark.Suite('`_.includes` searching a string')
.add(buildName, '\
lodash.includes(strNumbers, "," + (limit - 1))'
lodash.include(strNumbers, "," + (limit - 1))'
)
.add(otherName, '\
_.includes(strNumbers, "," + (limit - 1))'
_.include(strNumbers, "," + (limit - 1))'
)
);
}
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.indexBy` with `callback` iterating an array')
.add(buildName, '\
lodash.indexBy(numbers, function(num) { return num >> 1; })'
)
.add(otherName, '\
_.indexBy(numbers, function(num) { return num >> 1; })'
)
);
suites.push(
Benchmark.Suite('`_.indexBy` with `property` name iterating an array')
.add(buildName, {
'fn': 'lodash.indexBy(words, "length")',
'teardown': 'function countBy(){}'
})
.add(otherName, {
'fn': '_.indexBy(words, "length")',
'teardown': 'function countBy(){}'
})
);
suites.push(
Benchmark.Suite('`_.indexBy` with `callback` iterating an object')
.add(buildName, {
'fn': 'lodash.indexBy(wordToNumber, function(num) { return num >> 1; })',
'teardown': 'function countBy(){}'
})
.add(otherName, {
'fn': '_.indexBy(wordToNumber, function(num) { return num >> 1; })',
'teardown': 'function countBy(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.indexOf`')
.add(buildName, {
@@ -1093,6 +1165,18 @@
})
);
suites.push(
Benchmark.Suite('`_.indexOf` performing a binary search')
.add(buildName, {
'fn': 'lodash.indexOf(hundredSortedValues, 99, true)',
'teardown': 'function multiArrays(){}'
})
.add(otherName, {
'fn': '_.indexOf(hundredSortedValues, 99, true)',
'teardown': 'function multiArrays(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
@@ -1132,42 +1216,42 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.invokeMap` iterating an array')
Benchmark.Suite('`_.invoke` iterating an array')
.add(buildName, '\
lodash.invokeMap(numbers, "toFixed")'
lodash.invoke(numbers, "toFixed")'
)
.add(otherName, '\
_.invokeMap(numbers, "toFixed")'
_.invoke(numbers, "toFixed")'
)
);
suites.push(
Benchmark.Suite('`_.invokeMap` with arguments iterating an array')
Benchmark.Suite('`_.invoke` with arguments iterating an array')
.add(buildName, '\
lodash.invokeMap(numbers, "toFixed", 1)'
lodash.invoke(numbers, "toFixed", 1)'
)
.add(otherName, '\
_.invokeMap(numbers, "toFixed", 1)'
_.invoke(numbers, "toFixed", 1)'
)
);
suites.push(
Benchmark.Suite('`_.invokeMap` with a function for `path` iterating an array')
Benchmark.Suite('`_.invoke` with a function for `path` iterating an array')
.add(buildName, '\
lodash.invokeMap(numbers, Number.prototype.toFixed, 1)'
lodash.invoke(numbers, Number.prototype.toFixed, 1)'
)
.add(otherName, '\
_.invokeMap(numbers, Number.prototype.toFixed, 1)'
_.invoke(numbers, Number.prototype.toFixed, 1)'
)
);
suites.push(
Benchmark.Suite('`_.invokeMap` iterating an object')
Benchmark.Suite('`_.invoke` iterating an object')
.add(buildName, '\
lodash.invokeMap(object, "toFixed", 1)'
lodash.invoke(object, "toFixed", 1)'
)
.add(otherName, '\
_.invokeMap(object, "toFixed", 1)'
_.invoke(object, "toFixed", 1)'
)
);
@@ -1329,6 +1413,18 @@
})
);
suites.push(
Benchmark.Suite('`_.lastIndexOf` performing a binary search')
.add(buildName, {
'fn': 'lodash.lastIndexOf(hundredSortedValues, 0, true)',
'teardown': 'function multiArrays(){}'
})
.add(otherName, {
'fn': '_.lastIndexOf(hundredSortedValues, 0, true)',
'teardown': 'function multiArrays(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
@@ -1345,6 +1441,20 @@
)
);
suites.push(
Benchmark.Suite('`_.map` with `thisArg` iterating an array (slow path)')
.add(buildName, '\
lodash.map(objects, function(value, index) {\
return this["key" + index] + value.num;\
}, object)'
)
.add(otherName, '\
_.map(objects, function(value, index) {\
return this["key" + index] + value.num;\
}, object)'
)
);
suites.push(
Benchmark.Suite('`_.map` iterating an object')
.add(buildName, '\
@@ -1359,16 +1469,6 @@
)
);
suites.push(
Benchmark.Suite('`_.map` with `_.property` shorthand')
.add(buildName, '\
lodash.map(objects, "num")'
)
.add(otherName, '\
_.map(objects, "num")'
)
);
/*--------------------------------------------------------------------------*/
suites.push(
@@ -1419,6 +1519,18 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.pairs`')
.add(buildName, '\
lodash.pairs(object)'
)
.add(otherName, '\
_.pairs(object)'
)
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.partial` (slow path)')
.add(buildName, {
@@ -1459,6 +1571,20 @@
)
);
suites.push(
Benchmark.Suite('`_.partition` iterating an array with `thisArg` (slow path)')
.add(buildName, '\
lodash.partition(numbers, function(num, index) {\
return this["key" + index] % 2;\
}, object)'
)
.add(otherName, '\
_.partition(numbers, function(num, index) {\
return this["key" + index] % 2;\
}, object)'
)
);
suites.push(
Benchmark.Suite('`_.partition` iterating an object')
.add(buildName, '\
@@ -1487,6 +1613,18 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.pluck`')
.add(buildName, '\
lodash.pluck(objects, "num")'
)
.add(otherName, '\
_.pluck(objects, "num")'
)
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.reduce` iterating an array')
.add(buildName, '\
@@ -1569,6 +1707,20 @@
)
);
suites.push(
Benchmark.Suite('`_.reject` iterating an array with `thisArg` (slow path)')
.add(buildName, '\
lodash.reject(numbers, function(num, index) {\
return this["key" + index] % 2;\
}, object)'
)
.add(otherName, '\
_.reject(numbers, function(num, index) {\
return this["key" + index] % 2;\
}, object)'
)
);
suites.push(
Benchmark.Suite('`_.reject` iterating an object')
.add(buildName, '\
@@ -1586,12 +1738,12 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.sampleSize`')
Benchmark.Suite('`_.sample` with an `n`')
.add(buildName, '\
lodash.sampleSize(numbers, limit / 2)'
lodash.sample(numbers, limit / 2)'
)
.add(otherName, '\
_.sampleSize(numbers, limit / 2)'
_.sample(numbers, limit / 2)'
)
);
@@ -1635,6 +1787,20 @@
)
);
suites.push(
Benchmark.Suite('`_.some` with `thisArg` iterating an array (slow path)')
.add(buildName, '\
lodash.some(objects, function(value, index) {\
return this["key" + index] == (limit - 1);\
}, object)'
)
.add(otherName, '\
_.some(objects, function(value, index) {\
return this["key" + index] == (limit - 1);\
}, object)'
)
);
suites.push(
Benchmark.Suite('`_.some` iterating an object')
.add(buildName, '\
@@ -1661,6 +1827,16 @@
)
);
suites.push(
Benchmark.Suite('`_.sortBy` with `callback` and `thisArg` (slow path)')
.add(buildName, '\
lodash.sortBy(numbers, function(num) { return this.sin(num); }, Math)'
)
.add(otherName, '\
_.sortBy(numbers, function(num) { return this.sin(num); }, Math)'
)
);
suites.push(
Benchmark.Suite('`_.sortBy` with `property` name')
.add(buildName, {
@@ -1685,20 +1861,18 @@
)
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.sortedIndexBy`')
Benchmark.Suite('`_.sortedIndex` with `callback`')
.add(buildName, {
'fn': '\
lodash.sortedIndexBy(words, "twenty-five", function(value) {\
lodash.sortedIndex(words, "twenty-five", function(value) {\
return wordToNumber[value];\
})',
'teardown': 'function countBy(){}'
})
.add(otherName, {
'fn': '\
_.sortedIndexBy(words, "twenty-five", function(value) {\
_.sortedIndex(words, "twenty-five", function(value) {\
return wordToNumber[value];\
})',
'teardown': 'function countBy(){}'
@@ -1707,34 +1881,6 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.sortedIndexOf`')
.add(buildName, {
'fn': 'lodash.sortedIndexOf(hundredSortedValues, 99)',
'teardown': 'function multiArrays(){}'
})
.add(otherName, {
'fn': '_.sortedIndexOf(hundredSortedValues, 99)',
'teardown': 'function multiArrays(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.sortedLastIndexOf`')
.add(buildName, {
'fn': 'lodash.sortedLastIndexOf(hundredSortedValues, 0)',
'teardown': 'function multiArrays(){}'
})
.add(otherName, {
'fn': '_.sortedLastIndexOf(hundredSortedValues, 0)',
'teardown': 'function multiArrays(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.sum`')
.add(buildName, '\
@@ -1797,6 +1943,18 @@
)
);
suites.push(
Benchmark.Suite('`_.times` with `thisArg` (slow path)')
.add(buildName, '\
var result = [];\
lodash.times(limit, function(n) { result.push(this.sin(n)); }, Math)'
)
.add(otherName, '\
var result = [];\
_.times(limit, function(n) { result.push(this.sin(n)); }, Math)'
)
);
/*--------------------------------------------------------------------------*/
suites.push(
@@ -1821,18 +1979,6 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.toPairs`')
.add(buildName, '\
lodash.toPairs(object)'
)
.add(otherName, '\
_.toPairs(object)'
)
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.unescape` string without html entities')
.add(buildName, '\
@@ -1889,6 +2035,20 @@
)
);
suites.push(
Benchmark.Suite('`_.uniq` with `callback`')
.add(buildName, '\
lodash.uniq(numbers.concat(twoNumbers, fourNumbers), function(num) {\
return num % 2;\
})'
)
.add(otherName, '\
_.uniq(numbers.concat(twoNumbers, fourNumbers), function(num) {\
return num % 2;\
})'
)
);
suites.push(
Benchmark.Suite('`_.uniq` iterating an array of 200 elements')
.add(buildName, {
@@ -1903,22 +2063,6 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.uniqBy`')
.add(buildName, '\
lodash.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
return num % 2;\
})'
)
.add(otherName, '\
_.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
return num % 2;\
})'
)
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.values`')
.add(buildName, '\
@@ -1931,6 +2075,20 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.where`')
.add(buildName, {
'fn': 'lodash.where(objects, source)',
'teardown': 'function matches(){}'
})
.add(otherName, {
'fn': '_.where(objects, source)',
'teardown': 'function matches(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.without`')
.add(buildName, '\

14
perf/run-perf.sh Executable file
View File

@@ -0,0 +1,14 @@
cd "$(dirname "$0")"
echo "Running performance suite in node..."
node perf.js ../lodash.js && node perf.js ../lodash.min.js
for cmd in rhino "rhino -require" narwhal ringo phantomjs; do
echo ""
echo "Running performance suite in $cmd..."
$cmd perf.js ../lodash.src.js
done
echo ""
echo "Running performance suite in a browser..."
open index.html

157
test/asset/set.js Normal file
View File

@@ -0,0 +1,157 @@
;(function() {
/** Used to determine if values are of the language type Object. */
var objectTypes = {
'function': true,
'object': true
};
/** Used as the `Set#toString` return value. */
var nativeString = String(Object.prototype.toString).replace(/toString/g, 'Set');
/** Detect free variable `exports`. */
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Detect free variable `global` from Node.js. */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
/** Detect free variable `self`. */
var freeSelf = objectTypes[typeof self] && self && self.Object && self;
/** Detect free variable `window`. */
var freeWindow = objectTypes[typeof window] && window && window.Object && window;
/**
* Used as a reference to the global object.
*
* The `this` value is used if it is the global object to avoid Greasemonkey's
* restricted `window` object, otherwise the `window` object is used.
*/
var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
/*--------------------------------------------------------------------------*/
/**
* Installs `Set` on the given `context` object.
*
* @memberOf exports
* @param {Object} context The context object.
*/
function runInContext(context) {
/**
* Creates a `Set` object.
*/
function Set() {
this.__cache__ = {};
}
/**
* Gets the index at which the first occurrence of `value` is found using
* strict equality for comparisons, i.e. `===`.
*
* @private
* @param {Array} array The array to search.
* @param {*} value The value to search for.
* @returns {number} Returns the index of the matched value or `-1`.
*/
function indexOf(array, value) {
var index = -1,
length = array.length;
while (++index < length) {
if (array[index] === value) {
return index;
}
}
return -1;
}
/**
* Checks if `value` is in the set.
*
* @memberOf Set
* @param {*} value The value to search for.
* @returns {boolean} Returns `true` if `value` is found, else `false`.
*/
function has(value) {
var type = typeof value,
cache = this.__cache__;
if (type == 'boolean' || value == null) {
return cache[value] || false;
}
if (type != 'number' && type != 'string') {
type = 'object';
}
var key = type == 'number' ? value : '_' + value;
cache = (cache = cache[type]) && cache[key];
return type == 'object'
? (cache && indexOf(cache, value) > -1 ? true : false)
: (cache || false);
}
/**
* Adds `value` to the set.
*
* @memberOf Set
* @param {*} value The value to add.
*/
function add(value) {
var cache = this.__cache__,
type = typeof value;
if (type == 'boolean' || value == null) {
cache[value] = true;
} else {
if (type != 'number' && type != 'string') {
type = 'object';
}
var key = type == 'number' ? value : '_' + value,
typeCache = cache[type] || (cache[type] = {});
if (type == 'object') {
var array = typeCache[key];
if (array) {
array.push(value);
} else {
typeCache[key] = [value];
}
} else {
typeCache[key] = true;
}
}
}
/**
* Produces the `toString` result of `Set`.
*
* @static
* @memberOf Set
* @returns {string} Returns the string result.
*/
function toString() {
return nativeString;
}
Set.toString = toString;
Set.prototype.add = add;
Set.prototype.has = has;
if (!root.Set) {
context.Set = Set;
}
}
/*--------------------------------------------------------------------------*/
if (freeExports) {
freeExports.runInContext = runInContext;
} else {
runInContext(root);
}
}.call(this));

View File

@@ -64,10 +64,12 @@
buildList.selectedIndex = (function() {
switch (build) {
case 'lodash': return 1;
case 'lodash-core-dev': return 2;
case 'lodash-core': return 3;
case 'lodash-dev':
case 'lodash-compat': return 1;
case 'lodash-modern-dev': return 2;
case 'lodash-modern': return 3;
case 'lodash-custom-dev': return 4;
case 'lodash-custom': return 5;
case 'lodash-compat-dev':
case null: return 0;
}
return -1;
@@ -93,10 +95,12 @@
span1.innerHTML =
'<label for="qunit-build">Build: </label>' +
'<select id="qunit-build">' +
'<option value="lodash-dev">lodash (development)</option>' +
'<option value="lodash">lodash (production)</option>' +
'<option value="lodash-core-dev">lodash-core (development)</option>' +
'<option value="lodash-core">lodash-core (production)</option>' +
'<option value="lodash-compat-dev">lodash (compat development)</option>' +
'<option value="lodash-compat">lodash (compat production)</option>' +
'<option value="lodash-modern-dev">lodash (modern development)</option>' +
'<option value="lodash-modern">lodash (modern production)</option>' +
'<option value="lodash-custom-dev">lodash (custom development)</option>' +
'<option value="lodash-custom">lodash (custom production)</option>' +
'</select>';
var span2 = document.createElement('span');
@@ -120,15 +124,29 @@
init();
});
// Used to indicate testing a foreign file.
ui.isForeign = RegExp('^(\\w+:)?//').test(build);
// Used to indicate testing a modularized build.
ui.isModularize = /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test([location.pathname, location.search]);
// Used to indicate testing in Sauce Labs' automated test cloud.
ui.isSauceLabs = location.port == '9001';
// Used to indicate that lodash is in strict mode.
ui.isStrict = /\bes6?\b/.test([location.pathname, location.search]);
// The lodash build file path.
ui.buildPath = (function() {
var result;
switch (build) {
case 'lodash': result = 'dist/lodash.min.js'; break;
case 'lodash-core-dev': result = 'dist/lodash.core.js'; break;
case 'lodash-core': result = 'dist/lodash.core.min.js'; break;
case null: build = 'lodash-dev';
case 'lodash-dev': result = 'lodash.js'; break;
case 'lodash-compat': result = 'lodash.compat.min.js'; break;
case 'lodash-modern-dev': result = 'lodash.js'; break;
case 'lodash-modern': result = 'lodash.min.js'; break;
case 'lodash-custom-dev': result = 'lodash.custom.js'; break;
case 'lodash-custom': result = 'lodash.custom.min.js'; break;
case null: build = 'lodash-compat-dev';
case 'lodash-compat-dev': result = 'lodash.src.js'; break;
default: return build;
}
return basePath + result;
@@ -147,21 +165,6 @@
return basePath + result;
}());
// Used to indicate testing a core build.
ui.isCore = /\bcore(\.min)?\.js\b/.test(ui.buildPath);
// Used to indicate testing a foreign file.
ui.isForeign = RegExp('^(\\w+:)?//').test(build);
// Used to indicate testing a modularized build.
ui.isModularize = /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test([location.pathname, location.search]);
// Used to indicate testing in Sauce Labs' automated test cloud.
ui.isSauceLabs = location.port == '9001';
// Used to indicate that lodash is in strict mode.
ui.isStrict = /\bes\b/.test([location.pathname, location.search]);
ui.urlParams = { 'build': build, 'loader': loader };
ui.timing = { 'loadEventEnd': 0 };

102
test/asset/weakmap.js Normal file
View File

@@ -0,0 +1,102 @@
;(function() {
/** Used to determine if values are of the language type Object. */
var objectTypes = {
'function': true,
'object': true
};
/** Used as the `WeakMap#toString` return value. */
var nativeString = String(Object.prototype.toString).replace(/toString/g, 'WeakMap');
/** Detect free variable `exports`. */
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Detect free variable `global` from Node.js. */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
/** Detect free variable `self`. */
var freeSelf = objectTypes[typeof self] && self && self.Object && self;
/** Detect free variable `window`. */
var freeWindow = objectTypes[typeof window] && window && window.Object && window;
/**
* Used as a reference to the global object.
*
* The `this` value is used if it is the global object to avoid Greasemonkey's
* restricted `window` object, otherwise the `window` object is used.
*/
var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
/*--------------------------------------------------------------------------*/
/**
* Installs `WeakMap` on the given `context` object.
*
* @memberOf exports
* @param {Object} context The context object.
*/
function runInContext(context) {
/**
* Creates a `WeakMap` object.
*/
function WeakMap() {
// No operation performed.
}
/**
* Gets the value associated with the given key.
*
* @memberOf WeakMap
* @param {Object} key The key object.
* @returns {*} Returns the associated value, else `undefined`.
*/
function get(key) {
return key.__weakmap__;
}
/**
* Sets a value for the given key.
*
* @memberOf WeakMap
* @param {Object} key The key object.
* @param {*} value The value to set.
*/
function set(key, value) {
key.__weakmap__ = value;
return this;
}
/**
* Produces the `toString` result of `WeakMap`.
*
* @static
* @memberOf WeakMap
* @returns {string} Returns the string result.
*/
function toString() {
return nativeString;
}
WeakMap.toString = toString;
WeakMap.prototype.get = get;
WeakMap.prototype.set = set;
if (!root.WeakMap) {
context.WeakMap = WeakMap;
}
}
/*--------------------------------------------------------------------------*/
if (freeExports) {
freeExports.runInContext = runInContext;
} else {
runInContext(root);
}
}.call(this));

View File

@@ -4,7 +4,7 @@ addEventListener('message', function(e) {
if (e.data) {
try {
importScripts('../' + e.data);
} catch (e) {
} catch(e) {
self._ = { 'VERSION': e.message };
}
postMessage(_.VERSION);

View File

@@ -22,67 +22,27 @@
<script src="../vendor/json-js/json2.js"></script>
<script src="../node_modules/platform/platform.js"></script>
<script src="./asset/test-ui.js"></script>
<script src="../lodash.js"></script>
<script src="../lodash.src.js"></script>
<script>
QUnit.config.asyncRetries = 10;
QUnit.config.hidepassed = true;
var mixinPrereqs = (function() {
var aliasToReal = {
'indexBy': 'keyBy',
'invoke': 'invokeMap'
};
var keyMap = {
'rest': 'tail'
};
var lodash = _.noConflict();
return function(_) {
lodash.defaultsDeep(_, { 'templateSettings': lodash.templateSettings });
lodash.mixin(_, lodash.pick(lodash, lodash.difference([
'countBy',
'debounce',
'difference',
'find',
'findIndex',
'findLastIndex',
'groupBy',
'includes',
'invert',
'invokeMap',
'keyBy',
'omit',
'partition',
'reduceRight',
'reject',
'sample',
'without'
], lodash.functions(_))));
lodash.forOwn(keyMap, function(realName, otherName) {
_[otherName] = lodash[realName];
_.prototype[otherName] = lodash.prototype[realName];
});
lodash.forOwn(aliasToReal, function(realName, alias) {
_[alias] = _[realName];
_.prototype[alias] = _.prototype[realName];
_.mixin({
'debounce': _.debounce || lodash.debounce,
'defer': _.defer || lodash.defer,
'pluck': _.pluck || lodash.pluck
});
};
}());
// Load prerequisite scripts.
document.write(ui.urlParams.loader == 'none'
? '<script src="' + ui.buildPath + '"><\/script>'
: '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
);
</script>
<script>
if (ui.urlParams.loader == 'none') {
mixinPrereqs(_);
document.write([
QUnit.config.asyncRetries = 10;
QUnit.config.hidepassed = true;
// Load test scripts.
document.write(ui.urlParams.loader != 'none'
? '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
: ([
'<script src="' + ui.buildPath + '"><\/script>',
'<script src="../node_modules/jquery/dist/jquery.js"><\/script>',
'<script src="../vendor/backbone/backbone.js"><\/script>',
'<script src="../vendor/backbone/test/setup/dom-setup.js"><\/script>',
@@ -94,8 +54,8 @@
'<script src="../vendor/backbone/test/router.js"><\/script>',
'<script src="../vendor/backbone/test/view.js"><\/script>',
'<script src="../vendor/backbone/test/sync.js"><\/script>'
].join('\n'));
}
].join('\n'))
);
</script>
<script>
(function() {
@@ -103,6 +63,7 @@
curl.config({ 'apiName': 'require' });
}
if (!window.require) {
mixinPrereqs(_);
return;
}
var reBasename = /[\w.-]+$/,
@@ -146,22 +107,24 @@
QUnit.config.autostart = false;
require(getConfig(), ['underscore'], function(lodash) {
require(getConfig(), ['underscore', 'backbone'], function(lodash) {
mixinPrereqs(lodash);
require(getConfig(), ['backbone'], function() {
require(getConfig(), [
'test/setup/dom-setup',
'test/setup/environment',
'test/noconflict',
'test/events',
'test/model',
'test/collection',
'test/router',
'test/view',
'test/sync'
], function() {
QUnit.start();
});
if (ui.isModularize) {
window._ = lodash;
}
require(getConfig(), [
'test/setup/dom-setup',
'test/setup/environment',
'test/noconflict',
'test/events',
'test/model',
'test/collection',
'test/router',
'test/view',
'test/sync'
], function() {
QUnit.start();
});
});
}());

View File

@@ -1,41 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>lodash-fp Test Suite</title>
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
</head>
<body>
<script>
// Avoid reporting tests to Sauce Labs when script errors occur.
if (location.port == '9001') {
window.onerror = function(message) {
if (window.QUnit) {
QUnit.config.done.length = 0;
}
global_test_results = { 'message': message };
};
}
</script>
<script src="../lodash.js"></script>
<script src="../dist/lodash.fp.js"></script>
<script src="../dist/mapping.fp.js"></script>
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<script src="../node_modules/qunit-extras/qunit-extras.js"></script>
<script src="../node_modules/platform/platform.js"></script>
<script src="./test-fp.js"></script>
<div id="qunit"></div>
<script>
// Set a more readable browser name.
window.onload = function() {
var timeoutId = setInterval(function() {
var ua = document.getElementById('qunit-userAgent');
if (ua) {
ua.innerHTML = platform;
clearInterval(timeoutId);
}
}, 16);
};
</script>
</body>
</html>

View File

@@ -5,7 +5,7 @@
<title>lodash Test Suite</title>
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
<style>
#exports, #module {
#exports {
display: none;
}
</style>
@@ -22,33 +22,35 @@
};
}
</script>
<script src="../node_modules/lodash/index.js"></script>
<script>var lodashStable = _.noConflict();</script>
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<script src="../node_modules/qunit-extras/qunit-extras.js"></script>
<script src="../node_modules/platform/platform.js"></script>
<script src="./asset/set.js"></script>
<script src="./asset/weakmap.js"></script>
<script src="./asset/test-ui.js"></script>
<div id="qunit"></div>
<div id="exports"></div>
<div id="module"></div>
<script>
function setProperty(object, key, value) {
try {
Object.defineProperty(object, key, {
'configurable': true,
'enumerable': false,
'writable': true,
'value': value
});
} catch (e) {
object[key] = value;
}
return object;
}
var setProperty = (function() {
var _defineProperty = Object.defineProperty;
return function(object, key, value) {
try {
_defineProperty(object, key, {
'configurable': true,
'enumerable': false,
'writable': true,
'value': value
});
} catch(e) {
object[key] = value;
}
};
}());
function addBizarroMethods() {
var funcProto = Function.prototype,
objectProto = Object.prototype;
objectProto = Object.prototype,
stringProto = String.prototype;
var hasOwnProperty = objectProto.hasOwnProperty,
fnToString = funcProto.toString,
@@ -62,11 +64,9 @@
return value;
};
}
function createToString(funcName) {
return constant(nativeString.replace(reToString, funcName));
}
// Allow bypassing native checks.
setProperty(funcProto, 'toString', (function() {
function wrapper() {
@@ -82,49 +82,29 @@
funcProto._method = noop;
// Set bad shims.
setProperty(Object, '_create', Object.create);
setProperty(Object, 'create', (function() {
function object() {}
return function(prototype) {
if (prototype === Object(prototype)) {
object.prototype = prototype;
var result = new object;
object.prototype = undefined;
}
return result || {};
};
}()));
setProperty(Array, '_isArray', Array.isArray);
setProperty(Array, 'isArray', noop);
setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols);
setProperty(Object, 'getOwnPropertySymbols', undefined);
setProperty(Date, '_now', Date.now);
setProperty(Date, 'now', noop);
setProperty(Object, '_keys', Object.keys);
setProperty(Object, 'keys', noop);
setProperty(objectProto, '_propertyIsEnumerable', propertyIsEnumerable);
setProperty(objectProto, 'propertyIsEnumerable', function(key) {
return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
if (key == '1' && this && typeof this == 'object' &&
hasOwnProperty.call(this, 'callee') &&
!propertyIsEnumerable.call(this, 'callee') &&
this.length === 2 && this[0] === 1 && this[1] === 0) {
throw new Error;
}
return propertyIsEnumerable.call(this, key);
});
setProperty(window, '_Map', window.Map);
if (_Map) {
setProperty(window, 'Map', (function(Map) {
var count = 0;
return function() {
if (count++) {
return new Map;
}
var result = {};
setProperty(window, 'Map', Map);
return result;
};
}(_Map)));
setProperty(Map, 'toString', createToString('Map'));
}
setProperty(window, '_Set', window.Set);
setProperty(window, 'Set', noop);
setProperty(window, '_Symbol', window.Symbol);
setProperty(window, 'Symbol', undefined);
setProperty(window, '_WeakMap', window.WeakMap);
setProperty(window, 'WeakMap', noop);
@@ -139,52 +119,46 @@
function removeBizarroMethods() {
var funcProto = Function.prototype,
objectProto = Object.prototype;
objectProto = Object.prototype,
stringProto = String.prototype;
setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable);
if (Object._create) {
Object.create = Object._create;
if (Array._isArray) {
setProperty(Array, 'isArray', Array._isArray);
} else {
delete Object.create;
delete Array.isArray;
}
if (Object._getOwnPropertySymbols) {
Object.getOwnPropertySymbols = Object._getOwnPropertySymbols;
if (Date._now) {
setProperty(Date, 'now', Date._now);
} else {
delete Object.getOwnPropertySymbols;
delete Date.now;
}
if (_Map) {
Map = _Map;
if (Object._keys) {
setProperty(Object, 'keys', Object._keys);
} else {
setProperty(window, 'Map', undefined);
delete Object.keys;
}
if (_Set) {
if (window._Set) {
Set = _Set;
} else {
setProperty(window, 'Set', undefined);
}
if (_Symbol) {
Symbol = _Symbol;
}
if (_WeakMap) {
WeakMap = _WeakMap;
} else {
setProperty(window, 'WeakMap', undefined);
}
setProperty(window, '_Map', undefined);
setProperty(window, '_Set', undefined);
setProperty(window, '_Symbol', undefined);
if (window._WeakMap) {
WeakMap = _WeakMap;
}
setProperty(window, '_WeakMap', undefined);
setProperty(window, 'WinRTError', undefined);
setProperty(window, 'exports', document.getElementById('exports'));
setProperty(window, 'exports', undefined);
setProperty(window, 'global', undefined);
setProperty(window, 'module', document.getElementById('module'));
setProperty(window, 'module', undefined);
setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable);
delete Array._isArray;
delete Date._now;
delete Object._keys;
delete funcProto._method;
delete Object._create;
delete Object._getOwnPropertySymbols;
delete objectProto._propertyIsEnumerable;
}
@@ -292,17 +266,20 @@
underscoreModule = underscore.result(underscore, 'noConflict') || underscore;
underscoreModule.moduleName = 'underscore';
}
window._ = lodash;
if (ui.isModularize) {
window._ = lodash;
}
if (ui.isModularize) {
require(getConfig(), [
'lodash/internal/baseEach',
'lodash/internal/isIndex',
'lodash/internal/isIterateeCall'
], function(baseEach, isIndex, isIterateeCall) {
'lodash/internal/isIterateeCall',
'lodash/internal/isLength'
], function(baseEach, isIndex, isIterateeCall, isLength) {
lodash._baseEach = baseEach;
lodash._isIndex = isIndex;
lodash._isIterateeCall = isIterateeCall;
lodash._isLength = isLength;
loadTests();
});
} else {

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env node
'use strict';
var fs = require('fs'),
path = require('path');
var args = (args = process.argv)
.slice((args[0] === process.execPath || args[0] === 'node') ? 2 : 0);
var filePath = path.resolve(args[1]),
reLine = /.*/gm,
slice = Array.prototype.slice;
var pattern = (function() {
var result = args[0],
delimiter = result.charAt(0),
lastIndex = result.lastIndexOf(delimiter);
return RegExp(result.slice(1, lastIndex), result.slice(lastIndex + 1));
}());
/*----------------------------------------------------------------------------*/
fs.writeFileSync(filePath, fs.readFileSync(filePath, 'utf8').replace(pattern, function(match) {
var snippet = slice.call(arguments, -3, -1)[0];
return match.replace(snippet, snippet.replace(reLine, ''));
}));

14
test/run-test.sh Normal file
View File

@@ -0,0 +1,14 @@
cd "$(dirname "$0")"
echo "Testing in node..."
node test.js ../lodash.src.js
for cmd in rhino "rhino -require" ringo phantomjs; do
echo ""
echo "Testing in $cmd..."
$cmd test.js ../lodash.src.js
done
echo ""
echo "Testing in a browser..."
open index.html

View File

@@ -17,7 +17,7 @@ var EventEmitter = require('events').EventEmitter,
util = require('util');
/** Load other modules. */
var _ = require('../lodash.js'),
var _ = require('../lodash.src.js'),
chalk = require('chalk'),
ecstatic = require('ecstatic'),
request = require('request'),
@@ -102,18 +102,26 @@ var browserNameMap = {
/** List of platforms to load the runner on. */
var platforms = [
['Linux', 'android', '5.1'],
['Windows 10', 'chrome', '48'],
['Windows 10', 'chrome', '47'],
['Windows 10', 'firefox', '44'],
['Windows 10', 'firefox', '43'],
['Windows 10', 'microsoftedge', '20.10240'],
['Windows 10', 'internet explorer', '11'],
['Linux', 'android', '5.0'],
['Linux', 'android', '4.4'],
['Linux', 'android', '4.0'],
['Windows 8.1', 'firefox', '38'],
['Windows 8.1', 'firefox', '37'],
['Windows 8.1', 'firefox', '20'],
['Windows 8.1', 'chrome', '43'],
['Windows 8.1', 'chrome', '42'],
['Windows 8.1', 'internet explorer', '11'],
['Windows 8', 'internet explorer', '10'],
['Windows 7', 'internet explorer', '9'],
// ['OS X 10.10', 'ipad', '9.1'],
['OS X 10.11', 'safari', '9'],
['OS X 10.10', 'safari', '8']
['Windows 7', 'internet explorer', '8'],
['Windows XP', 'internet explorer', '7'],
['Windows XP', 'internet explorer', '6'],
['OS X 10.9', 'ipad', '8.1'],
['OS X 10.6', 'ipad', '4'],
['OS X 10.10', 'safari', '8'],
['OS X 10.9', 'safari', '7'],
['OS X 10.8', 'safari', '6'],
['OS X 10.6', 'safari', '5']
];
/** Used to tailor the `platforms` array. */
@@ -124,7 +132,7 @@ var isAMD = _.includes(tags, 'amd'),
// The platforms to test IE compatibility modes.
if (compatMode) {
platforms = [
['Windows 10', 'internet explorer', '11'],
['Windows 8.1', 'internet explorer', '11'],
['Windows 8', 'internet explorer', '10'],
['Windows 7', 'internet explorer', '9'],
['Windows 7', 'internet explorer', '8']
@@ -268,7 +276,7 @@ function isJobId(value) {
*/
function logInline(text) {
var blankLine = _.repeat(' ', _.size(prevLine));
prevLine = text = _.truncate(text, { 'length': 40 });
prevLine = text = _.trunc(text, 40);
process.stdout.write(text + blankLine.slice(text.length) + '\r');
}
@@ -290,7 +298,7 @@ function logThrobber() {
* @returns {Array} Returns the new converted array.
*/
function optionToArray(name, string) {
return _.compact(_.invokeMap((optionToValue(name, string) || '').split(/, */), 'trim'));
return _.compact(_.invoke((optionToValue(name, string) || '').split(/, */), 'trim'));
}
/**
@@ -552,7 +560,7 @@ util.inherits(Job, EventEmitter);
* @param {Object} Returns the job instance.
*/
Job.prototype.remove = function(callback) {
this.once('remove', _.iteratee(callback));
this.once('remove', _.callback(callback));
if (this.removing) {
return this;
}
@@ -577,7 +585,7 @@ Job.prototype.remove = function(callback) {
* @param {Object} Returns the job instance.
*/
Job.prototype.reset = function(callback) {
this.once('reset', _.iteratee(callback));
this.once('reset', _.callback(callback));
if (this.resetting) {
return this;
}
@@ -593,7 +601,7 @@ Job.prototype.reset = function(callback) {
* @param {Object} Returns the job instance.
*/
Job.prototype.restart = function(callback) {
this.once('restart', _.iteratee(callback));
this.once('restart', _.callback(callback));
if (this.restarting) {
return this;
}
@@ -618,7 +626,7 @@ Job.prototype.restart = function(callback) {
* @param {Object} Returns the job instance.
*/
Job.prototype.start = function(callback) {
this.once('start', _.iteratee(callback));
this.once('start', _.callback(callback));
if (this.starting || this.running) {
return this;
}
@@ -639,7 +647,7 @@ Job.prototype.start = function(callback) {
* @param {Object} Returns the job instance.
*/
Job.prototype.status = function(callback) {
this.once('status', _.iteratee(callback));
this.once('status', _.callback(callback));
if (this.checking || this.removing || this.resetting || this.restarting || this.starting || this.stopping) {
return this;
}
@@ -661,7 +669,7 @@ Job.prototype.status = function(callback) {
* @param {Object} Returns the job instance.
*/
Job.prototype.stop = function(callback) {
this.once('stop', _.iteratee(callback));
this.once('stop', _.callback(callback));
if (this.stopping) {
return this;
}
@@ -699,14 +707,14 @@ function Tunnel(properties) {
var active = [],
queue = [];
var all = _.map(this.platforms, _.bind(function(platform) {
var all = _.map(this.platforms, function(platform) {
return new Job(_.merge({
'user': this.user,
'pass': this.pass,
'tunnel': this,
'options': { 'platforms': [platform] }
}, this.job));
}, this));
}, this);
var completed = 0,
restarted = [],
@@ -714,7 +722,7 @@ function Tunnel(properties) {
total = all.length,
tunnel = this;
_.invokeMap(all, 'on', 'complete', function() {
_.invoke(all, 'on', 'complete', function() {
_.pull(active, this);
if (success) {
success = !this.failed;
@@ -726,7 +734,7 @@ function Tunnel(properties) {
tunnel.dequeue();
});
_.invokeMap(all, 'on', 'restart', function() {
_.invoke(all, 'on', 'restart', function() {
if (!_.includes(restarted, this)) {
restarted.push(this);
}
@@ -760,7 +768,7 @@ util.inherits(Tunnel, EventEmitter);
* @param {Function} callback The function called once the tunnel is restarted.
*/
Tunnel.prototype.restart = function(callback) {
this.once('restart', _.iteratee(callback));
this.once('restart', _.callback(callback));
if (this.restarting) {
return this;
}
@@ -774,7 +782,7 @@ Tunnel.prototype.restart = function(callback) {
all = jobs.all;
var reset = _.after(all.length, _.bind(this.stop, this, onGenericRestart)),
stop = _.after(active.length, _.partial(_.invokeMap, all, 'reset', reset));
stop = _.after(active.length, _.partial(_.invoke, all, 'reset', reset));
if (_.isEmpty(active)) {
_.defer(stop);
@@ -782,7 +790,7 @@ Tunnel.prototype.restart = function(callback) {
if (_.isEmpty(all)) {
_.defer(reset);
}
_.invokeMap(active, 'stop', function() {
_.invoke(active, 'stop', function() {
_.pull(active, this);
stop();
});
@@ -802,7 +810,7 @@ Tunnel.prototype.restart = function(callback) {
* @param {Object} Returns the tunnel instance.
*/
Tunnel.prototype.start = function(callback) {
this.once('start', _.iteratee(callback));
this.once('start', _.callback(callback));
if (this.starting || this.running) {
return this;
}
@@ -845,7 +853,7 @@ Tunnel.prototype.dequeue = function() {
* @param {Object} Returns the tunnel instance.
*/
Tunnel.prototype.stop = function(callback) {
this.once('stop', _.iteratee(callback));
this.once('stop', _.callback(callback));
if (this.stopping) {
return this;
}
@@ -870,7 +878,7 @@ Tunnel.prototype.stop = function(callback) {
if (_.isEmpty(active)) {
_.defer(stop);
}
_.invokeMap(active, 'stop', function() {
_.invoke(active, 'stop', function() {
_.pull(active, this);
stop();
});

File diff suppressed because it is too large Load Diff

24766
test/test.js

File diff suppressed because it is too large Load Diff

View File

@@ -23,94 +23,50 @@
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../node_modules/platform/platform.js"></script>
<script src="./asset/test-ui.js"></script>
<script src="../lodash.js"></script>
<script>
QUnit.config.asyncRetries = 10;
QUnit.config.hidepassed = true;
// Excuse tests we intentionally fail or those with problems.
QUnit.config.excused = {
'Arrays': {
'difference': [
'can perform an OO-style difference'
],
'drop': [
'is an alias for rest'
'alias for rest'
],
'first': [
'returns an empty array when n <= 0 (0 case)',
'returns an empty array when n <= 0 (negative case)',
'can fetch the first n elements',
'returns the whole array if n > length'
],
'findIndex': [
'called with context'
],
'findLastIndex': [
'called with context'
],
'flatten': [
'supports empty arrays',
'can flatten nested arrays',
'works on an arguments object',
'can handle very deep arrays'
],
'head': [
'is an alias for first'
],
'indexOf': [
"sorted indexOf doesn't uses binary search",
'can pass an index to first',
'[1,2]',
'0'
],
'flatten': [
'Flattens empty arrays',
'can flatten nested arrays',
'can shallowly flatten nested arrays',
'works on an arguments object',
'can shallowly flatten arrays containing only other arrays'
],
'initial': [
'returns all but the last n elements',
'returns an empty array when n > length',
'works on an arguments object'
'initial can take an index',
'initial can take a large index',
'initial works on arguments object'
],
'intersection': [
'can perform an OO-style intersection'
],
'last': [
'returns an empty array when n <= 0 (0 case)',
'returns an empty array when n <= 0 (negative case)',
'can fetch the last n elements',
'returns the whole array if n > length'
'can pass an index to last',
'0'
],
'lastIndexOf': [
'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`',
'should treat non-number `fromIndex` values as `array.length`',
'[0,-1,-1]'
],
'object': [
'an array of pairs zipped together into an object',
'an object converted to pairs and back to an object'
],
'range': [
'range with two arguments a &amp; b, b&lt;a generates an empty array'
],
'rest': [
'returns the whole array when index is 0',
'returns elements starting at the given index',
'works on an arguments object'
],
'sortedIndex': [
'2',
'3'
],
'tail': [
'is an alias for rest'
'working rest(0)',
'rest can take an index',
'works on arguments object'
],
'take': [
'is an alias for first'
],
'uniq': [
'uses the result of `iterator` for uniqueness comparisons (unsorted case)',
'`sorted` argument defaults to false when omitted',
'when `iterator` is a string, uses that key for comparisons (unsorted case)',
'uses the result of `iterator` for uniqueness comparisons (sorted case)',
'when `iterator` is a string, uses that key for comparisons (sorted case)',
'can use falsey pluck like iterator'
],
'union': [
'can perform an OO-style union'
'alias for first'
]
},
'Chaining': {
@@ -122,120 +78,20 @@
]
},
'Collections': {
'lookupIterator with contexts': true,
'Iterating objects with sketchy length properties': true,
'Resistant to collection length and properties changing while iterating': true,
'countBy': [
'true'
],
'each': [
'context object property accessed'
],
'every': [
'Can be called with object',
'Died on test #15',
'context works'
],
'filter': [
'given context',
'[{"a":1,"b":2},{"a":1,"b":3},{"a":1,"b":4}]',
'[{"a":1,"b":2},{"a":2,"b":2}]',
'Empty object accepts all items',
'OO-filter'
],
'find': [
'{"a":1,"b":4}',
'undefined when not found',
'undefined when searching empty list',
'works on objects',
'undefined',
'called with context'
],
'findWhere': [
'checks properties given function'
],
'groupBy': [
'true'
],
'includes': [
"doesn't delegate to binary search"
],
'invoke': [
'handles null & undefined'
],
'map': [
'tripled numbers with context',
'OO-style doubled numbers'
],
'max': [
'can handle null/undefined',
'can perform a computation-based max',
'Maximum value of an empty object',
'Maximum value of an empty array',
'Maximum value of a non-numeric collection',
'Finds correct max in array starting with num and containing a NaN',
'Finds correct max in array starting with NaN',
'Respects iterator return value of -Infinity',
'String keys use property iterator',
'Iterator context',
'Lookup falsy iterator'
],
'min': [
'can handle null/undefined',
'can perform a computation-based min',
'Minimum value of an empty object',
'Minimum value of an empty array',
'Minimum value of a non-numeric collection',
'Finds correct min in array starting with NaN',
'Respects iterator return value of Infinity',
'String keys use property iterator',
'Iterator context',
'Lookup falsy iterator'
],
'partition': [
'can reference the array index',
'Died on test #8',
'partition takes a context argument',
'function(a){[code]}'
],
'pluck': [
'[1]'
],
'reduce': [
'can reduce with a context object'
],
'reject': [
'Returns empty list given empty array'
],
'sample': [
'behaves correctly on negative n',
'Died on test #3'
],
'some': [
'Can be called with object',
'Died on test #17',
'context works'
],
'where': [
'checks properties given function'
],
'Can use various collection methods on NodeLists': [
'<span id="id2"></span>',
'<span id="id1"></span>'
'Resistant to collection length and properties changing while iterating': [
'Died on test #50'
]
},
'Functions': {
'debounce asap': true,
'debounce asap cancel': true,
'debounce after system time is set backwards': true,
'debounce asap recursively': true,
'throttle repeatedly with results': true,
'more throttle does not trigger leading call when leading is set to false': true,
'throttle does not trigger trailing call when trailing is set to false': true,
'before': [
'stores a memo to the last value',
'provides context'
],
'bind': [
'Died on test #2'
],
@@ -246,78 +102,45 @@
'{"bar":"BAR","foo":"FOO"}',
'Died on test #8'
],
'partial':[
'can partially apply with placeholders',
'accepts more arguments than the number of placeholders',
'accepts fewer arguments than the number of placeholders',
'unfilled placeholders are undefined',
'keeps prototype',
'allows the placeholder to be swapped out'
]
'throttle repeatedly with results': true,
'more throttle does not trigger leading call when leading is set to false': true,
'throttle does not trigger trailing call when trailing is set to false': true,
'debounce asap': true
},
'Objects': {
'#1929 Typed Array constructors are functions': true,
'allKeys': [
'is not fooled by sparse arrays; see issue #95',
'is not fooled by sparse arrays with additional properties',
'[]'
],
'defaults': [
'defaults skips nulls',
'defaults skips undefined'
],
'allKeys': true,
'extendOwn': true,
'mapObject': true,
'matcher': true,
'matcher ': true,
'extend': [
'extending null results in null',
'extending undefined results in undefined'
],
'extendOwn': [
'extending non-objects results in returning the non-object value',
'extending undefined results in undefined'
],
'functions': [
'also looks up functions on the prototype'
'extend copies all properties from source'
],
'isEqual': [
'`0` is not equal to `-0`',
'Commutative equality is implemented for `0` and `-0`',
'`new Number(0)` and `-0` are not equal',
'Commutative equality is implemented for `new Number(0)` and `-0`',
'false'
'Commutative equality is implemented for `new Number(0)` and `-0`'
],
'isFinite': [
'Numeric strings are numbers',
'Number instances can be finite'
],
'isMatch': [
'inherited and own properties are checked on the test object',
'doesnt falsey match constructor on undefined/null'
],
'findKey': [
'called with context'
],
'keys': [
'is not fooled by sparse arrays; see issue #95',
'[]'
],
'mapObject': [
'keep context',
'called with context',
'mapValue identity'
],
'matcher': [
'null matches null',
'treats primitives as empty'
],
'omit': [
'can accept a predicate',
'function is given context'
],
'pick': [
'can accept a predicate and context',
'function is given context'
'matches': [
'inherited and own properties are checked on the test object',
'doesnt fasley match constructor on undefined/null'
]
},
'Utility': {
'noConflict (node vm)': true,
'now': [
'Produces the correct time in milliseconds'
],
@@ -327,75 +150,19 @@
}
};
var mixinPrereqs = (function() {
var aliasToReal = {
'all': 'every',
'allKeys': 'keysIn',
'any': 'some',
'collect': 'map',
'compose': 'flowRight',
'contains': 'includes',
'detect': 'find',
'extendOwn': 'assign',
'findWhere': 'find',
'foldl': 'reduce',
'foldr': 'reduceRight',
'include': 'includes',
'indexBy': 'keyBy',
'inject': 'reduce',
'invoke': 'invokeMap',
'mapObject': 'mapValues',
'matcher': 'matches',
'methods': 'functions',
'object': 'zipObject',
'pairs': 'toPairs',
'pluck': 'map',
'restParam': 'restArgs',
'select': 'filter',
'unique': 'uniq',
'where': 'filter'
};
var keyMap = {
'rest': 'tail',
'restArgs': 'rest'
};
var lodash = _.noConflict();
return function(_) {
lodash.defaultsDeep(_, { 'templateSettings': lodash.templateSettings });
lodash.mixin(_, lodash.pick(lodash, lodash.difference(lodash.functions(lodash), lodash.functions(_))));
lodash.forOwn(keyMap, function(realName, otherName) {
_[otherName] = lodash[realName];
_.prototype[otherName] = lodash.prototype[realName];
});
lodash.forOwn(aliasToReal, function(realName, alias) {
_[alias] = _[realName];
_.prototype[alias] = _.prototype[realName];
});
};
}());
// Only excuse in Sauce Labs.
// Only excuse in Sauce Labs (buggy Safari and timers).
if (!ui.isSauceLabs) {
delete QUnit.config.excused.Functions['throttle repeatedly with results'];
delete QUnit.config.excused.Functions['more throttle does not trigger leading call when leading is set to false'];
delete QUnit.config.excused.Functions['throttle does not trigger trailing call when trailing is set to false'];
delete QUnit.config.excused.Functions['debounce asap'];
delete QUnit.config.excused.Utility.now;
}
// Load prerequisite scripts.
document.write(ui.urlParams.loader == 'none'
? '<script src="' + ui.buildPath + '"><\/script>'
: '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
);
</script>
<script>
if (ui.urlParams.loader == 'none') {
mixinPrereqs(_);
document.write([
// Load test scripts.
document.write(ui.urlParams.loader != 'none'
? '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
: ([
'<script src="' + ui.buildPath + '"><\/script>',
'<script src="../vendor/underscore/test/collections.js"><\/script>',
'<script src="../vendor/underscore/test/arrays.js"><\/script>',
'<script src="../vendor/underscore/test/functions.js"><\/script>',
@@ -403,8 +170,8 @@
'<script src="../vendor/underscore/test/cross-document.js"><\/script>',
'<script src="../vendor/underscore/test/utility.js"><\/script>',
'<script src="../vendor/underscore/test/chaining.js"><\/script>'
].join('\n'));
}
].join('\n'))
);
</script>
<script>
(function() {
@@ -414,13 +181,6 @@
if (!window.require) {
return;
}
// Wrap to work around tests assuming Node `require` use.
require = (function(func) {
return function() {
return arguments[0] === '..' ? window._ : func.apply(null, arguments);
};
}(require));
var reBasename = /[\w.-]+$/,
basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
modulePath = ui.buildPath.replace(/\.js$/, ''),
@@ -461,7 +221,9 @@
QUnit.config.autostart = false;
require(getConfig(), [moduleId], function(lodash) {
mixinPrereqs(lodash);
if (ui.isModularize) {
window._ = lodash;
}
require(getConfig(), [
'test/collections',
'test/arrays',

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2016 Jeremy Ashkenas, DocumentCloud
Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation

View File

@@ -1,6 +1,6 @@
// Backbone.js 1.2.3
// Backbone.js 1.2.1
// (c) 2010-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://backbonejs.org
@@ -9,8 +9,8 @@
// Establish the root object, `window` (`self`) in the browser, or `global` on the server.
// We use `self` instead of `window` for `WebWorker` support.
var root = (typeof self == 'object' && self.self === self && self) ||
(typeof global == 'object' && global.global === global && global);
var root = (typeof self == 'object' && self.self == self && self) ||
(typeof global == 'object' && global.global == global && global);
// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
@@ -23,7 +23,7 @@
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore'), $;
try { $ = require('jquery'); } catch (e) {}
try { $ = require('jquery'); } catch(e) {}
factory(root, exports, _, $);
// Finally, as a browser global.
@@ -31,7 +31,7 @@
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
}
})(function(root, Backbone, _, $) {
}(function(root, Backbone, _, $) {
// Initial Setup
// -------------
@@ -41,10 +41,10 @@
var previousBackbone = root.Backbone;
// Create a local reference to a common array method we'll want to use later.
var slice = Array.prototype.slice;
var slice = [].slice;
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '1.2.3';
Backbone.VERSION = '1.2.1';
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// the `$` variable.
@@ -68,13 +68,8 @@
// form param named `model`.
Backbone.emulateJSON = false;
// Proxy Backbone class methods to Underscore functions, wrapping the model's
// `attributes` object or collection's `models` array behind the scenes.
//
// collection.filter(function(model) { return model.get('age') > 10 });
// collection.each(this.addView);
//
// `Function#apply` can be slow so we use the method's arg count, if we know it.
// Proxy Underscore methods to a Backbone class' prototype using a
// particular attribute as the data argument
var addMethod = function(length, method, attribute) {
switch (length) {
case 1: return function() {
@@ -84,10 +79,10 @@
return _[method](this[attribute], value);
};
case 3: return function(iteratee, context) {
return _[method](this[attribute], cb(iteratee, this), context);
return _[method](this[attribute], iteratee, context);
};
case 4: return function(iteratee, defaultVal, context) {
return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
return _[method](this[attribute], iteratee, defaultVal, context);
};
default: return function() {
var args = slice.call(arguments);
@@ -102,26 +97,12 @@
});
};
// Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
var cb = function(iteratee, instance) {
if (_.isFunction(iteratee)) return iteratee;
if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
return iteratee;
};
var modelMatcher = function(attrs) {
var matcher = _.matches(attrs);
return function(model) {
return matcher(model.attributes);
};
};
// Backbone.Events
// ---------------
// A module that can be mixed in to *any object* in order to provide it with
// a custom event channel. You may bind a callback to an event with `on` or
// remove with `off`; `trigger`-ing an event fires all callbacks in
// custom events. You may bind with `on` or remove with `off` callback
// functions to an event; `trigger`-ing an event fires all callbacks in
// succession.
//
// var object = {};
@@ -136,25 +117,26 @@
// Iterates over the standard `event, callback` (as well as the fancy multiple
// space-separated events `"change blur", callback` and jQuery-style event
// maps `{event: callback}`).
var eventsApi = function(iteratee, events, name, callback, opts) {
// maps `{event: callback}`), reducing them by manipulating `memo`.
// Passes a normalized single event name and callback, as well as any
// optional `opts`.
var eventsApi = function(iteratee, memo, name, callback, opts) {
var i = 0, names;
if (name && typeof name === 'object') {
// Handle event maps.
if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
for (names = _.keys(name); i < names.length ; i++) {
events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
memo = iteratee(memo, names[i], name[names[i]], opts);
}
} else if (name && eventSplitter.test(name)) {
// Handle space-separated event names by delegating them individually.
// Handle space separated event names.
for (names = name.split(eventSplitter); i < names.length; i++) {
events = iteratee(events, names[i], callback, opts);
memo = iteratee(memo, names[i], callback, opts);
}
} else {
// Finally, standard events.
events = iteratee(events, name, callback, opts);
memo = iteratee(memo, name, callback, opts);
}
return events;
return memo;
};
// Bind an event to a `callback` function. Passing `"all"` will bind
@@ -163,12 +145,13 @@
return internalOn(this, name, callback, context);
};
// Guard the `listening` argument from the public API.
// An internal use `on` function, used to guard the `listening` argument from
// the public API.
var internalOn = function(obj, name, callback, context, listening) {
obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
context: context,
ctx: obj,
listening: listening
context: context,
ctx: obj,
listening: listening
});
if (listening) {
@@ -180,9 +163,8 @@
};
// Inversion-of-control versions of `on`. Tell *this* object to listen to
// an event in another object... keeping track of what it's listening to
// for easier unbinding later.
Events.listenTo = function(obj, name, callback) {
// an event in another object... keeping track of what it's listening to.
Events.listenTo = function(obj, name, callback) {
if (!obj) return this;
var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
var listeningTo = this._listeningTo || (this._listeningTo = {});
@@ -207,7 +189,7 @@
var context = options.context, ctx = options.ctx, listening = options.listening;
if (listening) listening.count++;
handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
}
return events;
};
@@ -216,18 +198,18 @@
// callbacks with that function. If `callback` is null, removes all
// callbacks for the event. If `name` is null, removes all bound
// callbacks for all events.
Events.off = function(name, callback, context) {
Events.off = function(name, callback, context) {
if (!this._events) return this;
this._events = eventsApi(offApi, this._events, name, callback, {
context: context,
listeners: this._listeners
context: context,
listeners: this._listeners
});
return this;
};
// Tell this object to stop listening to either specific events ... or
// to every object it's currently listening to.
Events.stopListening = function(obj, name, callback) {
Events.stopListening = function(obj, name, callback) {
var listeningTo = this._listeningTo;
if (!listeningTo) return this;
@@ -249,6 +231,7 @@
// The reducing API that removes a callback from the `events` object.
var offApi = function(events, name, callback, options) {
// No events to consider.
if (!events) return;
var i = 0, listening;
@@ -303,17 +286,17 @@
};
// Bind an event to only be triggered a single time. After the first time
// the callback is invoked, its listener will be removed. If multiple events
// are passed in using the space-separated syntax, the handler will fire
// once for each event, not once for a combination of all events.
Events.once = function(name, callback, context) {
// the callback is invoked, it will be removed. When multiple events are
// passed in using the space-separated syntax, the event will fire once for every
// event you passed in, not once for a combination of all events
Events.once = function(name, callback, context) {
// Map the event into a `{event: once}` object.
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
return this.on(events, void 0, context);
};
// Inversion-of-control versions of `once`.
Events.listenToOnce = function(obj, name, callback) {
Events.listenToOnce = function(obj, name, callback) {
// Map the event into a `{event: once}` object.
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
return this.listenTo(obj, events);
@@ -336,7 +319,7 @@
// passed the same arguments as `trigger` is, apart from the event name
// (unless you're listening on `"all"`, which will cause your callback to
// receive the true name of the event as the first argument).
Events.trigger = function(name) {
Events.trigger = function(name) {
if (!this._events) return this;
var length = Math.max(0, arguments.length - 1);
@@ -348,7 +331,7 @@
};
// Handles triggering the appropriate event callbacks.
var triggerApi = function(objEvents, name, callback, args) {
var triggerApi = function(objEvents, name, cb, args) {
if (objEvents) {
var events = objEvents[name];
var allEvents = objEvents.all;
@@ -493,6 +476,9 @@
var changed = this.changed;
var prev = this._previousAttributes;
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
// For each `set` attribute, update or delete the current value.
for (var attr in attrs) {
val = attrs[attr];
@@ -505,9 +491,6 @@
unset ? delete current[attr] : current[attr] = val;
}
// Update the `id`.
if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
// Trigger all relevant attribute changes.
if (!silent) {
if (changes.length) this._pending = options;
@@ -619,8 +602,8 @@
// the model will be valid when the attributes, if any, are set.
if (attrs && !wait) {
if (!this.set(attrs, options)) return false;
} else if (!this._validate(attrs, options)) {
return false;
} else {
if (!this._validate(attrs, options)) return false;
}
// After a successful server-side save, the client is (optionally)
@@ -730,10 +713,9 @@
});
// Underscore methods that we want to implement on the Model, mapped to the
// number of arguments they take.
var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
omit: 0, chain: 1, isEmpty: 1};
// Underscore methods that we want to implement on the Model.
var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
omit: 0, chain: 1, isEmpty: 1 };
// Mix in each Underscore method as a proxy to `Model#attributes`.
addUnderscoreMethods(Model, modelMethods, 'attributes');
@@ -764,17 +746,6 @@
var setOptions = {add: true, remove: true, merge: true};
var addOptions = {add: true, remove: false};
// Splices `insert` into `array` at index `at`.
var splice = function(array, insert, at) {
at = Math.min(Math.max(at, 0), array.length);
var tail = Array(array.length - at);
var length = insert.length;
var i;
for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
for (i = 0; i < length; i++) array[i + at] = insert[i];
for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
};
// Define the Collection's inheritable methods.
_.extend(Collection.prototype, Events, {
@@ -797,9 +768,7 @@
return Backbone.sync.apply(this, arguments);
},
// Add a model, or list of models to the set. `models` may be Backbone
// Models or raw JavaScript objects to be converted to Models, or any
// combination of the two.
// Add a model, or list of models to the set.
add: function(models, options) {
return this.set(models, _.extend({merge: false}, options, addOptions));
},
@@ -808,12 +777,9 @@
remove: function(models, options) {
options = _.extend({}, options);
var singular = !_.isArray(models);
models = singular ? [models] : models.slice();
models = singular ? [models] : _.clone(models);
var removed = this._removeModels(models, options);
if (!options.silent && removed.length) {
options.changes = {added: [], merged: [], removed: removed};
this.trigger('update', this, options);
}
if (!options.silent && removed) this.trigger('update', this, options);
return singular ? removed[0] : removed;
},
@@ -822,113 +788,97 @@
// already exist in the collection, as necessary. Similar to **Model#set**,
// the core operation for updating the data contained by the collection.
set: function(models, options) {
if (models == null) return;
options = _.defaults({}, options, setOptions);
if (options.parse && !this._isModel(models)) {
models = this.parse(models, options) || [];
}
if (options.parse && !this._isModel(models)) models = this.parse(models, options);
var singular = !_.isArray(models);
models = singular ? [models] : models.slice();
models = singular ? (models ? [models] : []) : models.slice();
var id, model, attrs, existing, sort;
var at = options.at;
if (at != null) at = +at;
if (at < 0) at += this.length + 1;
var set = [];
var toAdd = [];
var toMerge = [];
var toRemove = [];
var modelMap = {};
var add = options.add;
var merge = options.merge;
var remove = options.remove;
var sort = false;
var sortable = this.comparator && at == null && options.sort !== false;
var sortable = this.comparator && (at == null) && options.sort !== false;
var sortAttr = _.isString(this.comparator) ? this.comparator : null;
var toAdd = [], toRemove = [], modelMap = {};
var add = options.add, merge = options.merge, remove = options.remove;
var order = !sortable && add && remove ? [] : false;
var orderChanged = false;
// Turn bare objects into model references, and prevent invalid models
// from being added.
var model, i;
for (i = 0; i < models.length; i++) {
model = models[i];
for (var i = 0; i < models.length; i++) {
attrs = models[i];
// If a duplicate is found, prevent it from being added and
// optionally merge it into the existing model.
var existing = this.get(model);
if (existing) {
if (merge && model !== existing) {
var attrs = this._isModel(model) ? model.attributes : model;
if (existing = this.get(attrs)) {
if (remove) modelMap[existing.cid] = true;
if (merge && attrs !== existing) {
attrs = this._isModel(attrs) ? attrs.attributes : attrs;
if (options.parse) attrs = existing.parse(attrs, options);
existing.set(attrs, options);
toMerge.push(existing);
if (sortable && !sort) sort = existing.hasChanged(sortAttr);
}
if (!modelMap[existing.cid]) {
modelMap[existing.cid] = true;
set.push(existing);
if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
}
models[i] = existing;
// If this is a new, valid model, push it to the `toAdd` list.
} else if (add) {
model = models[i] = this._prepareModel(model, options);
if (model) {
toAdd.push(model);
this._addReference(model, options);
modelMap[model.cid] = true;
set.push(model);
}
model = models[i] = this._prepareModel(attrs, options);
if (!model) continue;
toAdd.push(model);
this._addReference(model, options);
}
// Do not add multiple models with the same `id`.
model = existing || model;
if (!model) continue;
id = this.modelId(model.attributes);
if (order && (model.isNew() || !modelMap[id])) {
order.push(model);
// Check to see if this is actually a new model at this index.
orderChanged = orderChanged || !this.models[i] || model.cid !== this.models[i].cid;
}
modelMap[id] = true;
}
// Remove stale models.
// Remove nonexistent models if appropriate.
if (remove) {
for (i = 0; i < this.length; i++) {
model = this.models[i];
if (!modelMap[model.cid]) toRemove.push(model);
for (var i = 0; i < this.length; i++) {
if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
}
if (toRemove.length) this._removeModels(toRemove, options);
}
// See if sorting is needed, update `length` and splice in new models.
var orderChanged = false;
var replace = !sortable && add && remove;
if (set.length && replace) {
orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
return m !== set[index];
});
this.models.length = 0;
splice(this.models, set, 0);
this.length = this.models.length;
} else if (toAdd.length) {
if (toAdd.length || orderChanged) {
if (sortable) sort = true;
splice(this.models, toAdd, at == null ? this.length : at);
this.length = this.models.length;
this.length += toAdd.length;
if (at != null) {
for (var i = 0; i < toAdd.length; i++) {
this.models.splice(at + i, 0, toAdd[i]);
}
} else {
if (order) this.models.length = 0;
var orderedModels = order || toAdd;
for (var i = 0; i < orderedModels.length; i++) {
this.models.push(orderedModels[i]);
}
}
}
// Silently sort the collection if appropriate.
if (sort) this.sort({silent: true});
// Unless silenced, it's time to fire all appropriate add/sort/update events.
// Unless silenced, it's time to fire all appropriate add/sort events.
if (!options.silent) {
for (i = 0; i < toAdd.length; i++) {
if (at != null) options.index = at + i;
model = toAdd[i];
model.trigger('add', model, this, options);
var addOpts = at != null ? _.clone(options) : options;
for (var i = 0; i < toAdd.length; i++) {
if (at != null) addOpts.index = at + i;
(model = toAdd[i]).trigger('add', model, this, addOpts);
}
if (sort || orderChanged) this.trigger('sort', this, options);
if (toAdd.length || toRemove.length || toMerge.length) {
options.changes = {
added: toAdd,
removed: toRemove,
merged: toMerge
};
this.trigger('update', this, options);
}
if (toAdd.length || toRemove.length) this.trigger('update', this, options);
}
// Return the added (or merged) model (or models).
@@ -985,11 +935,6 @@
return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
},
// Returns `true` if the model is in the collection.
has: function(obj) {
return this.get(obj) != null;
},
// Get the model at the given index.
at: function(index) {
if (index < 0) index += this.length;
@@ -999,7 +944,10 @@
// Return models with matching attributes. Useful for simple cases of
// `filter`.
where: function(attrs, first) {
return this[first ? 'find' : 'filter'](attrs);
var matches = _.matches(attrs);
return this[first ? 'find' : 'filter'](function(model) {
return matches(model.attributes);
});
},
// Return the first model with matching attributes. Useful for simple cases
@@ -1012,26 +960,23 @@
// normal circumstances, as the set will maintain sort order as each item
// is added.
sort: function(options) {
var comparator = this.comparator;
if (!comparator) throw new Error('Cannot sort a set without a comparator');
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
options || (options = {});
var length = comparator.length;
if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
// Run sort based on type of `comparator`.
if (length === 1 || _.isString(comparator)) {
this.models = this.sortBy(comparator);
if (_.isString(this.comparator) || this.comparator.length === 1) {
this.models = this.sortBy(this.comparator, this);
} else {
this.models.sort(comparator);
this.models.sort(_.bind(this.comparator, this));
}
if (!options.silent) this.trigger('sort', this, options);
return this;
},
// Pluck an attribute from each model in the collection.
pluck: function(attr) {
return this.map(attr + '');
return _.invoke(this.models, 'get', attr);
},
// Fetch the default set of models for this collection, resetting the
@@ -1062,9 +1007,9 @@
if (!wait) this.add(model, options);
var collection = this;
var success = options.success;
options.success = function(m, resp, callbackOpts) {
if (wait) collection.add(m, callbackOpts);
if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
options.success = function(model, resp, callbackOpts) {
if (wait) collection.add(model, callbackOpts);
if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
};
model.save(null, options);
return model;
@@ -1085,7 +1030,7 @@
},
// Define how to uniquely identify models in the collection.
modelId: function(attrs) {
modelId: function (attrs) {
return attrs[this.model.prototype.idAttribute || 'id'];
},
@@ -1113,6 +1058,7 @@
},
// Internal method called by both remove and set.
// Returns removed models, or false if nothing is removed.
_removeModels: function(models, options) {
var removed = [];
for (var i = 0; i < models.length; i++) {
@@ -1123,12 +1069,6 @@
this.models.splice(index, 1);
this.length--;
// Remove references before triggering 'remove' event to prevent an
// infinite loop. #3693
delete this._byId[model.cid];
var id = this.modelId(model.attributes);
if (id != null) delete this._byId[id];
if (!options.silent) {
options.index = index;
model.trigger('remove', model, this, options);
@@ -1137,12 +1077,12 @@
removed.push(model);
this._removeReference(model, options);
}
return removed;
return removed.length ? removed : false;
},
// Method for checking whether an object should be considered a model for
// the purposes of adding to the collection.
_isModel: function(model) {
_isModel: function (model) {
return model instanceof Model;
},
@@ -1168,16 +1108,14 @@
// events simply proxy through. "add" and "remove" events that originate
// in other collections are ignored.
_onModelEvent: function(event, model, collection, options) {
if (model) {
if ((event === 'add' || event === 'remove') && collection !== this) return;
if (event === 'destroy') this.remove(model, options);
if (event === 'change') {
var prevId = this.modelId(model.previousAttributes());
var id = this.modelId(model.attributes);
if (prevId !== id) {
if (prevId != null) delete this._byId[prevId];
if (id != null) this._byId[id] = model;
}
if ((event === 'add' || event === 'remove') && collection !== this) return;
if (event === 'destroy') this.remove(model, options);
if (event === 'change') {
var prevId = this.modelId(model.previousAttributes());
var id = this.modelId(model.attributes);
if (prevId !== id) {
if (prevId != null) delete this._byId[prevId];
if (id != null) this._byId[id] = model;
}
}
this.trigger.apply(this, arguments);
@@ -1188,18 +1126,31 @@
// Underscore methods that we want to implement on the Collection.
// 90% of the core usefulness of Backbone Collections is actually implemented
// right here:
var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 2,
contains: 2, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
isEmpty: 1, chain: 1, sample: 3, partition: 3 };
// Mix in each Underscore method as a proxy to `Collection#models`.
addUnderscoreMethods(Collection, collectionMethods, 'models');
// Underscore methods that take a property name as an argument.
var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
// Use attributes instead of properties.
_.each(attributeMethods, function(method) {
if (!_[method]) return;
Collection.prototype[method] = function(value, context) {
var iterator = _.isFunction(value) ? value : function(model) {
return model.get(value);
};
return _[method](this.models, iterator, context);
};
});
// Backbone.View
// -------------
@@ -1223,7 +1174,7 @@
// Cached regex to split keys for `delegate`.
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
// List of view options to be set as properties.
// List of view options to be merged as properties.
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
// Set up all inheritable **Backbone.View** properties and methods.
@@ -1445,9 +1396,9 @@
var methodMap = {
'create': 'POST',
'update': 'PUT',
'patch': 'PATCH',
'patch': 'PATCH',
'delete': 'DELETE',
'read': 'GET'
'read': 'GET'
};
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
@@ -1567,7 +1518,7 @@
// falls back to polling.
var History = Backbone.History = function() {
this.handlers = [];
this.checkUrl = _.bind(this.checkUrl, this);
_.bindAll(this, 'checkUrl');
// Ensure that `History` can be used outside of the browser.
if (typeof window !== 'undefined') {
@@ -1604,8 +1555,8 @@
// Does the pathname match the root?
matchRoot: function() {
var path = this.decodeFragment(this.location.pathname);
var rootPath = path.slice(0, this.root.length - 1) + '/';
return rootPath === this.root;
var root = path.slice(0, this.root.length - 1) + '/';
return root === this.root;
},
// Unicode characters in `location.pathname` are percent encoded so they're
@@ -1660,7 +1611,7 @@
this.options = _.extend({root: '/'}, this.options, options);
this.root = this.options.root;
this._wantsHashChange = this.options.hashChange !== false;
this._hasHashChange = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
this._hasHashChange = 'onhashchange' in window;
this._useHashChange = this._wantsHashChange && this._hasHashChange;
this._wantsPushState = !!this.options.pushState;
this._hasPushState = !!(this.history && this.history.pushState);
@@ -1677,8 +1628,8 @@
// If we've started off with a route from a `pushState`-enabled
// browser, but we're currently in a browser that doesn't support it...
if (!this._hasPushState && !this.atRoot()) {
var rootPath = this.root.slice(0, -1) || '/';
this.location.replace(rootPath + '#' + this.getPath());
var root = this.root.slice(0, -1) || '/';
this.location.replace(root + '#' + this.getPath());
// Return immediately as browser will do redirect to new url
return true;
@@ -1707,7 +1658,7 @@
}
// Add a cross-platform `addEventListener` shim for older browsers.
var addEventListener = window.addEventListener || function(eventName, listener) {
var addEventListener = window.addEventListener || function (eventName, listener) {
return attachEvent('on' + eventName, listener);
};
@@ -1728,7 +1679,7 @@
// but possibly useful for unit testing Routers.
stop: function() {
// Add a cross-platform `removeEventListener` shim for older browsers.
var removeEventListener = window.removeEventListener || function(eventName, listener) {
var removeEventListener = window.removeEventListener || function (eventName, listener) {
return detachEvent('on' + eventName, listener);
};
@@ -1779,7 +1730,7 @@
// If the root doesn't match, no routes can match either.
if (!this.matchRoot()) return false;
fragment = this.fragment = this.getFragment(fragment);
return _.some(this.handlers, function(handler) {
return _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
@@ -1802,11 +1753,11 @@
fragment = this.getFragment(fragment || '');
// Don't include a trailing slash on the root.
var rootPath = this.root;
var root = this.root;
if (fragment === '' || fragment.charAt(0) === '?') {
rootPath = rootPath.slice(0, -1) || '/';
root = root.slice(0, -1) || '/';
}
var url = rootPath + fragment;
var url = root + fragment;
// Strip the hash and decode for matching.
fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
@@ -1822,7 +1773,7 @@
// fragment to store history.
} else if (this._wantsHashChange) {
this._updateHash(this.location, fragment, options.replace);
if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) {
var iWindow = this.iframe.contentWindow;
// Opening and closing the iframe tricks IE7 and earlier to push a
@@ -1884,9 +1835,14 @@
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function and add the prototype properties.
child.prototype = _.create(parent.prototype, protoProps);
child.prototype.constructor = child;
// `parent` constructor function.
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Set a convenience property in case the parent's prototype is needed
// later.
@@ -1914,4 +1870,4 @@
return Backbone;
});
}));

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +1,42 @@
(function() {
QUnit.module('Backbone.Events');
module("Backbone.Events");
QUnit.test('on and trigger', function(assert) {
assert.expect(2);
var obj = {counter: 0};
_.extend(obj, Backbone.Events);
test("on and trigger", 2, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
obj.on('event', function() { obj.counter += 1; });
obj.trigger('event');
assert.equal(obj.counter, 1, 'counter should be incremented.');
equal(obj.counter,1,'counter should be incremented.');
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
assert.equal(obj.counter, 5, 'counter should be incremented five times.');
equal(obj.counter, 5, 'counter should be incremented five times.');
});
QUnit.test('binding and triggering multiple events', function(assert) {
assert.expect(4);
var obj = {counter: 0};
test("binding and triggering multiple events", 4, function() {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
obj.on('a b c', function() { obj.counter += 1; });
obj.trigger('a');
assert.equal(obj.counter, 1);
equal(obj.counter, 1);
obj.trigger('a b');
assert.equal(obj.counter, 3);
equal(obj.counter, 3);
obj.trigger('c');
assert.equal(obj.counter, 4);
equal(obj.counter, 4);
obj.off('a c');
obj.trigger('a b c');
assert.equal(obj.counter, 5);
equal(obj.counter, 5);
});
QUnit.test('binding and triggering with event maps', function(assert) {
var obj = {counter: 0};
test("binding and triggering with event maps", function() {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var increment = function() {
@@ -52,85 +50,54 @@
}, obj);
obj.trigger('a');
assert.equal(obj.counter, 1);
equal(obj.counter, 1);
obj.trigger('a b');
assert.equal(obj.counter, 3);
equal(obj.counter, 3);
obj.trigger('c');
assert.equal(obj.counter, 4);
equal(obj.counter, 4);
obj.off({
a: increment,
c: increment
}, obj);
obj.trigger('a b c');
assert.equal(obj.counter, 5);
equal(obj.counter, 5);
});
QUnit.test('binding and triggering multiple event names with event maps', function(assert) {
var obj = {counter: 0};
_.extend(obj, Backbone.Events);
var increment = function() {
this.counter += 1;
};
obj.on({
'a b c': increment
});
obj.trigger('a');
assert.equal(obj.counter, 1);
obj.trigger('a b');
assert.equal(obj.counter, 3);
obj.trigger('c');
assert.equal(obj.counter, 4);
obj.off({
'a c': increment
});
obj.trigger('a b c');
assert.equal(obj.counter, 5);
});
QUnit.test('binding and trigger with event maps context', function(assert) {
assert.expect(2);
var obj = {counter: 0};
test("binding and trigger with event maps context", 2, function() {
var obj = { counter: 0 };
var context = {};
_.extend(obj, Backbone.Events);
obj.on({
a: function() {
assert.strictEqual(this, context, 'defaults `context` to `callback` param');
}
a: function() {
strictEqual(this, context, 'defaults `context` to `callback` param');
}
}, context).trigger('a');
obj.off().on({
a: function() {
assert.strictEqual(this, context, 'will not override explicit `context` param');
}
a: function() {
strictEqual(this, context, 'will not override explicit `context` param');
}
}, this, context).trigger('a');
});
QUnit.test('listenTo and stopListening', function(assert) {
assert.expect(1);
test("listenTo and stopListening", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenTo(b, 'all', function(){ assert.ok(true); });
a.listenTo(b, 'all', function(){ ok(true); });
b.trigger('anything');
a.listenTo(b, 'all', function(){ assert.ok(false); });
a.listenTo(b, 'all', function(){ ok(false); });
a.stopListening();
b.trigger('anything');
});
QUnit.test('listenTo and stopListening with event maps', function(assert) {
assert.expect(4);
test("listenTo and stopListening with event maps", 4, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var cb = function(){ assert.ok(true); };
var cb = function(){ ok(true); };
a.listenTo(b, {event: cb});
b.trigger('event');
a.listenTo(b, {event2: cb});
@@ -141,11 +108,10 @@
b.trigger('event event2');
});
QUnit.test('stopListening with omitted args', function(assert) {
assert.expect(2);
test("stopListening with omitted args", 2, function () {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var cb = function() { assert.ok(true); };
var cb = function () { ok(true); };
a.listenTo(b, 'event', cb);
b.on('event', cb);
a.listenTo(b, 'event2', cb);
@@ -158,237 +124,219 @@
b.trigger('event2');
});
QUnit.test('listenToOnce', function(assert) {
assert.expect(2);
test("listenToOnce", 2, function() {
// Same as the previous test, but we use once rather than having to explicitly unbind
var obj = {counterA: 0, counterB: 0};
var obj = { counterA: 0, counterB: 0 };
_.extend(obj, Backbone.Events);
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
var incrB = function(){ obj.counterB += 1; };
obj.listenToOnce(obj, 'event', incrA);
obj.listenToOnce(obj, 'event', incrB);
obj.trigger('event');
assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
});
QUnit.test('listenToOnce and stopListening', function(assert) {
assert.expect(1);
test("listenToOnce and stopListening", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, 'all', function() { assert.ok(true); });
a.listenToOnce(b, 'all', function() { ok(true); });
b.trigger('anything');
b.trigger('anything');
a.listenToOnce(b, 'all', function() { assert.ok(false); });
a.listenToOnce(b, 'all', function() { ok(false); });
a.stopListening();
b.trigger('anything');
});
QUnit.test('listenTo, listenToOnce and stopListening', function(assert) {
assert.expect(1);
test("listenTo, listenToOnce and stopListening", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, 'all', function() { assert.ok(true); });
a.listenToOnce(b, 'all', function() { ok(true); });
b.trigger('anything');
b.trigger('anything');
a.listenTo(b, 'all', function() { assert.ok(false); });
a.listenTo(b, 'all', function() { ok(false); });
a.stopListening();
b.trigger('anything');
});
QUnit.test('listenTo and stopListening with event maps', function(assert) {
assert.expect(1);
test("listenTo and stopListening with event maps", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenTo(b, {change: function(){ assert.ok(true); }});
a.listenTo(b, {change: function(){ ok(true); }});
b.trigger('change');
a.listenTo(b, {change: function(){ assert.ok(false); }});
a.listenTo(b, {change: function(){ ok(false); }});
a.stopListening();
b.trigger('change');
});
QUnit.test('listenTo yourself', function(assert) {
assert.expect(1);
test("listenTo yourself", 1, function(){
var e = _.extend({}, Backbone.Events);
e.listenTo(e, 'foo', function(){ assert.ok(true); });
e.trigger('foo');
e.listenTo(e, "foo", function(){ ok(true); });
e.trigger("foo");
});
QUnit.test('listenTo yourself cleans yourself up with stopListening', function(assert) {
assert.expect(1);
test("listenTo yourself cleans yourself up with stopListening", 1, function(){
var e = _.extend({}, Backbone.Events);
e.listenTo(e, 'foo', function(){ assert.ok(true); });
e.trigger('foo');
e.listenTo(e, "foo", function(){ ok(true); });
e.trigger("foo");
e.stopListening();
e.trigger('foo');
e.trigger("foo");
});
QUnit.test('stopListening cleans up references', function(assert) {
assert.expect(12);
test("stopListening cleans up references", 12, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var fn = function() {};
b.on('event', fn);
a.listenTo(b, 'event', fn).stopListening();
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
a.listenTo(b, 'event', fn).stopListening(b);
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
a.listenTo(b, 'event', fn).stopListening(b, 'event');
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
a.listenTo(b, 'event', fn).stopListening(b, 'event', fn);
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
});
QUnit.test('stopListening cleans up references from listenToOnce', function(assert) {
assert.expect(12);
test("stopListening cleans up references from listenToOnce", 12, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var fn = function() {};
b.on('event', fn);
a.listenToOnce(b, 'event', fn).stopListening();
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
a.listenToOnce(b, 'event', fn).stopListening(b);
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
a.listenToOnce(b, 'event', fn).stopListening(b, 'event');
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
a.listenToOnce(b, 'event', fn).stopListening(b, 'event', fn);
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._events.event), 1);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._events.event), 1);
equal(_.size(b._listeners), 0);
});
QUnit.test('listenTo and off cleaning up references', function(assert) {
assert.expect(8);
test("listenTo and off cleaning up references", 8, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var fn = function() {};
a.listenTo(b, 'event', fn);
b.off();
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._listeners), 0);
a.listenTo(b, 'event', fn);
b.off('event');
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._listeners), 0);
a.listenTo(b, 'event', fn);
b.off(null, fn);
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._listeners), 0);
a.listenTo(b, 'event', fn);
b.off(null, null, a);
assert.equal(_.size(a._listeningTo), 0);
assert.equal(_.size(b._listeners), 0);
equal(_.size(a._listeningTo), 0);
equal(_.size(b._listeners), 0);
});
QUnit.test('listenTo and stopListening cleaning up references', function(assert) {
assert.expect(2);
test("listenTo and stopListening cleaning up references", 2, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenTo(b, 'all', function(){ assert.ok(true); });
a.listenTo(b, 'all', function(){ ok(true); });
b.trigger('anything');
a.listenTo(b, 'other', function(){ assert.ok(false); });
a.listenTo(b, 'other', function(){ ok(false); });
a.stopListening(b, 'other');
a.stopListening(b, 'all');
assert.equal(_.size(a._listeningTo), 0);
equal(_.size(a._listeningTo), 0);
});
QUnit.test('listenToOnce without context cleans up references after the event has fired', function(assert) {
assert.expect(2);
test("listenToOnce without context cleans up references after the event has fired", 2, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, 'all', function(){ assert.ok(true); });
a.listenToOnce(b, 'all', function(){ ok(true); });
b.trigger('anything');
assert.equal(_.size(a._listeningTo), 0);
equal(_.size(a._listeningTo), 0);
});
QUnit.test('listenToOnce with event maps cleans up references', function(assert) {
assert.expect(2);
test("listenToOnce with event maps cleans up references", 2, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, {
one: function() { assert.ok(true); },
two: function() { assert.ok(false); }
one: function() { ok(true); },
two: function() { ok(false); }
});
b.trigger('one');
assert.equal(_.size(a._listeningTo), 1);
equal(_.size(a._listeningTo), 1);
});
QUnit.test('listenToOnce with event maps binds the correct `this`', function(assert) {
assert.expect(1);
test("listenToOnce with event maps binds the correct `this`", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, {
one: function() { assert.ok(this === a); },
two: function() { assert.ok(false); }
one: function() { ok(this === a); },
two: function() { ok(false); }
});
b.trigger('one');
});
QUnit.test("listenTo with empty callback doesn't throw an error", function(assert) {
assert.expect(1);
test("listenTo with empty callback doesn't throw an error", 1, function(){
var e = _.extend({}, Backbone.Events);
e.listenTo(e, 'foo', null);
e.trigger('foo');
assert.ok(true);
e.listenTo(e, "foo", null);
e.trigger("foo");
ok(true);
});
QUnit.test('trigger all for each event', function(assert) {
assert.expect(3);
var a, b, obj = {counter: 0};
test("trigger all for each event", 3, function() {
var a, b, obj = { counter: 0 };
_.extend(obj, Backbone.Events);
obj.on('all', function(event) {
obj.counter++;
if (event === 'a') a = true;
if (event === 'b') b = true;
if (event == 'a') a = true;
if (event == 'b') b = true;
})
.trigger('a b');
assert.ok(a);
assert.ok(b);
assert.equal(obj.counter, 2);
ok(a);
ok(b);
equal(obj.counter, 2);
});
QUnit.test('on, then unbind all functions', function(assert) {
assert.expect(1);
var obj = {counter: 0};
_.extend(obj, Backbone.Events);
test("on, then unbind all functions", 1, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counter += 1; };
obj.on('event', callback);
obj.trigger('event');
obj.off('event');
obj.trigger('event');
assert.equal(obj.counter, 1, 'counter should have only been incremented once.');
equal(obj.counter, 1, 'counter should have only been incremented once.');
});
QUnit.test('bind two callbacks, unbind only one', function(assert) {
assert.expect(2);
var obj = {counterA: 0, counterB: 0};
_.extend(obj, Backbone.Events);
test("bind two callbacks, unbind only one", 2, function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counterA += 1; };
obj.on('event', callback);
obj.on('event', function() { obj.counterB += 1; });
obj.trigger('event');
obj.off('event', callback);
obj.trigger('event');
assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
assert.equal(obj.counterB, 2, 'counterB should have been incremented twice.');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 2, 'counterB should have been incremented twice.');
});
QUnit.test('unbind a callback in the midst of it firing', function(assert) {
assert.expect(1);
test("unbind a callback in the midst of it firing", 1, function() {
var obj = {counter: 0};
_.extend(obj, Backbone.Events);
var callback = function() {
@@ -399,13 +347,12 @@
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
assert.equal(obj.counter, 1, 'the callback should have been unbound.');
equal(obj.counter, 1, 'the callback should have been unbound.');
});
QUnit.test('two binds that unbind themeselves', function(assert) {
assert.expect(2);
var obj = {counterA: 0, counterB: 0};
_.extend(obj, Backbone.Events);
test("two binds that unbind themeselves", 2, function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };
obj.on('event', incrA);
@@ -413,52 +360,48 @@
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
});
QUnit.test('bind a callback with a supplied context', function(assert) {
assert.expect(1);
var TestClass = function() {
test("bind a callback with a supplied context", 1, function () {
var TestClass = function () {
return this;
};
TestClass.prototype.assertTrue = function() {
assert.ok(true, '`this` was bound to the callback');
TestClass.prototype.assertTrue = function () {
ok(true, '`this` was bound to the callback');
};
var obj = _.extend({}, Backbone.Events);
obj.on('event', function() { this.assertTrue(); }, new TestClass);
var obj = _.extend({},Backbone.Events);
obj.on('event', function () { this.assertTrue(); }, (new TestClass));
obj.trigger('event');
});
QUnit.test('nested trigger with unbind', function(assert) {
assert.expect(1);
var obj = {counter: 0};
test("nested trigger with unbind", 1, function () {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
var incr2 = function(){ obj.counter += 1; };
obj.on('event', incr1);
obj.on('event', incr2);
obj.trigger('event');
assert.equal(obj.counter, 3, 'counter should have been incremented three times');
equal(obj.counter, 3, 'counter should have been incremented three times');
});
QUnit.test('callback list is not altered during trigger', function(assert) {
assert.expect(2);
test("callback list is not altered during trigger", 2, function () {
var counter = 0, obj = _.extend({}, Backbone.Events);
var incr = function(){ counter++; };
var incrOn = function(){ obj.on('event all', incr); };
var incrOff = function(){ obj.off('event all', incr); };
obj.on('event all', incrOn).trigger('event');
assert.equal(counter, 0, 'on does not alter callback list');
equal(counter, 0, 'on does not alter callback list');
obj.off().on('event', incrOff).on('event all', incr).trigger('event');
assert.equal(counter, 2, 'off does not alter callback list');
equal(counter, 2, 'off does not alter callback list');
});
QUnit.test("#1282 - 'all' callback list is retrieved after each event.", function(assert) {
assert.expect(1);
test("#1282 - 'all' callback list is retrieved after each event.", 1, function() {
var counter = 0;
var obj = _.extend({}, Backbone.Events);
var incr = function(){ counter++; };
@@ -466,68 +409,61 @@
obj.on('y', incr).on('all', incr);
})
.trigger('x y');
assert.strictEqual(counter, 2);
strictEqual(counter, 2);
});
QUnit.test('if no callback is provided, `on` is a noop', function(assert) {
assert.expect(0);
test("if no callback is provided, `on` is a noop", 0, function() {
_.extend({}, Backbone.Events).on('test').trigger('test');
});
QUnit.test('if callback is truthy but not a function, `on` should throw an error just like jQuery', function(assert) {
assert.expect(1);
test("if callback is truthy but not a function, `on` should throw an error just like jQuery", 1, function() {
var view = _.extend({}, Backbone.Events).on('test', 'noop');
assert.raises(function() {
throws(function() {
view.trigger('test');
});
});
QUnit.test('remove all events for a specific context', function(assert) {
assert.expect(4);
test("remove all events for a specific context", 4, function() {
var obj = _.extend({}, Backbone.Events);
obj.on('x y all', function() { assert.ok(true); });
obj.on('x y all', function() { assert.ok(false); }, obj);
obj.on('x y all', function() { ok(true); });
obj.on('x y all', function() { ok(false); }, obj);
obj.off(null, null, obj);
obj.trigger('x y');
});
QUnit.test('remove all events for a specific callback', function(assert) {
assert.expect(4);
test("remove all events for a specific callback", 4, function() {
var obj = _.extend({}, Backbone.Events);
var success = function() { assert.ok(true); };
var fail = function() { assert.ok(false); };
var success = function() { ok(true); };
var fail = function() { ok(false); };
obj.on('x y all', success);
obj.on('x y all', fail);
obj.off(null, fail);
obj.trigger('x y');
});
QUnit.test('#1310 - off does not skip consecutive events', function(assert) {
assert.expect(0);
test("#1310 - off does not skip consecutive events", 0, function() {
var obj = _.extend({}, Backbone.Events);
obj.on('event', function() { assert.ok(false); }, obj);
obj.on('event', function() { assert.ok(false); }, obj);
obj.on('event', function() { ok(false); }, obj);
obj.on('event', function() { ok(false); }, obj);
obj.off(null, null, obj);
obj.trigger('event');
});
QUnit.test('once', function(assert) {
assert.expect(2);
test("once", 2, function() {
// Same as the previous test, but we use once rather than having to explicitly unbind
var obj = {counterA: 0, counterB: 0};
var obj = { counterA: 0, counterB: 0 };
_.extend(obj, Backbone.Events);
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
var incrB = function(){ obj.counterB += 1; };
obj.once('event', incrA);
obj.once('event', incrB);
obj.trigger('event');
assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
});
QUnit.test('once variant one', function(assert) {
assert.expect(3);
var f = function(){ assert.ok(true); };
test("once variant one", 3, function() {
var f = function(){ ok(true); };
var a = _.extend({}, Backbone.Events).once('event', f);
var b = _.extend({}, Backbone.Events).on('event', f);
@@ -538,9 +474,8 @@
b.trigger('event');
});
QUnit.test('once variant two', function(assert) {
assert.expect(3);
var f = function(){ assert.ok(true); };
test("once variant two", 3, function() {
var f = function(){ ok(true); };
var obj = _.extend({}, Backbone.Events);
obj
@@ -550,9 +485,8 @@
.trigger('event');
});
QUnit.test('once with off', function(assert) {
assert.expect(0);
var f = function(){ assert.ok(true); };
test("once with off", 0, function() {
var f = function(){ ok(true); };
var obj = _.extend({}, Backbone.Events);
obj.once('event', f);
@@ -560,8 +494,8 @@
obj.trigger('event');
});
QUnit.test('once with event maps', function(assert) {
var obj = {counter: 0};
test("once with event maps", function() {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var increment = function() {
@@ -575,103 +509,94 @@
}, obj);
obj.trigger('a');
assert.equal(obj.counter, 1);
equal(obj.counter, 1);
obj.trigger('a b');
assert.equal(obj.counter, 2);
equal(obj.counter, 2);
obj.trigger('c');
assert.equal(obj.counter, 3);
equal(obj.counter, 3);
obj.trigger('a b c');
assert.equal(obj.counter, 3);
equal(obj.counter, 3);
});
QUnit.test('once with off only by context', function(assert) {
assert.expect(0);
test("once with off only by context", 0, function() {
var context = {};
var obj = _.extend({}, Backbone.Events);
obj.once('event', function(){ assert.ok(false); }, context);
obj.once('event', function(){ ok(false); }, context);
obj.off(null, null, context);
obj.trigger('event');
});
QUnit.test('Backbone object inherits Events', function(assert) {
assert.ok(Backbone.on === Backbone.Events.on);
test("Backbone object inherits Events", function() {
ok(Backbone.on === Backbone.Events.on);
});
QUnit.test('once with asynchronous events', function(assert) {
var done = assert.async();
assert.expect(1);
var func = _.debounce(function() { assert.ok(true); done(); }, 50);
asyncTest("once with asynchronous events", 1, function() {
var func = _.debounce(function() { ok(true); start(); }, 50);
var obj = _.extend({}, Backbone.Events).once('async', func);
obj.trigger('async');
obj.trigger('async');
});
QUnit.test('once with multiple events.', function(assert) {
assert.expect(2);
test("once with multiple events.", 2, function() {
var obj = _.extend({}, Backbone.Events);
obj.once('x y', function() { assert.ok(true); });
obj.once('x y', function() { ok(true); });
obj.trigger('x y');
});
QUnit.test('Off during iteration with once.', function(assert) {
assert.expect(2);
test("Off during iteration with once.", 2, function() {
var obj = _.extend({}, Backbone.Events);
var f = function(){ this.off('event', f); };
obj.on('event', f);
obj.once('event', function(){});
obj.on('event', function(){ assert.ok(true); });
obj.on('event', function(){ ok(true); });
obj.trigger('event');
obj.trigger('event');
});
QUnit.test('`once` on `all` should work as expected', function(assert) {
assert.expect(1);
test("`once` on `all` should work as expected", 1, function() {
Backbone.once('all', function() {
assert.ok(true);
ok(true);
Backbone.trigger('all');
});
Backbone.trigger('all');
});
QUnit.test('once without a callback is a noop', function(assert) {
assert.expect(0);
test("once without a callback is a noop", 0, function() {
_.extend({}, Backbone.Events).once('event').trigger('event');
});
QUnit.test('listenToOnce without a callback is a noop', function(assert) {
assert.expect(0);
test("listenToOnce without a callback is a noop", 0, function() {
var obj = _.extend({}, Backbone.Events);
obj.listenToOnce(obj, 'event').trigger('event');
});
QUnit.test('event functions are chainable', function(assert) {
test("event functions are chainable", function() {
var obj = _.extend({}, Backbone.Events);
var obj2 = _.extend({}, Backbone.Events);
var fn = function() {};
assert.equal(obj, obj.trigger('noeventssetyet'));
assert.equal(obj, obj.off('noeventssetyet'));
assert.equal(obj, obj.stopListening('noeventssetyet'));
assert.equal(obj, obj.on('a', fn));
assert.equal(obj, obj.once('c', fn));
assert.equal(obj, obj.trigger('a'));
assert.equal(obj, obj.listenTo(obj2, 'a', fn));
assert.equal(obj, obj.listenToOnce(obj2, 'b', fn));
assert.equal(obj, obj.off('a c'));
assert.equal(obj, obj.stopListening(obj2, 'a'));
assert.equal(obj, obj.stopListening());
equal(obj, obj.trigger('noeventssetyet'));
equal(obj, obj.off('noeventssetyet'));
equal(obj, obj.stopListening('noeventssetyet'));
equal(obj, obj.on('a', fn));
equal(obj, obj.once('c', fn));
equal(obj, obj.trigger('a'));
equal(obj, obj.listenTo(obj2, 'a', fn));
equal(obj, obj.listenToOnce(obj2, 'b', fn));
equal(obj, obj.off('a c'));
equal(obj, obj.stopListening(obj2, 'a'));
equal(obj, obj.stopListening());
});
QUnit.test('#3448 - listenToOnce with space-separated events', function(assert) {
assert.expect(2);
test("#3448 - listenToOnce with space-separated events", 2, function() {
var one = _.extend({}, Backbone.Events);
var two = _.extend({}, Backbone.Events);
var count = 1;
one.listenToOnce(two, 'x y', function(n) { assert.ok(n === count++); });
one.listenToOnce(two, 'x y', function(n) { ok(n === count++); });
two.trigger('x', 1);
two.trigger('x', 1);
two.trigger('y', 2);

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,12 @@
(function() {
QUnit.module('Backbone.noConflict');
module("Backbone.noConflict");
QUnit.test('noConflict', function(assert) {
assert.expect(2);
test('noConflict', 2, function() {
var noconflictBackbone = Backbone.noConflict();
assert.equal(window.Backbone, undefined, 'Returned window.Backbone');
equal(window.Backbone, undefined, 'Returned window.Backbone');
window.Backbone = noconflictBackbone;
assert.equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
});
})();

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,6 @@
$('body').append(
'<div id="qunit"></div>' +
'<div id="qunit-fixture"></div>'
);
'<div id="qunit-fixture">' +
'<div id="testElement"><h1>Test</h1></div>' +
'</div>'
);

View File

@@ -8,8 +8,6 @@
var pushState = history.pushState;
var replaceState = history.replaceState;
QUnit.config.noglobals = true;
QUnit.testStart(function() {
var env = QUnit.config.current.testEnvironment;

View File

@@ -1,236 +1,218 @@
(function() {
var Library = Backbone.Collection.extend({
url: function() { return '/library'; }
url : function() { return '/library'; }
});
var library;
var attrs = {
title: 'The Tempest',
author: 'Bill Shakespeare',
length: 123
title : "The Tempest",
author : "Bill Shakespeare",
length : 123
};
QUnit.module('Backbone.sync', {
module("Backbone.sync", {
beforeEach: function(assert) {
setup : function() {
library = new Library;
library.create(attrs, {wait: false});
},
afterEach: function(assert) {
teardown: function() {
Backbone.emulateHTTP = false;
}
});
QUnit.test('read', function(assert) {
assert.expect(4);
test("read", 4, function() {
library.fetch();
assert.equal(this.ajaxSettings.url, '/library');
assert.equal(this.ajaxSettings.type, 'GET');
assert.equal(this.ajaxSettings.dataType, 'json');
assert.ok(_.isEmpty(this.ajaxSettings.data));
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.type, 'GET');
equal(this.ajaxSettings.dataType, 'json');
ok(_.isEmpty(this.ajaxSettings.data));
});
QUnit.test('passing data', function(assert) {
assert.expect(3);
test("passing data", 3, function() {
library.fetch({data: {a: 'a', one: 1}});
assert.equal(this.ajaxSettings.url, '/library');
assert.equal(this.ajaxSettings.data.a, 'a');
assert.equal(this.ajaxSettings.data.one, 1);
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.data.a, 'a');
equal(this.ajaxSettings.data.one, 1);
});
QUnit.test('create', function(assert) {
assert.expect(6);
assert.equal(this.ajaxSettings.url, '/library');
assert.equal(this.ajaxSettings.type, 'POST');
assert.equal(this.ajaxSettings.dataType, 'json');
test("create", 6, function() {
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.dataType, 'json');
var data = JSON.parse(this.ajaxSettings.data);
assert.equal(data.title, 'The Tempest');
assert.equal(data.author, 'Bill Shakespeare');
assert.equal(data.length, 123);
equal(data.title, 'The Tempest');
equal(data.author, 'Bill Shakespeare');
equal(data.length, 123);
});
QUnit.test('update', function(assert) {
assert.expect(7);
test("update", 7, function() {
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
assert.equal(this.ajaxSettings.url, '/library/1-the-tempest');
assert.equal(this.ajaxSettings.type, 'PUT');
assert.equal(this.ajaxSettings.dataType, 'json');
equal(this.ajaxSettings.url, '/library/1-the-tempest');
equal(this.ajaxSettings.type, 'PUT');
equal(this.ajaxSettings.dataType, 'json');
var data = JSON.parse(this.ajaxSettings.data);
assert.equal(data.id, '1-the-tempest');
assert.equal(data.title, 'The Tempest');
assert.equal(data.author, 'William Shakespeare');
assert.equal(data.length, 123);
equal(data.id, '1-the-tempest');
equal(data.title, 'The Tempest');
equal(data.author, 'William Shakespeare');
equal(data.length, 123);
});
QUnit.test('update with emulateHTTP and emulateJSON', function(assert) {
assert.expect(7);
test("update with emulateHTTP and emulateJSON", 7, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateHTTP: true,
emulateJSON: true
});
assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
assert.equal(this.ajaxSettings.type, 'POST');
assert.equal(this.ajaxSettings.dataType, 'json');
assert.equal(this.ajaxSettings.data._method, 'PUT');
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.dataType, 'json');
equal(this.ajaxSettings.data._method, 'PUT');
var data = JSON.parse(this.ajaxSettings.data.model);
assert.equal(data.id, '2-the-tempest');
assert.equal(data.author, 'Tim Shakespeare');
assert.equal(data.length, 123);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
QUnit.test('update with just emulateHTTP', function(assert) {
assert.expect(6);
test("update with just emulateHTTP", 6, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateHTTP: true
});
assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
assert.equal(this.ajaxSettings.type, 'POST');
assert.equal(this.ajaxSettings.contentType, 'application/json');
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.contentType, 'application/json');
var data = JSON.parse(this.ajaxSettings.data);
assert.equal(data.id, '2-the-tempest');
assert.equal(data.author, 'Tim Shakespeare');
assert.equal(data.length, 123);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
QUnit.test('update with just emulateJSON', function(assert) {
assert.expect(6);
test("update with just emulateJSON", 6, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateJSON: true
});
assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
assert.equal(this.ajaxSettings.type, 'PUT');
assert.equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'PUT');
equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
var data = JSON.parse(this.ajaxSettings.data.model);
assert.equal(data.id, '2-the-tempest');
assert.equal(data.author, 'Tim Shakespeare');
assert.equal(data.length, 123);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
QUnit.test('read model', function(assert) {
assert.expect(3);
test("read model", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().fetch();
assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
assert.equal(this.ajaxSettings.type, 'GET');
assert.ok(_.isEmpty(this.ajaxSettings.data));
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'GET');
ok(_.isEmpty(this.ajaxSettings.data));
});
QUnit.test('destroy', function(assert) {
assert.expect(3);
test("destroy", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().destroy({wait: true});
assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
assert.equal(this.ajaxSettings.type, 'DELETE');
assert.equal(this.ajaxSettings.data, null);
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'DELETE');
equal(this.ajaxSettings.data, null);
});
QUnit.test('destroy with emulateHTTP', function(assert) {
assert.expect(3);
test("destroy with emulateHTTP", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().destroy({
emulateHTTP: true,
emulateJSON: true
});
assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
assert.equal(this.ajaxSettings.type, 'POST');
assert.equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
});
QUnit.test('urlError', function(assert) {
assert.expect(2);
test("urlError", 2, function() {
var model = new Backbone.Model();
assert.raises(function() {
throws(function() {
model.fetch();
});
model.fetch({url: '/one/two'});
assert.equal(this.ajaxSettings.url, '/one/two');
equal(this.ajaxSettings.url, '/one/two');
});
QUnit.test('#1052 - `options` is optional.', function(assert) {
assert.expect(0);
test("#1052 - `options` is optional.", 0, function() {
var model = new Backbone.Model();
model.url = '/test';
Backbone.sync('create', model);
});
QUnit.test('Backbone.ajax', function(assert) {
assert.expect(1);
test("Backbone.ajax", 1, function() {
Backbone.ajax = function(settings){
assert.strictEqual(settings.url, '/test');
strictEqual(settings.url, '/test');
};
var model = new Backbone.Model();
model.url = '/test';
Backbone.sync('create', model);
});
QUnit.test('Call provided error callback on error.', function(assert) {
assert.expect(1);
test("Call provided error callback on error.", 1, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.sync('read', model, {
error: function() { assert.ok(true); }
error: function() { ok(true); }
});
this.ajaxSettings.error();
});
QUnit.test('Use Backbone.emulateHTTP as default.', function(assert) {
assert.expect(2);
test('Use Backbone.emulateHTTP as default.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.emulateHTTP = true;
model.sync('create', model);
assert.strictEqual(this.ajaxSettings.emulateHTTP, true);
strictEqual(this.ajaxSettings.emulateHTTP, true);
Backbone.emulateHTTP = false;
model.sync('create', model);
assert.strictEqual(this.ajaxSettings.emulateHTTP, false);
strictEqual(this.ajaxSettings.emulateHTTP, false);
});
QUnit.test('Use Backbone.emulateJSON as default.', function(assert) {
assert.expect(2);
test('Use Backbone.emulateJSON as default.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.emulateJSON = true;
model.sync('create', model);
assert.strictEqual(this.ajaxSettings.emulateJSON, true);
strictEqual(this.ajaxSettings.emulateJSON, true);
Backbone.emulateJSON = false;
model.sync('create', model);
assert.strictEqual(this.ajaxSettings.emulateJSON, false);
strictEqual(this.ajaxSettings.emulateJSON, false);
});
QUnit.test('#1756 - Call user provided beforeSend function.', function(assert) {
assert.expect(4);
test("#1756 - Call user provided beforeSend function.", 4, function() {
Backbone.emulateHTTP = true;
var model = new Backbone.Model;
model.url = '/test';
var xhr = {
setRequestHeader: function(header, value) {
assert.strictEqual(header, 'X-HTTP-Method-Override');
assert.strictEqual(value, 'DELETE');
strictEqual(header, 'X-HTTP-Method-Override');
strictEqual(value, 'DELETE');
}
};
model.sync('delete', model, {
beforeSend: function(_xhr) {
assert.ok(_xhr === xhr);
ok(_xhr === xhr);
return false;
}
});
assert.strictEqual(this.ajaxSettings.beforeSend(xhr), false);
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
});
QUnit.test('#2928 - Pass along `textStatus` and `errorThrown`.', function(assert) {
assert.expect(2);
test('#2928 - Pass along `textStatus` and `errorThrown`.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
model.on('error', function(m, xhr, options) {
assert.strictEqual(options.textStatus, 'textStatus');
assert.strictEqual(options.errorThrown, 'errorThrown');
model.on('error', function(model, xhr, options) {
strictEqual(options.textStatus, 'textStatus');
strictEqual(options.errorThrown, 'errorThrown');
});
model.fetch();
this.ajaxSettings.error({}, 'textStatus', 'errorThrown');

View File

@@ -2,109 +2,97 @@
var view;
QUnit.module('Backbone.View', {
beforeEach: function(assert) {
$('#qunit-fixture').append(
'<div id="testElement"><h1>Test</h1></div>'
);
module("Backbone.View", {
setup: function() {
view = new Backbone.View({
id: 'test-view',
className: 'test-view',
other: 'non-special-option'
id : 'test-view',
className : 'test-view',
other : 'non-special-option'
});
}
});
QUnit.test('constructor', function(assert) {
assert.expect(3);
assert.equal(view.el.id, 'test-view');
assert.equal(view.el.className, 'test-view');
assert.equal(view.el.other, void 0);
test("constructor", 3, function() {
equal(view.el.id, 'test-view');
equal(view.el.className, 'test-view');
equal(view.el.other, void 0);
});
QUnit.test('$', function(assert) {
assert.expect(2);
var myView = new Backbone.View;
myView.setElement('<p><a><b>test</b></a></p>');
var result = myView.$('a b');
test("$", 2, function() {
var view = new Backbone.View;
view.setElement('<p><a><b>test</b></a></p>');
var result = view.$('a b');
assert.strictEqual(result[0].innerHTML, 'test');
assert.ok(result.length === +result.length);
strictEqual(result[0].innerHTML, 'test');
ok(result.length === +result.length);
});
QUnit.test('$el', function(assert) {
assert.expect(3);
var myView = new Backbone.View;
myView.setElement('<p><a><b>test</b></a></p>');
assert.strictEqual(myView.el.nodeType, 1);
test("$el", 3, function() {
var view = new Backbone.View;
view.setElement('<p><a><b>test</b></a></p>');
strictEqual(view.el.nodeType, 1);
assert.ok(myView.$el instanceof Backbone.$);
assert.strictEqual(myView.$el[0], myView.el);
ok(view.$el instanceof Backbone.$);
strictEqual(view.$el[0], view.el);
});
QUnit.test('initialize', function(assert) {
assert.expect(1);
test("initialize", 1, function() {
var View = Backbone.View.extend({
initialize: function() {
this.one = 1;
}
});
assert.strictEqual(new View().one, 1);
strictEqual(new View().one, 1);
});
QUnit.test('render', function(assert) {
assert.expect(1);
var myView = new Backbone.View;
assert.equal(myView.render(), myView, '#render returns the view instance');
test("render", 1, function() {
var view = new Backbone.View;
equal(view.render(), view, '#render returns the view instance');
});
QUnit.test('delegateEvents', function(assert) {
assert.expect(6);
test("delegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var myView = new Backbone.View({el: '#testElement'});
myView.increment = function(){ counter1++; };
myView.$el.on('click', function(){ counter2++; });
var view = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click h1': 'increment'};
myView.delegateEvents(events);
myView.$('h1').trigger('click');
assert.equal(counter1, 1);
assert.equal(counter2, 1);
view.delegateEvents(events);
view.$('h1').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
myView.$('h1').trigger('click');
assert.equal(counter1, 2);
assert.equal(counter2, 2);
view.$('h1').trigger('click');
equal(counter1, 2);
equal(counter2, 2);
myView.delegateEvents(events);
myView.$('h1').trigger('click');
assert.equal(counter1, 3);
assert.equal(counter2, 3);
view.delegateEvents(events);
view.$('h1').trigger('click');
equal(counter1, 3);
equal(counter2, 3);
});
QUnit.test('delegate', function(assert) {
assert.expect(3);
var myView = new Backbone.View({el: '#testElement'});
myView.delegate('click', 'h1', function() {
assert.ok(true);
test("delegate", 3, function() {
var view = new Backbone.View({el: '#testElement'});
view.delegate('click', 'h1', function() {
ok(true);
});
myView.delegate('click', function() {
assert.ok(true);
view.delegate('click', function() {
ok(true);
});
myView.$('h1').trigger('click');
view.$('h1').trigger('click');
assert.equal(myView.delegate(), myView, '#delegate returns the view instance');
equal(view.delegate(), view, '#delegate returns the view instance');
});
QUnit.test('delegateEvents allows functions for callbacks', function(assert) {
assert.expect(3);
var myView = new Backbone.View({el: '<p></p>'});
myView.counter = 0;
test("delegateEvents allows functions for callbacks", 3, function() {
var view = new Backbone.View({el: '<p></p>'});
view.counter = 0;
var events = {
click: function() {
@@ -112,148 +100,137 @@
}
};
myView.delegateEvents(events);
myView.$el.trigger('click');
assert.equal(myView.counter, 1);
view.delegateEvents(events);
view.$el.trigger('click');
equal(view.counter, 1);
myView.$el.trigger('click');
assert.equal(myView.counter, 2);
view.$el.trigger('click');
equal(view.counter, 2);
myView.delegateEvents(events);
myView.$el.trigger('click');
assert.equal(myView.counter, 3);
view.delegateEvents(events);
view.$el.trigger('click');
equal(view.counter, 3);
});
QUnit.test('delegateEvents ignore undefined methods', function(assert) {
assert.expect(0);
var myView = new Backbone.View({el: '<p></p>'});
myView.delegateEvents({'click': 'undefinedMethod'});
myView.$el.trigger('click');
test("delegateEvents ignore undefined methods", 0, function() {
var view = new Backbone.View({el: '<p></p>'});
view.delegateEvents({'click': 'undefinedMethod'});
view.$el.trigger('click');
});
QUnit.test('undelegateEvents', function(assert) {
assert.expect(7);
test("undelegateEvents", 7, function() {
var counter1 = 0, counter2 = 0;
var myView = new Backbone.View({el: '#testElement'});
myView.increment = function(){ counter1++; };
myView.$el.on('click', function(){ counter2++; });
var view = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click h1': 'increment'};
myView.delegateEvents(events);
myView.$('h1').trigger('click');
assert.equal(counter1, 1);
assert.equal(counter2, 1);
view.delegateEvents(events);
view.$('h1').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
myView.undelegateEvents();
myView.$('h1').trigger('click');
assert.equal(counter1, 1);
assert.equal(counter2, 2);
view.undelegateEvents();
view.$('h1').trigger('click');
equal(counter1, 1);
equal(counter2, 2);
myView.delegateEvents(events);
myView.$('h1').trigger('click');
assert.equal(counter1, 2);
assert.equal(counter2, 3);
view.delegateEvents(events);
view.$('h1').trigger('click');
equal(counter1, 2);
equal(counter2, 3);
assert.equal(myView.undelegateEvents(), myView, '#undelegateEvents returns the view instance');
equal(view.undelegateEvents(), view, '#undelegateEvents returns the view instance');
});
QUnit.test('undelegate', function(assert) {
assert.expect(1);
var myView = new Backbone.View({el: '#testElement'});
myView.delegate('click', function() { assert.ok(false); });
myView.delegate('click', 'h1', function() { assert.ok(false); });
test("undelegate", 1, function() {
view = new Backbone.View({el: '#testElement'});
view.delegate('click', function() { ok(false); });
view.delegate('click', 'h1', function() { ok(false); });
myView.undelegate('click');
view.undelegate('click');
myView.$('h1').trigger('click');
myView.$el.trigger('click');
view.$('h1').trigger('click');
view.$el.trigger('click');
assert.equal(myView.undelegate(), myView, '#undelegate returns the view instance');
equal(view.undelegate(), view, '#undelegate returns the view instance');
});
QUnit.test('undelegate with passed handler', function(assert) {
assert.expect(1);
var myView = new Backbone.View({el: '#testElement'});
var listener = function() { assert.ok(false); };
myView.delegate('click', listener);
myView.delegate('click', function() { assert.ok(true); });
myView.undelegate('click', listener);
myView.$el.trigger('click');
test("undelegate with passed handler", 1, function() {
view = new Backbone.View({el: '#testElement'});
var listener = function() { ok(false); };
view.delegate('click', listener);
view.delegate('click', function() { ok(true); });
view.undelegate('click', listener);
view.$el.trigger('click');
});
QUnit.test('undelegate with selector', function(assert) {
assert.expect(2);
var myView = new Backbone.View({el: '#testElement'});
myView.delegate('click', function() { assert.ok(true); });
myView.delegate('click', 'h1', function() { assert.ok(false); });
myView.undelegate('click', 'h1');
myView.$('h1').trigger('click');
myView.$el.trigger('click');
test("undelegate with selector", 2, function() {
view = new Backbone.View({el: '#testElement'});
view.delegate('click', function() { ok(true); });
view.delegate('click', 'h1', function() { ok(false); });
view.undelegate('click', 'h1');
view.$('h1').trigger('click');
view.$el.trigger('click');
});
QUnit.test('undelegate with handler and selector', function(assert) {
assert.expect(2);
var myView = new Backbone.View({el: '#testElement'});
myView.delegate('click', function() { assert.ok(true); });
var handler = function(){ assert.ok(false); };
myView.delegate('click', 'h1', handler);
myView.undelegate('click', 'h1', handler);
myView.$('h1').trigger('click');
myView.$el.trigger('click');
test("undelegate with handler and selector", 2, function() {
view = new Backbone.View({el: '#testElement'});
view.delegate('click', function() { ok(true); });
var handler = function(){ ok(false); };
view.delegate('click', 'h1', handler);
view.undelegate('click', 'h1', handler);
view.$('h1').trigger('click');
view.$el.trigger('click');
});
QUnit.test('tagName can be provided as a string', function(assert) {
assert.expect(1);
test("tagName can be provided as a string", 1, function() {
var View = Backbone.View.extend({
tagName: 'span'
});
assert.equal(new View().el.tagName, 'SPAN');
equal(new View().el.tagName, 'SPAN');
});
QUnit.test('tagName can be provided as a function', function(assert) {
assert.expect(1);
test("tagName can be provided as a function", 1, function() {
var View = Backbone.View.extend({
tagName: function() {
return 'p';
}
});
assert.ok(new View().$el.is('p'));
ok(new View().$el.is('p'));
});
QUnit.test('_ensureElement with DOM node el', function(assert) {
assert.expect(1);
test("_ensureElement with DOM node el", 1, function() {
var View = Backbone.View.extend({
el: document.body
});
assert.equal(new View().el, document.body);
equal(new View().el, document.body);
});
QUnit.test('_ensureElement with string el', function(assert) {
assert.expect(3);
test("_ensureElement with string el", 3, function() {
var View = Backbone.View.extend({
el: 'body'
el: "body"
});
assert.strictEqual(new View().el, document.body);
strictEqual(new View().el, document.body);
View = Backbone.View.extend({
el: '#testElement > h1'
el: "#testElement > h1"
});
assert.strictEqual(new View().el, $('#testElement > h1').get(0));
strictEqual(new View().el, $("#testElement > h1").get(0));
View = Backbone.View.extend({
el: '#nonexistent'
el: "#nonexistent"
});
assert.ok(!new View().el);
ok(!new View().el);
});
QUnit.test('with className and id functions', function(assert) {
assert.expect(2);
test("with className and id functions", 2, function() {
var View = Backbone.View.extend({
className: function() {
return 'className';
@@ -263,54 +240,33 @@
}
});
assert.strictEqual(new View().el.className, 'className');
assert.strictEqual(new View().el.id, 'id');
strictEqual(new View().el.className, 'className');
strictEqual(new View().el.id, 'id');
});
QUnit.test('with attributes', function(assert) {
assert.expect(2);
test("with attributes", 2, function() {
var View = Backbone.View.extend({
attributes: {
'id': 'id',
id: 'id',
'class': 'class'
}
});
assert.strictEqual(new View().el.className, 'class');
assert.strictEqual(new View().el.id, 'id');
strictEqual(new View().el.className, 'class');
strictEqual(new View().el.id, 'id');
});
QUnit.test('with attributes as a function', function(assert) {
assert.expect(1);
test("with attributes as a function", 1, function() {
var View = Backbone.View.extend({
attributes: function() {
return {'class': 'dynamic'};
}
});
assert.strictEqual(new View().el.className, 'dynamic');
strictEqual(new View().el.className, 'dynamic');
});
QUnit.test('should default to className/id properties', function(assert) {
assert.expect(4);
var View = Backbone.View.extend({
className: 'backboneClass',
id: 'backboneId',
attributes: {
'class': 'attributeClass',
'id': 'attributeId'
}
});
var myView = new View;
assert.strictEqual(myView.el.className, 'backboneClass');
assert.strictEqual(myView.el.id, 'backboneId');
assert.strictEqual(myView.$el.attr('class'), 'backboneClass');
assert.strictEqual(myView.$el.attr('id'), 'backboneId');
});
QUnit.test('multiple views per element', function(assert) {
assert.expect(3);
test("multiple views per element", 3, function() {
var count = 0;
var $el = $('<p></p>');
@@ -324,112 +280,105 @@
});
var view1 = new View;
$el.trigger('click');
assert.equal(1, count);
$el.trigger("click");
equal(1, count);
var view2 = new View;
$el.trigger('click');
assert.equal(3, count);
$el.trigger("click");
equal(3, count);
view1.delegateEvents();
$el.trigger('click');
assert.equal(5, count);
$el.trigger("click");
equal(5, count);
});
QUnit.test('custom events', function(assert) {
assert.expect(2);
test("custom events", 2, function() {
var View = Backbone.View.extend({
el: $('body'),
events: {
fake$event: function() { assert.ok(true); }
"fake$event": function() { ok(true); }
}
});
var myView = new View;
var view = new View;
$('body').trigger('fake$event').trigger('fake$event');
$('body').off('fake$event');
$('body').trigger('fake$event');
});
QUnit.test('#1048 - setElement uses provided object.', function(assert) {
assert.expect(2);
test("#1048 - setElement uses provided object.", 2, function() {
var $el = $('body');
var myView = new Backbone.View({el: $el});
assert.ok(myView.$el === $el);
var view = new Backbone.View({el: $el});
ok(view.$el === $el);
myView.setElement($el = $($el));
assert.ok(myView.$el === $el);
view.setElement($el = $($el));
ok(view.$el === $el);
});
QUnit.test('#986 - Undelegate before changing element.', function(assert) {
assert.expect(1);
test("#986 - Undelegate before changing element.", 1, function() {
var button1 = $('<button></button>');
var button2 = $('<button></button>');
var View = Backbone.View.extend({
events: {
click: function(e) {
assert.ok(myView.el === e.target);
ok(view.el === e.target);
}
}
});
var myView = new View({el: button1});
myView.setElement(button2);
var view = new View({el: button1});
view.setElement(button2);
button1.trigger('click');
button2.trigger('click');
});
QUnit.test('#1172 - Clone attributes object', function(assert) {
assert.expect(2);
test("#1172 - Clone attributes object", 2, function() {
var View = Backbone.View.extend({
attributes: {foo: 'bar'}
});
var view1 = new View({id: 'foo'});
assert.strictEqual(view1.el.id, 'foo');
strictEqual(view1.el.id, 'foo');
var view2 = new View();
assert.ok(!view2.el.id);
ok(!view2.el.id);
});
QUnit.test('views stopListening', function(assert) {
assert.expect(0);
test("views stopListening", 0, function() {
var View = Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, 'all x', function(){ assert.ok(false); });
this.listenTo(this.collection, 'all x', function(){ assert.ok(false); });
this.listenTo(this.model, 'all x', function(){ ok(false); });
this.listenTo(this.collection, 'all x', function(){ ok(false); });
}
});
var myView = new View({
var view = new View({
model: new Backbone.Model,
collection: new Backbone.Collection
});
myView.stopListening();
myView.model.trigger('x');
myView.collection.trigger('x');
view.stopListening();
view.model.trigger('x');
view.collection.trigger('x');
});
QUnit.test('Provide function for el.', function(assert) {
assert.expect(2);
test("Provide function for el.", 2, function() {
var View = Backbone.View.extend({
el: function() {
return '<p><a></a></p>';
return "<p><a></a></p>";
}
});
var myView = new View;
assert.ok(myView.$el.is('p'));
assert.ok(myView.$el.has('a'));
var view = new View;
ok(view.$el.is('p'));
ok(view.$el.has('a'));
});
QUnit.test('events passed in options', function(assert) {
assert.expect(1);
test("events passed in options", 1, function() {
var counter = 0;
var View = Backbone.View.extend({
@@ -439,52 +388,50 @@
}
});
var myView = new View({
var view = new View({
events: {
'click h1': 'increment'
}
});
myView.$('h1').trigger('click').trigger('click');
assert.equal(counter, 2);
view.$('h1').trigger('click').trigger('click');
equal(counter, 2);
});
QUnit.test('remove', function(assert) {
assert.expect(2);
var myView = new Backbone.View;
test("remove", 2, function() {
var view = new Backbone.View;
document.body.appendChild(view.el);
myView.delegate('click', function() { assert.ok(false); });
myView.listenTo(myView, 'all x', function() { assert.ok(false); });
view.delegate('click', function() { ok(false); });
view.listenTo(view, 'all x', function() { ok(false); });
assert.equal(myView.remove(), myView, '#remove returns the view instance');
myView.$el.trigger('click');
myView.trigger('x');
equal(view.remove(), view, '#remove returns the view instance');
view.$el.trigger('click');
view.trigger('x');
// In IE8 and below, parentNode still exists but is not document.body.
assert.notEqual(myView.el.parentNode, document.body);
notEqual(view.el.parentNode, document.body);
});
QUnit.test('setElement', function(assert) {
assert.expect(3);
var myView = new Backbone.View({
test("setElement", 3, function() {
var view = new Backbone.View({
events: {
click: function() { assert.ok(false); }
click: function() { ok(false); }
}
});
myView.events = {
click: function() { assert.ok(true); }
view.events = {
click: function() { ok(true); }
};
var oldEl = myView.el;
var $oldEl = myView.$el;
var oldEl = view.el;
var $oldEl = view.$el;
myView.setElement(document.createElement('div'));
view.setElement(document.createElement('div'));
$oldEl.click();
myView.$el.click();
view.$el.click();
assert.notEqual(oldEl, myView.el);
assert.notEqual($oldEl, myView.$el);
notEqual(oldEl, view.el);
notEqual($oldEl, view.$el);
});
})();

22
vendor/benchmark.js/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright 2010-2015 Mathias Bynens <http://mathiasbynens.be/>
Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
Modified by John-David Dalton <http://allyoucanleet.com/>
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 above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.

2875
vendor/benchmark.js/benchmark.js vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
vendor/benchmark.js/nano.jar vendored Normal file

Binary file not shown.

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative
Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative
Reporters & Editors
Permission is hereby granted, free of charge, to any person

View File

@@ -3,399 +3,398 @@
QUnit.module('Arrays');
QUnit.test('first', function(assert) {
assert.equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
assert.equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements');
assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
test('first', function() {
equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
deepEqual(_.first([1, 2, 3], 0), [], 'can pass an index to first');
deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can pass an index to first');
deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'can pass an index to first');
var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
assert.equal(result, 4, 'works on an arguments object');
equal(result, 4, 'works on an arguments object.');
result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
assert.deepEqual(result, [1, 1], 'works well with _.map');
assert.equal(_.first(null), void 0, 'returns undefined when called on null');
deepEqual(result, [1, 1], 'works well with _.map');
result = (function() { return _.first([1, 2, 3], 2); }());
deepEqual(result, [1, 2]);
equal(_.first(null), undefined, 'handles nulls');
strictEqual(_.first([1, 2, 3], -1).length, 0);
});
QUnit.test('head', function(assert) {
assert.strictEqual(_.head, _.first, 'is an alias for first');
test('head', function() {
strictEqual(_.first, _.head, 'alias for first');
});
QUnit.test('take', function(assert) {
assert.strictEqual(_.take, _.first, 'is an alias for first');
test('take', function() {
strictEqual(_.first, _.take, 'alias for first');
});
QUnit.test('rest', function(assert) {
test('rest', function() {
var numbers = [1, 2, 3, 4];
assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element');
assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0');
assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index');
deepEqual(_.rest(numbers), [2, 3, 4], 'working rest()');
deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'working rest(0)');
deepEqual(_.rest(numbers, 2), [3, 4], 'rest can take an index');
var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
deepEqual(result, [2, 3, 4], 'works on arguments object');
result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
deepEqual(result, [2, 3, 4], 'works on arguments object');
});
QUnit.test('tail', function(assert) {
assert.strictEqual(_.tail, _.rest, 'is an alias for rest');
test('tail', function() {
strictEqual(_.rest, _.tail, 'alias for rest');
});
QUnit.test('drop', function(assert) {
assert.strictEqual(_.drop, _.rest, 'is an alias for rest');
test('drop', function() {
strictEqual(_.rest, _.drop, 'alias for rest');
});
QUnit.test('initial', function(assert) {
assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element');
assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements');
assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length');
test('initial', function() {
deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'working initial()');
deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'initial can take an index');
deepEqual(_.initial([1, 2, 3, 4], 6), [], 'initial can take a large index');
var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
deepEqual(result, [1, 2, 3], 'initial works on arguments object');
result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map');
deepEqual(_.flatten(result), [1, 2, 1, 2], 'initial works with _.map');
});
QUnit.test('last', function(assert) {
assert.equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
assert.equal(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"');
assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements');
assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
test('last', function() {
equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
deepEqual(_.last([1, 2, 3], 0), [], 'can pass an index to last');
deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can pass an index to last');
deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'can pass an index to last');
var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
assert.equal(result, 4, 'works on an arguments object');
equal(result, 4, 'works on an arguments object');
result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
assert.deepEqual(result, [3, 3], 'works well with _.map');
assert.equal(_.last(null), void 0, 'returns undefined when called on null');
deepEqual(result, [3, 3], 'works well with _.map');
equal(_.last(null), undefined, 'handles nulls');
strictEqual(_.last([1, 2, 3], -1).length, 0);
});
QUnit.test('compact', function(assert) {
assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values');
var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3));
assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
result = _.map([[1, false, false], [false, false, 3]], _.compact);
assert.deepEqual(result, [[1], [3]], 'works well with _.map');
test('compact', function() {
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
var result = (function(){ return _.compact(arguments).length; }(0, 1, false, 2, false, 3));
equal(result, 3, 'works on an arguments object');
});
QUnit.test('flatten', function(assert) {
assert.deepEqual(_.flatten(null), [], 'supports null');
assert.deepEqual(_.flatten(void 0), [], 'supports undefined');
test('flatten', function() {
deepEqual(_.flatten(null), [], 'Flattens supports null');
deepEqual(_.flatten(void 0), [], 'Flattens supports undefined');
assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays');
assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays');
deepEqual(_.flatten([[], [[]], []]), [], 'Flattens empty arrays');
deepEqual(_.flatten([[], [[]], []], true), [[]], 'Flattens empty arrays');
var list = [1, [2], [3, [[[4]]]]];
assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
list = [[1], [2], [3], [[4]]];
assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
assert.equal(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23, 'can flatten medium length arrays');
assert.equal(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23, 'can shallowly flatten medium length arrays');
assert.equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'can handle massive arrays');
assert.equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'can handle massive arrays in shallow mode');
var x = _.range(100000);
for (var i = 0; i < 1000; i++) x = [x];
assert.deepEqual(_.flatten(x), _.range(100000), 'can handle very deep arrays');
assert.deepEqual(_.flatten(x, true), x[0], 'can handle very deep arrays in shallow mode');
equal(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23);
equal(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23);
equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'Flatten can handle massive collections');
equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'Flatten can handle massive collections');
});
QUnit.test('without', function(assert) {
test('without', function() {
var list = [1, 2, 1, 0, 3, 1, 4];
assert.deepEqual(_.without(list, 0, 1), [2, 3, 4], 'removes all instances of the given values');
deepEqual(_.without(list, 0, 1), [2, 3, 4], 'can remove all instances of an object');
var result = (function(){ return _.without(arguments, 0, 1); }(1, 2, 1, 0, 3, 1, 4));
assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
deepEqual(result, [2, 3, 4], 'works on an arguments object');
list = [{one: 1}, {two: 2}];
assert.deepEqual(_.without(list, {one: 1}), list, 'compares objects by reference (value case)');
assert.deepEqual(_.without(list, list[0]), [{two: 2}], 'compares objects by reference (reference case)');
list = [{one : 1}, {two : 2}];
equal(_.without(list, {one : 1}).length, 2, 'uses real object identity for comparisons.');
equal(_.without(list, list[0]).length, 1, 'ditto.');
});
QUnit.test('sortedIndex', function(assert) {
var numbers = [10, 20, 30, 40, 50];
var indexFor35 = _.sortedIndex(numbers, 35);
assert.equal(indexFor35, 3, 'finds the index at which a value should be inserted to retain order');
test('sortedIndex', function() {
var numbers = [10, 20, 30, 40, 50], num = 35;
var indexForNum = _.sortedIndex(numbers, num);
equal(indexForNum, 3, '35 should be inserted at index 3');
var indexFor30 = _.sortedIndex(numbers, 30);
assert.equal(indexFor30, 2, 'finds the smallest index at which a value could be inserted to retain order');
equal(indexFor30, 2, '30 should be inserted at index 2');
var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}];
var iterator = function(obj){ return obj.x; };
assert.strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2, 'uses the result of `iterator` for order comparisons');
assert.strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3, 'when `iterator` is a string, uses that key for order comparisons');
strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2);
strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3);
var context = {1: 2, 2: 3, 3: 4};
iterator = function(obj){ return this[obj]; };
assert.strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1, 'can execute its iterator in the given context');
strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1);
var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287,
1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647];
var largeArray = Array(Math.pow(2, 32) - 1);
var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647];
var array = Array(Math.pow(2, 32) - 1);
var length = values.length;
// Sparsely populate `array`
while (length--) {
largeArray[values[length]] = values[length];
array[values[length]] = values[length];
}
assert.equal(_.sortedIndex(largeArray, 2147483648), 2147483648, 'works with large indexes');
equal(_.sortedIndex(array, 2147483648), 2147483648, 'should work with large indexes');
});
QUnit.test('uniq', function(assert) {
test('uniq', function() {
var list = [1, 2, 1, 3, 1, 4];
assert.deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
list = [1, 1, 1, 2, 2, 3];
assert.deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
list = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}, {name: 'Curly'}];
var expected = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}];
var iterator = function(stooge) { return stooge.name; };
assert.deepEqual(_.uniq(list, false, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (unsorted case)');
assert.deepEqual(_.uniq(list, iterator), expected, '`sorted` argument defaults to false when omitted');
assert.deepEqual(_.uniq(list, 'name'), expected, 'when `iterator` is a string, uses that key for comparisons (unsorted case)');
list = [{name: 'moe'}, {name: 'curly'}, {name: 'larry'}, {name: 'curly'}];
var iterator = function(value) { return value.name; };
deepEqual(_.map(_.uniq(list, false, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator');
list = [{score: 8}, {score: 10}, {score: 10}];
expected = [{score: 8}, {score: 10}];
iterator = function(item) { return item.score; };
assert.deepEqual(_.uniq(list, true, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (sorted case)');
assert.deepEqual(_.uniq(list, true, 'score'), expected, 'when `iterator` is a string, uses that key for comparisons (sorted case)');
deepEqual(_.map(_.uniq(list, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator without specifying whether array is sorted');
iterator = function(value) { return value + 1; };
list = [1, 2, 2, 3, 4, 4];
deepEqual(_.uniq(list, true, iterator), [1, 2, 3, 4], 'iterator works with sorted array');
var kittens = [
{kitten: 'Celery', cuteness: 8},
{kitten: 'Juniper', cuteness: 10},
{kitten: 'Spottis', cuteness: 10}
];
var expected = [
{kitten: 'Celery', cuteness: 8},
{kitten: 'Juniper', cuteness: 10}
];
deepEqual(_.uniq(kittens, true, 'cuteness'), expected, 'string iterator works with sorted array');
assert.deepEqual(_.uniq([{0: 1}, {0: 1}, {0: 1}, {0: 2}], 0), [{0: 1}, {0: 2}], 'can use falsey pluck like iterator');
var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4));
assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
var a = {}, b = {}, c = {};
assert.deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered');
deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered');
assert.deepEqual(_.uniq(null), [], 'returns an empty array when `array` is not iterable');
deepEqual(_.uniq(null), []);
var context = {};
list = [3];
_.uniq(list, function(value, index, array) {
assert.strictEqual(this, context, 'executes its iterator in the given context');
assert.strictEqual(value, 3, 'passes its iterator the value');
assert.strictEqual(index, 0, 'passes its iterator the index');
assert.strictEqual(array, list, 'passes its iterator the entire array');
strictEqual(this, context);
strictEqual(value, 3);
strictEqual(index, 0);
strictEqual(array, list);
}, context);
deepEqual(_.uniq([{a: 1, b: 1}, {a: 1, b: 2}, {a: 1, b: 3}, {a: 2, b: 1}], 'a'), [{a: 1, b: 1}, {a: 2, b: 1}], 'can use pluck like iterator');
deepEqual(_.uniq([{0: 1, b: 1}, {0: 1, b: 2}, {0: 1, b: 3}, {0: 2, b: 1}], 0), [{0: 1, b: 1}, {0: 2, b: 1}], 'can use falsey pluck like iterator');
});
QUnit.test('unique', function(assert) {
assert.strictEqual(_.unique, _.uniq, 'is an alias for uniq');
test('unique', function() {
strictEqual(_.uniq, _.unique, 'alias for uniq');
});
QUnit.test('intersection', function(assert) {
test('intersection', function() {
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can find the set intersection of two arrays');
assert.deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection');
deepEqual(_.intersection(stooges, leaders), ['moe'], 'can take the set intersection of two arrays');
deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection');
var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry'));
assert.deepEqual(result, ['moe'], 'works on an arguments object');
deepEqual(result, ['moe'], 'works on an arguments object');
var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry'];
assert.deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array');
deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array');
result = _.intersection([2, 4, 3, 1], [1, 2, 3]);
assert.deepEqual(result, [2, 3, 1], 'preserves the order of the first array');
deepEqual(result, [2, 3, 1], 'preserves order of first array');
result = _.intersection(null, [1, 2, 3]);
assert.deepEqual(result, [], 'returns an empty array when passed null as the first argument');
equal(Object.prototype.toString.call(result), '[object Array]', 'returns an empty array when passed null as first argument');
equal(result.length, 0, 'returns an empty array when passed null as first argument');
result = _.intersection([1, 2, 3], null);
assert.deepEqual(result, [], 'returns an empty array when passed null as an argument beyond the first');
equal(Object.prototype.toString.call(result), '[object Array]', 'returns an empty array when passed null as argument beyond the first');
equal(result.length, 0, 'returns an empty array when passed null as argument beyond the first');
});
QUnit.test('union', function(assert) {
test('union', function() {
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
assert.deepEqual(result, [1, 2, 3, 30, 40], 'can find the union of a list of arrays');
result = _([1, 2, 3]).union([2, 30, 1], [1, 40]);
assert.deepEqual(result, [1, 2, 3, 30, 40], 'can perform an OO-style union');
deepEqual(result, [1, 2, 3, 30, 40], 'takes the union of a list of arrays');
result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
assert.deepEqual(result, [1, 2, 3, 30, 40, [1]], 'can find the union of a list of nested arrays');
deepEqual(result, [1, 2, 3, 30, 40, [1]], 'takes the union of a list of nested arrays');
result = _.union([10, 20], [1, 30, 10], [0, 40]);
assert.deepEqual(result, [10, 20, 1, 30, 0, 40], 'orders values by their first encounter');
var args = null;
(function(){ args = arguments; }(1, 2, 3));
result = _.union(args, [2, 30, 1], [1, 40]);
deepEqual(result, [1, 2, 3, 30, 40], 'takes the union of a list of arrays');
result = (function(){ return _.union(arguments, [2, 30, 1], [1, 40]); }(1, 2, 3));
assert.deepEqual(result, [1, 2, 3, 30, 40], 'works on an arguments object');
assert.deepEqual(_.union([1, 2, 3], 4), [1, 2, 3], 'restricts the union to arrays only');
result = _.union([1, 2, 3], 4);
deepEqual(result, [1, 2, 3], 'restrict the union to arrays only');
});
QUnit.test('difference', function(assert) {
test('difference', function() {
var result = _.difference([1, 2, 3], [2, 30, 40]);
assert.deepEqual(result, [1, 3], 'can find the difference of two arrays');
result = _([1, 2, 3]).difference([2, 30, 40]);
assert.deepEqual(result, [1, 3], 'can perform an OO-style difference');
deepEqual(result, [1, 3], 'takes the difference of two arrays');
result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
assert.deepEqual(result, [3, 4], 'can find the difference of three arrays');
result = _.difference([8, 9, 3, 1], [3, 8]);
assert.deepEqual(result, [9, 1], 'preserves the order of the first array');
result = (function(){ return _.difference(arguments, [2, 30, 40]); }(1, 2, 3));
assert.deepEqual(result, [1, 3], 'works on an arguments object');
deepEqual(result, [3, 4], 'takes the difference of three arrays');
result = _.difference([1, 2, 3], 1);
assert.deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only');
deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only');
});
QUnit.test('zip', function(assert) {
test('zip', function() {
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
assert.deepEqual(_.zip(names, ages, leaders), [
deepEqual(_.zip(names, ages, leaders), [
['moe', 30, true],
['larry', 40, void 0],
['curly', 50, void 0]
['larry', 40, undefined],
['curly', 50, undefined]
], 'zipped together arrays of different lengths');
var stooges = _.zip(['moe', 30, 'stooge 1'], ['larry', 40, 'stooge 2'], ['curly', 50, 'stooge 3']);
assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
// In the case of different lengths of the tuples, undefined values
// In the case of difference lengths of the tuples undefineds
// should be used as placeholder
stooges = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [void 0, void 0, 'extra data']], 'zipped pairs with empties');
deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [undefined, undefined, 'extra data']], 'zipped pairs with empties');
var empty = _.zip([]);
assert.deepEqual(empty, [], 'unzipped empty');
deepEqual(empty, [], 'unzipped empty');
assert.deepEqual(_.zip(null), [], 'handles null');
assert.deepEqual(_.zip(), [], '_.zip() returns []');
deepEqual(_.zip(null), [], 'handles null');
deepEqual(_.zip(), [], '_.zip() returns []');
});
QUnit.test('unzip', function(assert) {
assert.deepEqual(_.unzip(null), [], 'handles null');
test('unzip', function() {
deepEqual(_.unzip(null), [], 'handles null');
assert.deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]);
deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]);
// complements zip
var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
assert.deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]);
deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]);
zipped = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
assert.deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array');
deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array');
});
QUnit.test('object', function(assert) {
test('object', function() {
var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
var shouldBe = {moe: 30, larry: 40, curly: 50};
assert.deepEqual(result, shouldBe, 'two arrays zipped together into an object');
deepEqual(result, shouldBe, 'two arrays zipped together into an object');
result = _.object([['one', 1], ['two', 2], ['three', 3]]);
shouldBe = {one: 1, two: 2, three: 3};
assert.deepEqual(result, shouldBe, 'an array of pairs zipped together into an object');
deepEqual(result, shouldBe, 'an array of pairs zipped together into an object');
var stooges = {moe: 30, larry: 40, curly: 50};
assert.deepEqual(_.object(_.pairs(stooges)), stooges, 'an object converted to pairs and back to an object');
deepEqual(_.object(_.pairs(stooges)), stooges, 'an object converted to pairs and back to an object');
assert.deepEqual(_.object(null), {}, 'handles nulls');
deepEqual(_.object(null), {}, 'handles nulls');
});
QUnit.test('indexOf', function(assert) {
test('indexOf', function() {
var numbers = [1, 2, 3];
assert.equal(_.indexOf(numbers, 2), 1, 'can compute indexOf');
equal(_.indexOf(numbers, 2), 1, 'can compute indexOf');
var result = (function(){ return _.indexOf(arguments, 2); }(1, 2, 3));
assert.equal(result, 1, 'works on an arguments object');
equal(result, 1, 'works on an arguments object');
_.each([null, void 0, [], false], function(val) {
var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
assert.equal(_.indexOf(val, 2), -1, msg);
assert.equal(_.indexOf(val, 2, -1), -1, msg);
assert.equal(_.indexOf(val, 2, -20), -1, msg);
assert.equal(_.indexOf(val, 2, 15), -1, msg);
equal(_.indexOf(val, 2), -1, msg);
equal(_.indexOf(val, 2, -1), -1, msg);
equal(_.indexOf(val, 2, -20), -1, msg);
equal(_.indexOf(val, 2, 15), -1, msg);
});
var num = 35;
numbers = [10, 20, 30, 40, 50];
var index = _.indexOf(numbers, num, true);
assert.equal(index, -1, '35 is not in the list');
equal(index, -1, '35 is not in the list');
numbers = [10, 20, 30, 40, 50]; num = 40;
index = _.indexOf(numbers, num, true);
assert.equal(index, 3, '40 is in the list');
equal(index, 3, '40 is in the list');
numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
assert.equal(_.indexOf(numbers, num, true), 1, '40 is in the list');
assert.equal(_.indexOf(numbers, 6, true), -1, '6 isnt in the list');
assert.equal(_.indexOf([1, 2, 5, 4, 6, 7], 5, true), -1, 'sorted indexOf doesn\'t uses binary search');
assert.ok(_.every(['1', [], {}, null], function() {
equal(_.indexOf(numbers, num, true), 1, '40 is in the list');
equal(_.indexOf(numbers, 6, true), -1, '6 isnt in the list');
equal(_.indexOf([1, 2, 5, 4, 6, 7], 5, true), -1, 'sorted indexOf doesn\'t uses binary search');
ok(_.every(['1', [], {}, null], function() {
return _.indexOf(numbers, num, {}) === 1;
}), 'non-nums as fromIndex make indexOf assume sorted');
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
index = _.indexOf(numbers, 2, 5);
assert.equal(index, 7, 'supports the fromIndex argument');
equal(index, 7, 'supports the fromIndex argument');
index = _.indexOf([,,, 0], void 0);
assert.equal(index, 0, 'treats sparse arrays as if they were dense');
index = _.indexOf([,,,], undefined);
equal(index, 0, 'treats sparse arrays as if they were dense');
var array = [1, 2, 3, 1, 2, 3];
assert.strictEqual(_.indexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
assert.strictEqual(_.indexOf(array, 1, -2), -1, 'neg `fromIndex` starts at the right index');
assert.strictEqual(_.indexOf(array, 2, -3), 4);
strictEqual(_.indexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
strictEqual(_.indexOf(array, 1, -2), -1, 'neg `fromIndex` starts at the right index');
strictEqual(_.indexOf(array, 2, -3), 4);
_.each([-6, -8, -Infinity], function(fromIndex) {
assert.strictEqual(_.indexOf(array, 1, fromIndex), 0);
strictEqual(_.indexOf(array, 1, fromIndex), 0);
});
assert.strictEqual(_.indexOf([1, 2, 3], 1, true), 0);
strictEqual(_.indexOf([1, 2, 3], 1, true), 0);
index = _.indexOf([], void 0, true);
assert.equal(index, -1, 'empty array with truthy `isSorted` returns -1');
index = _.indexOf([], undefined, true);
equal(index, -1, 'empty array with truthy `isSorted` returns -1');
});
QUnit.test('indexOf with NaN', function(assert) {
assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN');
assert.strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
test('indexOf with NaN', function() {
strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN');
strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, 1), 2, 'startIndex does not affect result');
assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, -2), 2, 'startIndex does not affect result');
strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, 1), 2, 'startIndex does not affect result');
strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, -2), 2, 'startIndex does not affect result');
(function() {
assert.strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN');
strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN');
}(1, 2, NaN, NaN));
});
QUnit.test('indexOf with +- 0', function(assert) {
test('indexOf with +- 0', function() {
_.each([-0, +0], function(val) {
assert.strictEqual(_.indexOf([1, 2, val, val], val), 2);
assert.strictEqual(_.indexOf([1, 2, val, val], -val), 2);
strictEqual(_.indexOf([1, 2, val, val], val), 2);
strictEqual(_.indexOf([1, 2, val, val], -val), 2);
});
});
QUnit.test('lastIndexOf', function(assert) {
test('lastIndexOf', function() {
var numbers = [1, 0, 1];
var falsey = [void 0, '', 0, false, NaN, null, void 0];
assert.equal(_.lastIndexOf(numbers, 1), 2);
var falsey = [void 0, '', 0, false, NaN, null, undefined];
equal(_.lastIndexOf(numbers, 1), 2);
numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
numbers.lastIndexOf = null;
assert.equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
assert.equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
var result = (function(){ return _.lastIndexOf(arguments, 1); }(1, 0, 1, 0, 0, 1, 0, 0, 0));
assert.equal(result, 5, 'works on an arguments object');
equal(result, 5, 'works on an arguments object');
_.each([null, void 0, [], false], function(val) {
var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
assert.equal(_.lastIndexOf(val, 2), -1, msg);
assert.equal(_.lastIndexOf(val, 2, -1), -1, msg);
assert.equal(_.lastIndexOf(val, 2, -20), -1, msg);
assert.equal(_.lastIndexOf(val, 2, 15), -1, msg);
equal(_.lastIndexOf(val, 2), -1, msg);
equal(_.lastIndexOf(val, 2, -1), -1, msg);
equal(_.lastIndexOf(val, 2, -20), -1, msg);
equal(_.lastIndexOf(val, 2, 15), -1, msg);
});
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
var index = _.lastIndexOf(numbers, 2, 2);
assert.equal(index, 1, 'supports the fromIndex argument');
equal(index, 1, 'supports the fromIndex argument');
var array = [1, 2, 3, 1, 2, 3];
assert.strictEqual(_.lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx');
assert.strictEqual(_.lastIndexOf(array, 3), 5, 'should return the index of the last matched value');
assert.strictEqual(_.lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value');
strictEqual(_.lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx');
strictEqual(_.lastIndexOf(array, 3), 5, 'should return the index of the last matched value');
strictEqual(_.lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value');
assert.strictEqual(_.lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`');
strictEqual(_.lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`');
_.each([6, 8, Math.pow(2, 32), Infinity], function(fromIndex) {
assert.strictEqual(_.lastIndexOf(array, void 0, fromIndex), -1);
assert.strictEqual(_.lastIndexOf(array, 1, fromIndex), 3);
assert.strictEqual(_.lastIndexOf(array, '', fromIndex), -1);
strictEqual(_.lastIndexOf(array, undefined, fromIndex), -1);
strictEqual(_.lastIndexOf(array, 1, fromIndex), 3);
strictEqual(_.lastIndexOf(array, '', fromIndex), -1);
});
var expected = _.map(falsey, function(value) {
@@ -406,150 +405,133 @@
return _.lastIndexOf(array, 3, fromIndex);
});
assert.deepEqual(actual, expected, 'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`');
assert.strictEqual(_.lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`');
assert.strictEqual(_.lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`');
deepEqual(actual, expected, 'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`');
strictEqual(_.lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`');
strictEqual(_.lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`');
assert.strictEqual(_.lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`');
assert.strictEqual(_.lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
strictEqual(_.lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`');
strictEqual(_.lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
assert.deepEqual(_.map([-6, -8, -Infinity], function(fromIndex) {
deepEqual(_.map([-6, -8, -Infinity], function(fromIndex) {
return _.lastIndexOf(array, 1, fromIndex);
}), [0, -1, -1]);
});
QUnit.test('lastIndexOf with NaN', function(assert) {
assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN');
assert.strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
test('lastIndexOf with NaN', function() {
strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN');
strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, 2), 2, 'fromIndex does not affect result');
assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, -2), 2, 'fromIndex does not affect result');
strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, 2), 2, 'fromIndex does not affect result');
strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, -2), 2, 'fromIndex does not affect result');
(function() {
assert.strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN');
strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN');
}(1, 2, NaN, NaN));
});
QUnit.test('lastIndexOf with +- 0', function(assert) {
test('lastIndexOf with +- 0', function() {
_.each([-0, +0], function(val) {
assert.strictEqual(_.lastIndexOf([1, 2, val, val], val), 3);
assert.strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3);
assert.strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1);
strictEqual(_.lastIndexOf([1, 2, val, val], val), 3);
strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3);
strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1);
});
});
QUnit.test('findIndex', function(assert) {
test('findIndex', function() {
var objects = [
{a: 0, b: 0},
{a: 1, b: 1},
{a: 2, b: 2},
{a: 0, b: 0}
{'a': 0, 'b': 0},
{'a': 1, 'b': 1},
{'a': 2, 'b': 2},
{'a': 0, 'b': 0}
];
assert.equal(_.findIndex(objects, function(obj) {
equal(_.findIndex(objects, function(obj) {
return obj.a === 0;
}), 0);
assert.equal(_.findIndex(objects, function(obj) {
equal(_.findIndex(objects, function(obj) {
return obj.b * obj.a === 4;
}), 2);
assert.equal(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator');
equal(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator');
assert.equal(_.findIndex(objects, function(obj) {
equal(_.findIndex(objects, function(obj) {
return obj.b * obj.a === 5;
}), -1);
assert.equal(_.findIndex(null, _.noop), -1);
assert.strictEqual(_.findIndex(objects, function(a) {
equal(_.findIndex(null, _.noop), -1);
strictEqual(_.findIndex(objects, function(a) {
return a.foo === null;
}), -1);
_.findIndex([{a: 1}], function(a, key, obj) {
assert.equal(key, 0);
assert.deepEqual(obj, [{a: 1}]);
assert.strictEqual(this, objects, 'called with context');
equal(key, 0);
deepEqual(obj, [{a: 1}]);
strictEqual(this, objects, 'called with context');
}, objects);
var sparse = [];
sparse[20] = {a: 2, b: 2};
assert.equal(_.findIndex(sparse, function(obj) {
sparse[20] = {'a': 2, 'b': 2};
equal(_.findIndex(sparse, function(obj) {
return obj && obj.b * obj.a === 4;
}), 20, 'Works with sparse arrays');
var array = [1, 2, 3, 4];
array.match = 55;
assert.strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
});
QUnit.test('findLastIndex', function(assert) {
test('findLastIndex', function() {
var objects = [
{a: 0, b: 0},
{a: 1, b: 1},
{a: 2, b: 2},
{a: 0, b: 0}
{'a': 0, 'b': 0},
{'a': 1, 'b': 1},
{'a': 2, 'b': 2},
{'a': 0, 'b': 0}
];
assert.equal(_.findLastIndex(objects, function(obj) {
equal(_.findLastIndex(objects, function(obj) {
return obj.a === 0;
}), 3);
assert.equal(_.findLastIndex(objects, function(obj) {
equal(_.findLastIndex(objects, function(obj) {
return obj.b * obj.a === 4;
}), 2);
assert.equal(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator');
equal(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator');
assert.equal(_.findLastIndex(objects, function(obj) {
equal(_.findLastIndex(objects, function(obj) {
return obj.b * obj.a === 5;
}), -1);
assert.equal(_.findLastIndex(null, _.noop), -1);
assert.strictEqual(_.findLastIndex(objects, function(a) {
equal(_.findLastIndex(null, _.noop), -1);
strictEqual(_.findLastIndex(objects, function(a) {
return a.foo === null;
}), -1);
_.findLastIndex([{a: 1}], function(a, key, obj) {
assert.equal(key, 0);
assert.deepEqual(obj, [{a: 1}]);
assert.strictEqual(this, objects, 'called with context');
equal(key, 0);
deepEqual(obj, [{a: 1}]);
strictEqual(this, objects, 'called with context');
}, objects);
var sparse = [];
sparse[20] = {a: 2, b: 2};
assert.equal(_.findLastIndex(sparse, function(obj) {
sparse[20] = {'a': 2, 'b': 2};
equal(_.findLastIndex(sparse, function(obj) {
return obj && obj.b * obj.a === 4;
}), 20, 'Works with sparse arrays');
var array = [1, 2, 3, 4];
array.match = 55;
assert.strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
});
QUnit.test('range', function(assert) {
assert.deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array');
assert.deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
assert.deepEqual(_.range(5, 8), [5, 6, 7], 'range with two arguments a &amp; b, a&lt;b generates an array of elements a,a+1,a+2,...,b-2,b-1');
assert.deepEqual(_.range(3, 10, 3), [3, 6, 9], 'range with three arguments a &amp; b &amp; c, c &lt; b-a, a &lt; b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) &lt; c');
assert.deepEqual(_.range(3, 10, 15), [3], 'range with three arguments a &amp; b &amp; c, c &gt; b-a, a &lt; b generates an array with a single element, equal to a');
assert.deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a &amp; b &amp; c, a &gt; b, c &lt; 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
assert.deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs');
assert.strictEqual(1 / _.range(-0, 1)[0], -Infinity, 'should preserve -0');
assert.deepEqual(_.range(8, 5), [8, 7, 6], 'negative range generates descending array');
assert.deepEqual(_.range(-3), [0, -1, -2], 'negative range generates descending array');
test('range', function() {
deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array');
deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
deepEqual(_.range(5, 8), [5, 6, 7], 'range with two arguments a &amp; b, a&lt;b generates an array of elements a,a+1,a+2,...,b-2,b-1');
deepEqual(_.range(8, 5), [], 'range with two arguments a &amp; b, b&lt;a generates an empty array');
deepEqual(_.range(3, 10, 3), [3, 6, 9], 'range with three arguments a &amp; b &amp; c, c &lt; b-a, a &lt; b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) &lt; c');
deepEqual(_.range(3, 10, 15), [3], 'range with three arguments a &amp; b &amp; c, c &gt; b-a, a &lt; b generates an array with a single element, equal to a');
deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a &amp; b &amp; c, a &gt; b, c &lt; 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs');
});
QUnit.test('chunk', function(assert) {
assert.deepEqual(_.chunk([], 2), [], 'chunk for empty array returns an empty array');
assert.deepEqual(_.chunk([1, 2, 3], 0), [], 'chunk into parts of 0 elements returns empty array');
assert.deepEqual(_.chunk([1, 2, 3], -1), [], 'chunk into parts of negative amount of elements returns an empty array');
assert.deepEqual(_.chunk([1, 2, 3]), [], 'defaults to empty array (chunk size 0)');
assert.deepEqual(_.chunk([1, 2, 3], 1), [[1], [2], [3]], 'chunk into parts of 1 elements returns original array');
assert.deepEqual(_.chunk([1, 2, 3], 3), [[1, 2, 3]], 'chunk into parts of current array length elements returns the original array');
assert.deepEqual(_.chunk([1, 2, 3], 5), [[1, 2, 3]], 'chunk into parts of more then current array length elements returns the original array');
assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 2), [[10, 20], [30, 40], [50, 60], [70]], 'chunk into parts of less then current array length elements');
assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 3), [[10, 20, 30], [40, 50, 60], [70]], 'chunk into parts of less then current array length elements');
});
}());

View File

@@ -3,7 +3,7 @@
QUnit.module('Chaining');
QUnit.test('map/flatten/reduce', function(assert) {
test('map/flatten/reduce', function() {
var lyrics = [
'I\'m a lumberjack and I\'m okay',
'I sleep all night and I work all day',
@@ -17,13 +17,12 @@
hash[l] = hash[l] || 0;
hash[l]++;
return hash;
}, {})
.value();
assert.equal(counts.a, 16, 'counted all the letters in the song');
assert.equal(counts.e, 10, 'counted all the letters in the song');
}, {}).value();
equal(counts.a, 16, 'counted all the letters in the song');
equal(counts.e, 10, 'counted all the letters in the song');
});
QUnit.test('select/reject/sortBy', function(assert) {
test('select/reject/sortBy', function() {
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
numbers = _(numbers).chain().select(function(n) {
return n % 2 === 0;
@@ -32,10 +31,10 @@
}).sortBy(function(n) {
return -n;
}).value();
assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
});
QUnit.test('select/reject/sortBy in functional style', function(assert) {
test('select/reject/sortBy in functional style', function() {
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
numbers = _.chain(numbers).select(function(n) {
return n % 2 === 0;
@@ -44,10 +43,10 @@
}).sortBy(function(n) {
return -n;
}).value();
assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
});
QUnit.test('reverse/concat/unshift/pop/map', function(assert) {
test('reverse/concat/unshift/pop/map', function() {
var numbers = [1, 2, 3, 4, 5];
numbers = _(numbers).chain()
.reverse()
@@ -56,44 +55,44 @@
.pop()
.map(function(n){ return n * 2; })
.value();
assert.deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.');
deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.');
});
QUnit.test('splice', function(assert) {
test('splice', function() {
var instance = _([1, 2, 3, 4, 5]).chain();
assert.deepEqual(instance.splice(1, 3).value(), [1, 5]);
assert.deepEqual(instance.splice(1, 0).value(), [1, 5]);
assert.deepEqual(instance.splice(1, 1).value(), [1]);
assert.deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array');
deepEqual(instance.splice(1, 3).value(), [1, 5]);
deepEqual(instance.splice(1, 0).value(), [1, 5]);
deepEqual(instance.splice(1, 1).value(), [1]);
deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array');
});
QUnit.test('shift', function(assert) {
test('shift', function() {
var instance = _([1, 2, 3]).chain();
assert.deepEqual(instance.shift().value(), [2, 3]);
assert.deepEqual(instance.shift().value(), [3]);
assert.deepEqual(instance.shift().value(), [], '#397 Can create empty array');
deepEqual(instance.shift().value(), [2, 3]);
deepEqual(instance.shift().value(), [3]);
deepEqual(instance.shift().value(), [], '#397 Can create empty array');
});
QUnit.test('pop', function(assert) {
test('pop', function() {
var instance = _([1, 2, 3]).chain();
assert.deepEqual(instance.pop().value(), [1, 2]);
assert.deepEqual(instance.pop().value(), [1]);
assert.deepEqual(instance.pop().value(), [], '#397 Can create empty array');
deepEqual(instance.pop().value(), [1, 2]);
deepEqual(instance.pop().value(), [1]);
deepEqual(instance.pop().value(), [], '#397 Can create empty array');
});
QUnit.test('chaining works in small stages', function(assert) {
test('chaining works in small stages', function() {
var o = _([1, 2, 3, 4]).chain();
assert.deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]);
assert.deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]);
deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]);
deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]);
});
QUnit.test('#1562: Engine proxies for chained functions', function(assert) {
test('#1562: Engine proxies for chained functions', function() {
var wrapped = _(512);
assert.strictEqual(wrapped.toJSON(), 512);
assert.strictEqual(wrapped.valueOf(), 512);
assert.strictEqual(+wrapped, 512);
assert.strictEqual(wrapped.toString(), '512');
assert.strictEqual('' + wrapped, '512');
strictEqual(wrapped.toJSON(), 512);
strictEqual(wrapped.valueOf(), 512);
strictEqual(+wrapped, 512);
strictEqual(wrapped.toString(), '512');
strictEqual('' + wrapped, '512');
});
}());

File diff suppressed because it is too large Load Diff

View File

@@ -33,95 +33,95 @@
);
iDoc.close();
QUnit.test('isEqual', function(assert) {
test('isEqual', function() {
assert.ok(!_.isEqual(iNumber, 101));
assert.ok(_.isEqual(iNumber, 100));
ok(!_.isEqual(iNumber, 101));
ok(_.isEqual(iNumber, 100));
// Objects from another frame.
assert.ok(_.isEqual({}, iObject), 'Objects with equivalent members created in different documents are equal');
ok(_.isEqual({}, iObject), 'Objects with equivalent members created in different documents are equal');
// Array from another frame.
assert.ok(_.isEqual([1, 2, 3], iArray), 'Arrays with equivalent elements created in different documents are equal');
ok(_.isEqual([1, 2, 3], iArray), 'Arrays with equivalent elements created in different documents are equal');
});
QUnit.test('isEmpty', function(assert) {
assert.ok(!_([iNumber]).isEmpty(), '[1] is not empty');
assert.ok(!_.isEmpty(iArray), '[] is empty');
assert.ok(_.isEmpty(iObject), '{} is empty');
test('isEmpty', function() {
ok(!_([iNumber]).isEmpty(), '[1] is not empty');
ok(!_.isEmpty(iArray), '[] is empty');
ok(_.isEmpty(iObject), '{} is empty');
});
QUnit.test('isElement', function(assert) {
assert.ok(!_.isElement('div'), 'strings are not dom elements');
assert.ok(_.isElement(document.body), 'the body tag is a DOM element');
assert.ok(_.isElement(iElement), 'even from another frame');
test('isElement', function() {
ok(!_.isElement('div'), 'strings are not dom elements');
ok(_.isElement(document.body), 'the body tag is a DOM element');
ok(_.isElement(iElement), 'even from another frame');
});
QUnit.test('isArguments', function(assert) {
assert.ok(_.isArguments(iArguments), 'even from another frame');
test('isArguments', function() {
ok(_.isArguments(iArguments), 'even from another frame');
});
QUnit.test('isObject', function(assert) {
assert.ok(_.isObject(iElement), 'even from another frame');
assert.ok(_.isObject(iFunction), 'even from another frame');
test('isObject', function() {
ok(_.isObject(iElement), 'even from another frame');
ok(_.isObject(iFunction), 'even from another frame');
});
QUnit.test('isArray', function(assert) {
assert.ok(_.isArray(iArray), 'even from another frame');
test('isArray', function() {
ok(_.isArray(iArray), 'even from another frame');
});
QUnit.test('isString', function(assert) {
assert.ok(_.isString(iString), 'even from another frame');
test('isString', function() {
ok(_.isString(iString), 'even from another frame');
});
QUnit.test('isNumber', function(assert) {
assert.ok(_.isNumber(iNumber), 'even from another frame');
test('isNumber', function() {
ok(_.isNumber(iNumber), 'even from another frame');
});
QUnit.test('isBoolean', function(assert) {
assert.ok(_.isBoolean(iBoolean), 'even from another frame');
test('isBoolean', function() {
ok(_.isBoolean(iBoolean), 'even from another frame');
});
QUnit.test('isFunction', function(assert) {
assert.ok(_.isFunction(iFunction), 'even from another frame');
test('isFunction', function() {
ok(_.isFunction(iFunction), 'even from another frame');
});
QUnit.test('isDate', function(assert) {
assert.ok(_.isDate(iDate), 'even from another frame');
test('isDate', function() {
ok(_.isDate(iDate), 'even from another frame');
});
QUnit.test('isRegExp', function(assert) {
assert.ok(_.isRegExp(iRegExp), 'even from another frame');
test('isRegExp', function() {
ok(_.isRegExp(iRegExp), 'even from another frame');
});
QUnit.test('isNaN', function(assert) {
assert.ok(_.isNaN(iNaN), 'even from another frame');
test('isNaN', function() {
ok(_.isNaN(iNaN), 'even from another frame');
});
QUnit.test('isNull', function(assert) {
assert.ok(_.isNull(iNull), 'even from another frame');
test('isNull', function() {
ok(_.isNull(iNull), 'even from another frame');
});
QUnit.test('isUndefined', function(assert) {
assert.ok(_.isUndefined(iUndefined), 'even from another frame');
test('isUndefined', function() {
ok(_.isUndefined(iUndefined), 'even from another frame');
});
QUnit.test('isError', function(assert) {
assert.ok(_.isError(iError), 'even from another frame');
test('isError', function() {
ok(_.isError(iError), 'even from another frame');
});
if (typeof ActiveXObject != 'undefined') {
QUnit.test('IE host objects', function(assert) {
test('IE host objects', function() {
var xml = new ActiveXObject('Msxml2.DOMDocument.3.0');
assert.ok(!_.isNumber(xml));
assert.ok(!_.isBoolean(xml));
assert.ok(!_.isNaN(xml));
assert.ok(!_.isFunction(xml));
assert.ok(!_.isNull(xml));
assert.ok(!_.isUndefined(xml));
ok(!_.isNumber(xml));
ok(!_.isBoolean(xml));
ok(!_.isNaN(xml));
ok(!_.isFunction(xml));
ok(!_.isNull(xml));
ok(!_.isUndefined(xml));
});
QUnit.test('#1621 IE 11 compat mode DOM elements are not functions', function(assert) {
test('#1621 IE 11 compat mode DOM elements are not functions', function() {
var fn = function() {};
var xml = new ActiveXObject('Msxml2.DOMDocument.3.0');
var div = document.createElement('div');
@@ -132,10 +132,10 @@
_.isFunction(fn);
}
assert.equal(_.isFunction(xml), false);
assert.equal(_.isFunction(div), false);
assert.equal(_.isFunction(fn), true);
equal(_.isFunction(xml), false);
equal(_.isFunction(div), false);
equal(_.isFunction(fn), true);
});
}
}());
}());

View File

@@ -4,65 +4,65 @@
QUnit.module('Functions');
QUnit.config.asyncRetries = 3;
QUnit.test('bind', function(assert) {
var context = {name: 'moe'};
test('bind', function() {
var context = {name : 'moe'};
var func = function(arg) { return 'name: ' + (this.name || arg); };
var bound = _.bind(func, context);
assert.equal(bound(), 'name: moe', 'can bind a function to a context');
equal(bound(), 'name: moe', 'can bind a function to a context');
bound = _(func).bind(context);
assert.equal(bound(), 'name: moe', 'can do OO-style binding');
equal(bound(), 'name: moe', 'can do OO-style binding');
bound = _.bind(func, null, 'curly');
var result = bound();
// Work around a PhantomJS bug when applying a function with null|undefined.
assert.ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context');
ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context');
func = function(salutation, name) { return salutation + ': ' + name; };
func = _.bind(func, this, 'hello');
assert.equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
func = _.bind(func, this, 'curly');
assert.equal(func(), 'hello: curly', 'the function was completely applied in advance');
equal(func(), 'hello: curly', 'the function was completely applied in advance');
func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
func = _.bind(func, this, 'hello', 'moe', 'curly');
assert.equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
func = function(ctx, message) { assert.equal(this, ctx, message); };
func = function(context, message) { equal(this, context, message); };
_.bind(func, 0, 0, 'can bind a function to `0`')();
_.bind(func, '', '', 'can bind a function to an empty string')();
_.bind(func, false, false, 'can bind a function to `false`')();
// These tests are only meaningful when using a browser without a native bind function
// To test this with a modern browser, set underscore's nativeBind to undefined
var F = function() { return this; };
var F = function () { return this; };
var boundf = _.bind(F, {hello: 'moe curly'});
var Boundf = boundf; // make eslint happy.
var newBoundf = new Boundf();
assert.equal(newBoundf.hello, void 0, 'function should not be bound to the context, to comply with ECMAScript 5');
assert.equal(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context");
assert.ok(newBoundf instanceof F, 'a bound instance is an instance of the original function');
equal(newBoundf.hello, undefined, 'function should not be bound to the context, to comply with ECMAScript 5');
equal(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context");
ok(newBoundf instanceof F, 'a bound instance is an instance of the original function');
assert.raises(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function');
throws(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function');
});
QUnit.test('partial', function(assert) {
test('partial', function() {
var obj = {name: 'moe'};
var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
obj.func = _.partial(func, 'a', 'b');
assert.equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
obj.func = _.partial(func, _, 'b', _, 'd');
assert.equal(obj.func('a', 'c'), 'moe a b c d', 'can partially apply with placeholders');
equal(obj.func('a', 'c'), 'moe a b c d', 'can partially apply with placeholders');
func = _.partial(function() { return arguments.length; }, _, 'b', _, 'd');
assert.equal(func('a', 'c', 'e'), 5, 'accepts more arguments than the number of placeholders');
assert.equal(func('a'), 4, 'accepts fewer arguments than the number of placeholders');
equal(func('a', 'c', 'e'), 5, 'accepts more arguments than the number of placeholders');
equal(func('a'), 4, 'accepts fewer arguments than the number of placeholders');
func = _.partial(function() { return typeof arguments[2]; }, _, 'b', _, 'd');
assert.equal(func('a'), 'undefined', 'unfilled placeholders are undefined');
equal(func('a'), 'undefined', 'unfilled placeholders are undefined');
// passes context
function MyWidget(name, options) {
@@ -74,93 +74,78 @@
};
var MyWidgetWithCoolOpts = _.partial(MyWidget, _, {a: 1});
var widget = new MyWidgetWithCoolOpts('foo');
assert.ok(widget instanceof MyWidget, 'Can partially bind a constructor');
assert.equal(widget.get(), 'foo', 'keeps prototype');
assert.deepEqual(widget.options, {a: 1});
_.partial.placeholder = obj;
func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
assert.equal(func('a'), 4, 'allows the placeholder to be swapped out');
_.partial.placeholder = {};
func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
assert.equal(func('a'), 5, 'swapping the placeholder preserves previously bound arguments');
_.partial.placeholder = _;
ok(widget instanceof MyWidget, 'Can partially bind a constructor');
equal(widget.get(), 'foo', 'keeps prototype');
deepEqual(widget.options, {a: 1});
});
QUnit.test('bindAll', function(assert) {
var curly = {name: 'curly'};
var moe = {
name: 'moe',
getName: function() { return 'name: ' + this.name; },
sayHi: function() { return 'hi: ' + this.name; }
test('bindAll', function() {
var curly = {name : 'curly'}, moe = {
name : 'moe',
getName : function() { return 'name: ' + this.name; },
sayHi : function() { return 'hi: ' + this.name; }
};
curly.getName = moe.getName;
_.bindAll(moe, 'getName', 'sayHi');
curly.sayHi = moe.sayHi;
assert.equal(curly.getName(), 'name: curly', 'unbound function is bound to current object');
assert.equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object');
equal(curly.getName(), 'name: curly', 'unbound function is bound to current object');
equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object');
curly = {name: 'curly'};
curly = {name : 'curly'};
moe = {
name: 'moe',
getName: function() { return 'name: ' + this.name; },
sayHi: function() { return 'hi: ' + this.name; },
sayLast: function() { return this.sayHi(_.last(arguments)); }
name : 'moe',
getName : function() { return 'name: ' + this.name; },
sayHi : function() { return 'hi: ' + this.name; },
sayLast : function() { return this.sayHi(_.last(arguments)); }
};
assert.raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named');
assert.raises(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined');
assert.raises(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function');
throws(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named');
throws(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined');
throws(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function');
_.bindAll(moe, 'sayHi', 'sayLast');
curly.sayHi = moe.sayHi;
assert.equal(curly.sayHi(), 'hi: moe');
equal(curly.sayHi(), 'hi: moe');
var sayLast = moe.sayLast;
assert.equal(sayLast(1, 2, 3, 4, 5, 6, 7, 'Tom'), 'hi: moe', 'createCallback works with any number of arguments');
_.bindAll(moe, ['getName']);
var getName = moe.getName;
assert.equal(getName(), 'name: moe', 'flattens arguments into a single list');
equal(sayLast(1, 2, 3, 4, 5, 6, 7, 'Tom'), 'hi: moe', 'createCallback works with any number of arguments');
});
QUnit.test('memoize', function(assert) {
test('memoize', function() {
var fib = function(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2);
};
assert.equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
fib = _.memoize(fib); // Redefine `fib` for memoization
assert.equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
var o = function(str) {
return str;
};
var fastO = _.memoize(o);
assert.equal(o('toString'), 'toString', 'checks hasOwnProperty');
assert.equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
equal(o('toString'), 'toString', 'checks hasOwnProperty');
equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
// Expose the cache.
var upper = _.memoize(function(s) {
return s.toUpperCase();
});
assert.equal(upper('foo'), 'FOO');
assert.equal(upper('bar'), 'BAR');
assert.deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'});
equal(upper('foo'), 'FOO');
equal(upper('bar'), 'BAR');
deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'});
upper.cache = {foo: 'BAR', bar: 'FOO'};
assert.equal(upper('foo'), 'BAR');
assert.equal(upper('bar'), 'FOO');
equal(upper('foo'), 'BAR');
equal(upper('bar'), 'FOO');
var hashed = _.memoize(function(key) {
//https://github.com/jashkenas/underscore/pull/1679#discussion_r13736209
assert.ok(/[a-z]+/.test(key), 'hasher doesn\'t change keys');
ok(/[a-z]+/.test(key), 'hasher doesn\'t change keys');
return key;
}, function(key) {
return key.toUpperCase();
});
hashed('yep');
assert.deepEqual(hashed.cache, {YEP: 'yep'}, 'takes a hasher');
deepEqual(hashed.cache, {'YEP': 'yep'}, 'takes a hasher');
// Test that the hash function can be used to swizzle the key.
var objCacher = _.memoize(function(value, key) {
@@ -170,94 +155,78 @@
});
var myObj = objCacher('a', 'alpha');
var myObjAlias = objCacher('b', 'alpha');
assert.notStrictEqual(myObj, void 0, 'object is created if second argument used as key');
assert.strictEqual(myObj, myObjAlias, 'object is cached if second argument used as key');
assert.strictEqual(myObj.value, 'a', 'object is not modified if second argument used as key');
notStrictEqual(myObj, undefined, 'object is created if second argument used as key');
strictEqual(myObj, myObjAlias, 'object is cached if second argument used as key');
strictEqual(myObj.value, 'a', 'object is not modified if second argument used as key');
});
QUnit.test('delay', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('delay', 2, function() {
var delayed = false;
_.delay(function(){ delayed = true; }, 100);
setTimeout(function(){ assert.ok(!delayed, "didn't delay the function quite yet"); }, 50);
setTimeout(function(){ assert.ok(delayed, 'delayed the function'); done(); }, 150);
setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50);
setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150);
});
QUnit.test('defer', function(assert) {
assert.expect(1);
var done = assert.async();
asyncTest('defer', 1, function() {
var deferred = false;
_.defer(function(bool){ deferred = bool; }, true);
_.delay(function(){ assert.ok(deferred, 'deferred the function'); done(); }, 50);
_.delay(function(){ ok(deferred, 'deferred the function'); start(); }, 50);
});
QUnit.test('throttle', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle', 2, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 32);
throttledIncr(); throttledIncr();
assert.equal(counter, 1, 'incr was called immediately');
_.delay(function(){ assert.equal(counter, 2, 'incr was throttled'); done(); }, 64);
equal(counter, 1, 'incr was called immediately');
_.delay(function(){ equal(counter, 2, 'incr was throttled'); start(); }, 64);
});
QUnit.test('throttle arguments', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle arguments', 2, function() {
var value = 0;
var update = function(val){ value = val; };
var throttledUpdate = _.throttle(update, 32);
throttledUpdate(1); throttledUpdate(2);
_.delay(function(){ throttledUpdate(3); }, 64);
assert.equal(value, 1, 'updated to latest value');
_.delay(function(){ assert.equal(value, 3, 'updated to latest value'); done(); }, 96);
equal(value, 1, 'updated to latest value');
_.delay(function(){ equal(value, 3, 'updated to latest value'); start(); }, 96);
});
QUnit.test('throttle once', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle once', 2, function() {
var counter = 0;
var incr = function(){ return ++counter; };
var throttledIncr = _.throttle(incr, 32);
var result = throttledIncr();
_.delay(function(){
assert.equal(result, 1, 'throttled functions return their value');
assert.equal(counter, 1, 'incr was called once'); done();
equal(result, 1, 'throttled functions return their value');
equal(counter, 1, 'incr was called once'); start();
}, 64);
});
QUnit.test('throttle twice', function(assert) {
assert.expect(1);
var done = assert.async();
asyncTest('throttle twice', 1, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 32);
throttledIncr(); throttledIncr();
_.delay(function(){ assert.equal(counter, 2, 'incr was called twice'); done(); }, 64);
_.delay(function(){ equal(counter, 2, 'incr was called twice'); start(); }, 64);
});
QUnit.test('more throttling', function(assert) {
assert.expect(3);
var done = assert.async();
asyncTest('more throttling', 3, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 30);
throttledIncr(); throttledIncr();
assert.equal(counter, 1);
equal(counter, 1);
_.delay(function(){
assert.equal(counter, 2);
equal(counter, 2);
throttledIncr();
assert.equal(counter, 3);
done();
equal(counter, 3);
start();
}, 85);
});
QUnit.test('throttle repeatedly with results', function(assert) {
assert.expect(6);
var done = assert.async();
asyncTest('throttle repeatedly with results', 6, function() {
var counter = 0;
var incr = function(){ return ++counter; };
var throttledIncr = _.throttle(incr, 100);
@@ -269,19 +238,17 @@
_.delay(saveResult, 160);
_.delay(saveResult, 230);
_.delay(function() {
assert.equal(results[0], 1, 'incr was called once');
assert.equal(results[1], 1, 'incr was throttled');
assert.equal(results[2], 1, 'incr was throttled');
assert.equal(results[3], 2, 'incr was called twice');
assert.equal(results[4], 2, 'incr was throttled');
assert.equal(results[5], 3, 'incr was called trailing');
done();
equal(results[0], 1, 'incr was called once');
equal(results[1], 1, 'incr was throttled');
equal(results[2], 1, 'incr was throttled');
equal(results[3], 2, 'incr was called twice');
equal(results[4], 2, 'incr was throttled');
equal(results[5], 3, 'incr was called trailing');
start();
}, 300);
});
QUnit.test('throttle triggers trailing call when invoked repeatedly', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle triggers trailing call when invoked repeatedly', 2, function() {
var counter = 0;
var limit = 48;
var incr = function(){ counter++; };
@@ -292,33 +259,29 @@
throttledIncr();
}
var lastCount = counter;
assert.ok(counter > 1);
ok(counter > 1);
_.delay(function() {
assert.ok(counter > lastCount);
done();
ok(counter > lastCount);
start();
}, 96);
});
QUnit.test('throttle does not trigger leading call when leading is set to false', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle does not trigger leading call when leading is set to false', 2, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 60, {leading: false});
throttledIncr(); throttledIncr();
assert.equal(counter, 0);
equal(counter, 0);
_.delay(function() {
assert.equal(counter, 1);
done();
equal(counter, 1);
start();
}, 96);
});
QUnit.test('more throttle does not trigger leading call when leading is set to false', function(assert) {
assert.expect(3);
var done = assert.async();
asyncTest('more throttle does not trigger leading call when leading is set to false', 3, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 100, {leading: false});
@@ -327,83 +290,75 @@
_.delay(throttledIncr, 50);
_.delay(throttledIncr, 60);
_.delay(throttledIncr, 200);
assert.equal(counter, 0);
equal(counter, 0);
_.delay(function() {
assert.equal(counter, 1);
equal(counter, 1);
}, 250);
_.delay(function() {
assert.equal(counter, 2);
done();
equal(counter, 2);
start();
}, 350);
});
QUnit.test('one more throttle with leading: false test', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('one more throttle with leading: false test', 2, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 100, {leading: false});
var time = new Date;
while (new Date - time < 350) throttledIncr();
assert.ok(counter <= 3);
ok(counter <= 3);
_.delay(function() {
assert.ok(counter <= 4);
done();
ok(counter <= 4);
start();
}, 200);
});
QUnit.test('throttle does not trigger trailing call when trailing is set to false', function(assert) {
assert.expect(4);
var done = assert.async();
asyncTest('throttle does not trigger trailing call when trailing is set to false', 4, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 60, {trailing: false});
throttledIncr(); throttledIncr(); throttledIncr();
assert.equal(counter, 1);
equal(counter, 1);
_.delay(function() {
assert.equal(counter, 1);
equal(counter, 1);
throttledIncr(); throttledIncr();
assert.equal(counter, 2);
equal(counter, 2);
_.delay(function() {
assert.equal(counter, 2);
done();
equal(counter, 2);
start();
}, 96);
}, 96);
});
QUnit.test('throttle continues to function after system time is set backwards', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle continues to function after system time is set backwards', 2, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 100);
var origNowFunc = _.now;
throttledIncr();
assert.equal(counter, 1);
_.now = function() {
equal(counter, 1);
_.now = function () {
return new Date(2013, 0, 1, 1, 1, 1);
};
_.delay(function() {
throttledIncr();
assert.equal(counter, 2);
done();
equal(counter, 2);
start();
_.now = origNowFunc;
}, 200);
});
QUnit.test('throttle re-entrant', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('throttle re-entrant', 2, function() {
var sequence = [
['b1', 'b2'],
['c1', 'c2']
@@ -419,114 +374,50 @@
};
throttledAppend = _.throttle(append, 32);
throttledAppend.call('a1', 'a2');
assert.equal(value, 'a1a2');
equal(value, 'a1a2');
_.delay(function(){
assert.equal(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
done();
equal(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
start();
}, 100);
});
QUnit.test('throttle cancel', function(assert) {
var done = assert.async();
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 32);
throttledIncr();
throttledIncr.cancel();
throttledIncr();
throttledIncr();
assert.equal(counter, 2, 'incr was called immediately');
_.delay(function(){ assert.equal(counter, 3, 'incr was throttled'); done(); }, 64);
});
QUnit.test('throttle cancel with leading: false', function(assert) {
var done = assert.async();
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 32, {leading: false});
throttledIncr();
throttledIncr.cancel();
assert.equal(counter, 0, 'incr was throttled');
_.delay(function(){ assert.equal(counter, 0, 'incr was throttled'); done(); }, 64);
});
QUnit.test('debounce', function(assert) {
assert.expect(1);
var done = assert.async();
asyncTest('debounce', 1, function() {
var counter = 0;
var incr = function(){ counter++; };
var debouncedIncr = _.debounce(incr, 32);
debouncedIncr(); debouncedIncr();
_.delay(debouncedIncr, 16);
_.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 96);
_.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 96);
});
QUnit.test('debounce cancel', function(assert) {
assert.expect(1);
var done = assert.async();
var counter = 0;
var incr = function(){ counter++; };
var debouncedIncr = _.debounce(incr, 32);
debouncedIncr();
debouncedIncr.cancel();
_.delay(function(){ assert.equal(counter, 0, 'incr was not called'); done(); }, 96);
});
QUnit.test('debounce asap', function(assert) {
assert.expect(4);
var done = assert.async();
asyncTest('debounce asap', 4, function() {
var a, b;
var counter = 0;
var incr = function(){ return ++counter; };
var debouncedIncr = _.debounce(incr, 64, true);
a = debouncedIncr();
b = debouncedIncr();
assert.equal(a, 1);
assert.equal(b, 1);
assert.equal(counter, 1, 'incr was called immediately');
equal(a, 1);
equal(b, 1);
equal(counter, 1, 'incr was called immediately');
_.delay(debouncedIncr, 16);
_.delay(debouncedIncr, 32);
_.delay(debouncedIncr, 48);
_.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 128);
_.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 128);
});
QUnit.test('debounce asap cancel', function(assert) {
assert.expect(4);
var done = assert.async();
var a, b;
var counter = 0;
var incr = function(){ return ++counter; };
var debouncedIncr = _.debounce(incr, 64, true);
a = debouncedIncr();
debouncedIncr.cancel();
b = debouncedIncr();
assert.equal(a, 1);
assert.equal(b, 2);
assert.equal(counter, 2, 'incr was called immediately');
_.delay(debouncedIncr, 16);
_.delay(debouncedIncr, 32);
_.delay(debouncedIncr, 48);
_.delay(function(){ assert.equal(counter, 2, 'incr was debounced'); done(); }, 128);
});
QUnit.test('debounce asap recursively', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('debounce asap recursively', 2, function() {
var counter = 0;
var debouncedIncr = _.debounce(function(){
counter++;
if (counter < 10) debouncedIncr();
}, 32, true);
debouncedIncr();
assert.equal(counter, 1, 'incr was called immediately');
_.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 96);
equal(counter, 1, 'incr was called immediately');
_.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 96);
});
QUnit.test('debounce after system time is set backwards', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('debounce after system time is set backwards', 2, function() {
var counter = 0;
var origNowFunc = _.now;
var debouncedIncr = _.debounce(function(){
@@ -534,23 +425,21 @@
}, 100, true);
debouncedIncr();
assert.equal(counter, 1, 'incr was called immediately');
equal(counter, 1, 'incr was called immediately');
_.now = function() {
_.now = function () {
return new Date(2013, 0, 1, 1, 1, 1);
};
_.delay(function() {
debouncedIncr();
assert.equal(counter, 2, 'incr was debounced successfully');
done();
equal(counter, 2, 'incr was debounced successfully');
start();
_.now = origNowFunc;
}, 200);
});
QUnit.test('debounce re-entrant', function(assert) {
assert.expect(2);
var done = assert.async();
asyncTest('debounce re-entrant', 2, function() {
var sequence = [
['b1', 'b2']
];
@@ -565,81 +454,80 @@
};
debouncedAppend = _.debounce(append, 32);
debouncedAppend.call('a1', 'a2');
assert.equal(value, '');
equal(value, '');
_.delay(function(){
assert.equal(value, 'a1a2b1b2', 'append was debounced successfully');
done();
equal(value, 'a1a2b1b2', 'append was debounced successfully');
start();
}, 100);
});
QUnit.test('once', function(assert) {
test('once', function() {
var num = 0;
var increment = _.once(function(){ return ++num; });
increment();
increment();
assert.equal(num, 1);
equal(num, 1);
assert.equal(increment(), 1, 'stores a memo to the last value');
equal(increment(), 1, 'stores a memo to the last value');
});
QUnit.test('Recursive onced function.', function(assert) {
assert.expect(1);
test('Recursive onced function.', 1, function() {
var f = _.once(function(){
assert.ok(true);
ok(true);
f();
});
f();
});
QUnit.test('wrap', function(assert) {
test('wrap', function() {
var greet = function(name){ return 'hi: ' + name; };
var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
assert.equal(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function');
equal(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function');
var inner = function(){ return 'Hello '; };
var obj = {name: 'Moe'};
obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
assert.equal(obj.hi(), 'Hello Moe');
var obj = {name : 'Moe'};
obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
equal(obj.hi(), 'Hello Moe');
var noop = function(){};
var noop = function(){};
var wrapped = _.wrap(noop, function(){ return Array.prototype.slice.call(arguments, 0); });
var ret = wrapped(['whats', 'your'], 'vector', 'victor');
assert.deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
var ret = wrapped(['whats', 'your'], 'vector', 'victor');
deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
});
QUnit.test('negate', function(assert) {
test('negate', function() {
var isOdd = function(n){ return n & 1; };
assert.equal(_.negate(isOdd)(2), true, 'should return the complement of the given function');
assert.equal(_.negate(isOdd)(3), false, 'should return the complement of the given function');
equal(_.negate(isOdd)(2), true, 'should return the complement of the given function');
equal(_.negate(isOdd)(3), false, 'should return the complement of the given function');
});
QUnit.test('compose', function(assert) {
test('compose', function() {
var greet = function(name){ return 'hi: ' + name; };
var exclaim = function(sentence){ return sentence + '!'; };
var composed = _.compose(exclaim, greet);
assert.equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
composed = _.compose(greet, exclaim);
assert.equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
// f(g(h(x, y, z)))
function h(x, y, z) {
assert.equal(arguments.length, 3, 'First function called with multiple args');
equal(arguments.length, 3, 'First function called with multiple args');
return z * y;
}
function g(x) {
assert.equal(arguments.length, 1, 'Composed function is called with 1 argument');
equal(arguments.length, 1, 'Composed function is called with 1 argument');
return x;
}
function f(x) {
assert.equal(arguments.length, 1, 'Composed function is called with 1 argument');
equal(arguments.length, 1, 'Composed function is called with 1 argument');
return x * 2;
}
composed = _.compose(f, g, h);
assert.equal(composed(1, 2, 3), 12);
equal(composed(1, 2, 3), 12);
});
QUnit.test('after', function(assert) {
test('after', function() {
var testAfter = function(afterAmount, timesCalled) {
var afterCalled = 0;
var after = _.after(afterAmount, function() {
@@ -649,13 +537,13 @@
return afterCalled;
};
assert.equal(testAfter(5, 5), 1, 'after(N) should fire after being called N times');
assert.equal(testAfter(5, 4), 0, 'after(N) should not fire unless called N times');
assert.equal(testAfter(0, 0), 0, 'after(0) should not fire immediately');
assert.equal(testAfter(0, 1), 1, 'after(0) should fire when first invoked');
equal(testAfter(5, 5), 1, 'after(N) should fire after being called N times');
equal(testAfter(5, 4), 0, 'after(N) should not fire unless called N times');
equal(testAfter(0, 0), 0, 'after(0) should not fire immediately');
equal(testAfter(0, 1), 1, 'after(0) should fire when first invoked');
});
QUnit.test('before', function(assert) {
test('before', function() {
var testBefore = function(beforeAmount, timesCalled) {
var beforeCalled = 0;
var before = _.before(beforeAmount, function() { beforeCalled++; });
@@ -663,60 +551,31 @@
return beforeCalled;
};
assert.equal(testBefore(5, 5), 4, 'before(N) should not fire after being called N times');
assert.equal(testBefore(5, 4), 4, 'before(N) should fire before being called N times');
assert.equal(testBefore(0, 0), 0, 'before(0) should not fire immediately');
assert.equal(testBefore(0, 1), 0, 'before(0) should not fire when first invoked');
equal(testBefore(5, 5), 4, 'before(N) should not fire after being called N times');
equal(testBefore(5, 4), 4, 'before(N) should fire before being called N times');
equal(testBefore(0, 0), 0, 'before(0) should not fire immediately');
equal(testBefore(0, 1), 0, 'before(0) should not fire when first invoked');
var context = {num: 0};
var increment = _.before(3, function(){ return ++this.num; });
_.times(10, increment, context);
assert.equal(increment(), 2, 'stores a memo to the last value');
assert.equal(context.num, 2, 'provides context');
equal(increment(), 2, 'stores a memo to the last value');
equal(context.num, 2, 'provides context');
});
QUnit.test('iteratee', function(assert) {
test('iteratee', function() {
var identity = _.iteratee();
assert.equal(identity, _.identity, '_.iteratee is exposed as an external function.');
equal(identity, _.identity, '_.iteratee is exposed as an external function.');
function fn() {
return arguments;
}
_.each([_.iteratee(fn), _.iteratee(fn, {})], function(cb) {
assert.equal(cb().length, 0);
assert.deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4));
assert.deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11));
equal(cb().length, 0);
deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4));
deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11));
});
});
QUnit.test('restArgs', function(assert) {
assert.expect(10);
_.restArgs(function(a, args) {
assert.strictEqual(a, 1);
assert.deepEqual(args, [2, 3], 'collects rest arguments into an array');
})(1, 2, 3);
_.restArgs(function(a, args) {
assert.strictEqual(a, void 0);
assert.deepEqual(args, [], 'passes empty array if there are not enough arguments');
})();
_.restArgs(function(a, b, c, args) {
assert.strictEqual(arguments.length, 4);
assert.deepEqual(args, [4, 5], 'works on functions with many named parameters');
})(1, 2, 3, 4, 5);
var obj = {};
_.restArgs(function() {
assert.strictEqual(this, obj, 'invokes function with this context');
}).call(obj);
_.restArgs(function(array, iteratee, context) {
assert.deepEqual(array, [1, 2, 3, 4], 'startIndex can be used manually specify index of rest parameter');
assert.strictEqual(iteratee, void 0);
assert.strictEqual(context, void 0);
}, 0)(1, 2, 3, 4);
});
}());

File diff suppressed because it is too large Load Diff

View File

@@ -4,217 +4,181 @@
QUnit.module('Utility', {
beforeEach: function() {
setup: function() {
templateSettings = _.clone(_.templateSettings);
},
afterEach: function() {
teardown: function() {
_.templateSettings = templateSettings;
}
});
if (typeof this == 'object') {
QUnit.test('noConflict', function(assert) {
var underscore = _.noConflict();
assert.equal(underscore.identity(1), 1);
if (typeof require != 'function') {
assert.equal(this._, void 0, 'global underscore is removed');
this._ = underscore;
} else if (typeof global !== 'undefined') {
delete global._;
}
});
}
if (typeof require == 'function') {
QUnit.test('noConflict (node vm)', function(assert) {
assert.expect(2);
var done = assert.async();
var fs = require('fs');
var vm = require('vm');
var filename = __dirname + '/../underscore.js';
fs.readFile(filename, function(err, content){
var sandbox = vm.createScript(
content + 'this.underscore = this._.noConflict();',
filename
);
var context = {_: 'oldvalue'};
sandbox.runInNewContext(context);
assert.equal(context._, 'oldvalue');
assert.equal(context.underscore.VERSION, _.VERSION);
done();
});
});
}
QUnit.test('#750 - Return _ instance.', function(assert) {
assert.expect(2);
test('#750 - Return _ instance.', 2, function() {
var instance = _([]);
assert.ok(_(instance) === instance);
assert.ok(new _(instance) === instance);
ok(_(instance) === instance);
ok(new _(instance) === instance);
});
QUnit.test('identity', function(assert) {
var stooge = {name: 'moe'};
assert.equal(_.identity(stooge), stooge, 'stooge is the same as his identity');
test('identity', function() {
var stooge = {name : 'moe'};
equal(_.identity(stooge), stooge, 'stooge is the same as his identity');
});
QUnit.test('constant', function(assert) {
var stooge = {name: 'moe'};
assert.equal(_.constant(stooge)(), stooge, 'should create a function that returns stooge');
test('constant', function() {
var stooge = {name : 'moe'};
equal(_.constant(stooge)(), stooge, 'should create a function that returns stooge');
});
QUnit.test('noop', function(assert) {
assert.strictEqual(_.noop('curly', 'larry', 'moe'), void 0, 'should always return undefined');
test('noop', function() {
strictEqual(_.noop('curly', 'larry', 'moe'), undefined, 'should always return undefined');
});
QUnit.test('property', function(assert) {
var stooge = {name: 'moe'};
assert.equal(_.property('name')(stooge), 'moe', 'should return the property with the given name');
assert.equal(_.property('name')(null), void 0, 'should return undefined for null values');
assert.equal(_.property('name')(void 0), void 0, 'should return undefined for undefined values');
test('property', function() {
var stooge = {name : 'moe'};
equal(_.property('name')(stooge), 'moe', 'should return the property with the given name');
equal(_.property('name')(null), undefined, 'should return undefined for null values');
equal(_.property('name')(undefined), undefined, 'should return undefined for undefined values');
});
QUnit.test('propertyOf', function(assert) {
test('propertyOf', function() {
var stoogeRanks = _.propertyOf({curly: 2, moe: 1, larry: 3});
assert.equal(stoogeRanks('curly'), 2, 'should return the property with the given name');
assert.equal(stoogeRanks(null), void 0, 'should return undefined for null values');
assert.equal(stoogeRanks(void 0), void 0, 'should return undefined for undefined values');
equal(stoogeRanks('curly'), 2, 'should return the property with the given name');
equal(stoogeRanks(null), undefined, 'should return undefined for null values');
equal(stoogeRanks(undefined), undefined, 'should return undefined for undefined values');
function MoreStooges() { this.shemp = 87; }
MoreStooges.prototype = {curly: 2, moe: 1, larry: 3};
var moreStoogeRanks = _.propertyOf(new MoreStooges());
assert.equal(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain');
equal(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain');
var nullPropertyOf = _.propertyOf(null);
assert.equal(nullPropertyOf('curly'), void 0, 'should return undefined when obj is null');
var undefPropertyOf = _.propertyOf(void 0);
assert.equal(undefPropertyOf('curly'), void 0, 'should return undefined when obj is undefined');
equal(nullPropertyOf('curly'), undefined, 'should return undefined when obj is null');
var undefPropertyOf = _.propertyOf(undefined);
equal(undefPropertyOf('curly'), undefined, 'should return undefined when obj is undefined');
});
QUnit.test('random', function(assert) {
test('random', function() {
var array = _.range(1000);
var min = Math.pow(2, 31);
var max = Math.pow(2, 62);
assert.ok(_.every(array, function() {
ok(_.every(array, function() {
return _.random(min, max) >= min;
}), 'should produce a random number greater than or equal to the minimum number');
assert.ok(_.some(array, function() {
ok(_.some(array, function() {
return _.random(Number.MAX_VALUE) > 0;
}), 'should produce a random number when passed `Number.MAX_VALUE`');
});
QUnit.test('now', function(assert) {
test('now', function() {
var diff = _.now() - new Date().getTime();
assert.ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms
ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms
});
QUnit.test('uniqueId', function(assert) {
test('uniqueId', function() {
var ids = [], i = 0;
while (i++ < 100) ids.push(_.uniqueId());
assert.equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
});
QUnit.test('times', function(assert) {
test('times', function() {
var vals = [];
_.times(3, function(i) { vals.push(i); });
assert.deepEqual(vals, [0, 1, 2], 'is 0 indexed');
_.times(3, function (i) { vals.push(i); });
deepEqual(vals, [0, 1, 2], 'is 0 indexed');
//
vals = [];
_(3).times(function(i) { vals.push(i); });
assert.deepEqual(vals, [0, 1, 2], 'works as a wrapper');
deepEqual(vals, [0, 1, 2], 'works as a wrapper');
// collects return values
assert.deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values');
deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values');
assert.deepEqual(_.times(0, _.identity), []);
assert.deepEqual(_.times(-1, _.identity), []);
assert.deepEqual(_.times(parseFloat('-Infinity'), _.identity), []);
deepEqual(_.times(0, _.identity), []);
deepEqual(_.times(-1, _.identity), []);
deepEqual(_.times(parseFloat('-Infinity'), _.identity), []);
});
QUnit.test('mixin', function(assert) {
test('mixin', function() {
_.mixin({
myReverse: function(string) {
return string.split('').reverse().join('');
}
});
assert.equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _');
assert.equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _');
equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
});
QUnit.test('_.escape', function(assert) {
assert.equal(_.escape(null), '');
test('_.escape', function() {
equal(_.escape(null), '');
});
QUnit.test('_.unescape', function(assert) {
test('_.unescape', function() {
var string = 'Curly & Moe';
assert.equal(_.unescape(null), '');
assert.equal(_.unescape(_.escape(string)), string);
assert.equal(_.unescape(string), string, 'don\'t unescape unnecessarily');
equal(_.unescape(null), '');
equal(_.unescape(_.escape(string)), string);
equal(_.unescape(string), string, 'don\'t unescape unnecessarily');
});
// Don't care what they escape them to just that they're escaped and can be unescaped
QUnit.test('_.escape & unescape', function(assert) {
test('_.escape & unescape', function() {
// test & (&amp;) seperately obviously
var escapeCharacters = ['<', '>', '"', '\'', '`'];
_.each(escapeCharacters, function(escapeChar) {
var s = 'a ' + escapeChar + ' string escaped';
var e = _.escape(s);
assert.notEqual(s, e, escapeChar + ' is escaped');
assert.equal(s, _.unescape(e), escapeChar + ' can be unescaped');
var str = 'a ' + escapeChar + ' string escaped';
var escaped = _.escape(str);
notEqual(str, escaped, escapeChar + ' is escaped');
equal(str, _.unescape(escaped), escapeChar + ' can be unescaped');
s = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar;
e = _.escape(s);
str = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar;
escaped = _.escape(str);
assert.equal(e.indexOf(escapeChar), -1, 'can escape multiple occurances of ' + escapeChar);
assert.equal(_.unescape(e), s, 'multiple occurrences of ' + escapeChar + ' can be unescaped');
equal(escaped.indexOf(escapeChar), -1, 'can escape multiple occurances of ' + escapeChar);
equal(_.unescape(escaped), str, 'multiple occurrences of ' + escapeChar + ' can be unescaped');
});
// handles multiple escape characters at once
var joiner = ' other stuff ';
var allEscaped = escapeCharacters.join(joiner);
allEscaped += allEscaped;
assert.ok(_.every(escapeCharacters, function(escapeChar) {
ok(_.every(escapeCharacters, function(escapeChar) {
return allEscaped.indexOf(escapeChar) !== -1;
}), 'handles multiple characters');
assert.ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time');
ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time');
// test & -> &amp;
var str = 'some string & another string & yet another';
var escaped = _.escape(str);
assert.ok(escaped.indexOf('&') !== -1, 'handles & aka &amp;');
assert.equal(_.unescape(str), str, 'can unescape &amp;');
ok(escaped.indexOf('&') !== -1, 'handles & aka &amp;');
equal(_.unescape(str), str, 'can unescape &amp;');
});
QUnit.test('template', function(assert) {
test('template', function() {
var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
var result = basicTemplate({thing: 'This'});
assert.equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
var result = basicTemplate({thing : 'This'});
equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
var sansSemicolonTemplate = _.template('A <% this %> B');
assert.equal(sansSemicolonTemplate(), 'A B');
equal(sansSemicolonTemplate(), 'A B');
var backslashTemplate = _.template('<%= thing %> is \\ridanculous');
assert.equal(backslashTemplate({thing: 'This'}), 'This is \\ridanculous');
equal(backslashTemplate({thing: 'This'}), 'This is \\ridanculous');
var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>');
assert.equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
var fancyTemplate = _.template('<ul><% ' +
' for (var key in people) { ' +
'%><li><%= people[key] %></li><% } %></ul>');
result = fancyTemplate({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
result = fancyTemplate({people : {moe : 'Moe', larry : 'Larry', curly : 'Curly'}});
equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
var escapedCharsInJavascriptTemplate = _.template('<ul><% _.each(numbers.split("\\n"), function(item) { %><li><%= item %></li><% }) %></ul>');
result = escapedCharsInJavascriptTemplate({numbers: 'one\ntwo\nthree\nfour'});
assert.equal(result, '<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>', 'Can use escaped characters (e.g. \\n) in JavaScript');
equal(result, '<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>', 'Can use escaped characters (e.g. \\n) in JavaScript');
var namespaceCollisionTemplate = _.template('<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %><div class="thumbnail" rel="<%= p %>"></div><% }); %>');
result = namespaceCollisionTemplate({
@@ -225,32 +189,32 @@
3: 'p3-thumbnail.gif'
}
});
assert.equal(result, '3 p3-thumbnail.gif <div class="thumbnail" rel="p1-thumbnail.gif"></div><div class="thumbnail" rel="p2-thumbnail.gif"></div><div class="thumbnail" rel="p3-thumbnail.gif"></div>');
equal(result, '3 p3-thumbnail.gif <div class="thumbnail" rel="p1-thumbnail.gif"></div><div class="thumbnail" rel="p2-thumbnail.gif"></div><div class="thumbnail" rel="p3-thumbnail.gif"></div>');
var noInterpolateTemplate = _.template('<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
result = noInterpolateTemplate();
assert.equal(result, '<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
equal(result, '<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
var quoteTemplate = _.template("It's its, not it's");
assert.equal(quoteTemplate({}), "It's its, not it's");
equal(quoteTemplate({}), "It's its, not it's");
var quoteInStatementAndBody = _.template('<% ' +
" if(foo == 'bar'){ " +
"%>Statement quotes and 'quotes'.<% } %>");
assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.');
assert.equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
var template = _.template('<i><%- value %></i>');
result = template({value: '<script>'});
assert.equal(result, '<i>&lt;script&gt;</i>');
equal(result, '<i>&lt;script&gt;</i>');
var stooge = {
name: 'Moe',
template: _.template("I'm <%= this.name %>")
};
assert.equal(stooge.template(), "I'm Moe");
equal(stooge.template(), "I'm Moe");
template = _.template('\n ' +
' <%\n ' +
@@ -258,163 +222,159 @@
' if (data) { data += 12345; }; %>\n ' +
' <li><%= data %></li>\n '
);
assert.equal(template({data: 12345}).replace(/\s/g, ''), '<li>24690</li>');
equal(template({data : 12345}).replace(/\s/g, ''), '<li>24690</li>');
_.templateSettings = {
evaluate: /\{\{([\s\S]+?)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g
evaluate : /\{\{([\s\S]+?)\}\}/g,
interpolate : /\{\{=([\s\S]+?)\}\}/g
};
var custom = _.template('<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>');
result = custom({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
result = custom({people : {moe : 'Moe', larry : 'Larry', curly : 'Curly'}});
equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
var customQuote = _.template("It's its, not it's");
assert.equal(customQuote({}), "It's its, not it's");
equal(customQuote({}), "It's its, not it's");
quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}");
assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
_.templateSettings = {
evaluate: /<\?([\s\S]+?)\?>/g,
interpolate: /<\?=([\s\S]+?)\?>/g
evaluate : /<\?([\s\S]+?)\?>/g,
interpolate : /<\?=([\s\S]+?)\?>/g
};
var customWithSpecialChars = _.template('<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>');
result = customWithSpecialChars({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
result = customWithSpecialChars({people : {moe : 'Moe', larry : 'Larry', curly : 'Curly'}});
equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
var customWithSpecialCharsQuote = _.template("It's its, not it's");
assert.equal(customWithSpecialCharsQuote({}), "It's its, not it's");
equal(customWithSpecialCharsQuote({}), "It's its, not it's");
quoteInStatementAndBody = _.template("<? if(foo == 'bar'){ ?>Statement quotes and 'quotes'.<? } ?>");
assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
interpolate : /\{\{(.+?)\}\}/g
};
var mustache = _.template('Hello {{planet}}!');
assert.equal(mustache({planet: 'World'}), 'Hello World!', 'can mimic mustache.js');
equal(mustache({planet : 'World'}), 'Hello World!', 'can mimic mustache.js');
var templateWithNull = _.template('a null undefined {{planet}}');
assert.equal(templateWithNull({planet: 'world'}), 'a null undefined world', 'can handle missing escape and evaluate settings');
equal(templateWithNull({planet : 'world'}), 'a null undefined world', 'can handle missing escape and evaluate settings');
});
QUnit.test('_.template provides the generated function source, when a SyntaxError occurs', function(assert) {
var source;
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
try {
_.template('<b><%= if x %></b>');
} catch (ex) {
source = ex.source;
var source = ex.source;
}
assert.ok(/__p/.test(source));
ok(/__p/.test(source));
});
QUnit.test('_.template handles \\u2028 & \\u2029', function(assert) {
test('_.template handles \\u2028 & \\u2029', function() {
var tmpl = _.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>');
assert.strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
});
QUnit.test('result calls functions and returns primitives', function(assert) {
test('result calls functions and returns primitives', function() {
var obj = {w: '', x: 'x', y: function(){ return this.x; }};
assert.strictEqual(_.result(obj, 'w'), '');
assert.strictEqual(_.result(obj, 'x'), 'x');
assert.strictEqual(_.result(obj, 'y'), 'x');
assert.strictEqual(_.result(obj, 'z'), void 0);
assert.strictEqual(_.result(null, 'x'), void 0);
strictEqual(_.result(obj, 'w'), '');
strictEqual(_.result(obj, 'x'), 'x');
strictEqual(_.result(obj, 'y'), 'x');
strictEqual(_.result(obj, 'z'), undefined);
strictEqual(_.result(null, 'x'), undefined);
});
QUnit.test('result returns a default value if object is null or undefined', function(assert) {
assert.strictEqual(_.result(null, 'b', 'default'), 'default');
assert.strictEqual(_.result(void 0, 'c', 'default'), 'default');
assert.strictEqual(_.result(''.match('missing'), 1, 'default'), 'default');
test('result returns a default value if object is null or undefined', function() {
strictEqual(_.result(null, 'b', 'default'), 'default');
strictEqual(_.result(undefined, 'c', 'default'), 'default');
strictEqual(_.result(''.match('missing'), 1, 'default'), 'default');
});
QUnit.test('result returns a default value if property of object is missing', function(assert) {
assert.strictEqual(_.result({d: null}, 'd', 'default'), null);
assert.strictEqual(_.result({e: false}, 'e', 'default'), false);
test('result returns a default value if property of object is missing', function() {
strictEqual(_.result({d: null}, 'd', 'default'), null);
strictEqual(_.result({e: false}, 'e', 'default'), false);
});
QUnit.test('result only returns the default value if the object does not have the property or is undefined', function(assert) {
assert.strictEqual(_.result({}, 'b', 'default'), 'default');
assert.strictEqual(_.result({d: void 0}, 'd', 'default'), 'default');
test('result only returns the default value if the object does not have the property or is undefined', function() {
strictEqual(_.result({}, 'b', 'default'), 'default');
strictEqual(_.result({d: undefined}, 'd', 'default'), 'default');
});
QUnit.test('result does not return the default if the property of an object is found in the prototype', function(assert) {
test('result does not return the default if the property of an object is found in the prototype', function() {
var Foo = function(){};
Foo.prototype.bar = 1;
assert.strictEqual(_.result(new Foo, 'bar', 2), 1);
strictEqual(_.result(new Foo, 'bar', 2), 1);
});
QUnit.test('result does use the fallback when the result of invoking the property is undefined', function(assert) {
test('result does use the fallback when the result of invoking the property is undefined', function() {
var obj = {a: function() {}};
assert.strictEqual(_.result(obj, 'a', 'failed'), void 0);
strictEqual(_.result(obj, 'a', 'failed'), undefined);
});
QUnit.test('result fallback can use a function', function(assert) {
test('result fallback can use a function', function() {
var obj = {a: [1, 2, 3]};
assert.strictEqual(_.result(obj, 'b', _.constant(5)), 5);
assert.strictEqual(_.result(obj, 'b', function() {
strictEqual(_.result(obj, 'b', _.constant(5)), 5);
strictEqual(_.result(obj, 'b', function() {
return this.a;
}), obj.a, 'called with context');
});
QUnit.test('_.templateSettings.variable', function(assert) {
test('_.templateSettings.variable', function() {
var s = '<%=data.x%>';
var data = {x: 'x'};
var tmp = _.template(s, {variable: 'data'});
assert.strictEqual(tmp(data), 'x');
strictEqual(tmp(data), 'x');
_.templateSettings.variable = 'data';
assert.strictEqual(_.template(s)(data), 'x');
strictEqual(_.template(s)(data), 'x');
});
QUnit.test('#547 - _.templateSettings is unchanged by custom settings.', function(assert) {
assert.ok(!_.templateSettings.variable);
test('#547 - _.templateSettings is unchanged by custom settings.', function() {
ok(!_.templateSettings.variable);
_.template('', {}, {variable: 'x'});
assert.ok(!_.templateSettings.variable);
ok(!_.templateSettings.variable);
});
QUnit.test('#556 - undefined template variables.', function(assert) {
test('#556 - undefined template variables.', function() {
var template = _.template('<%=x%>');
assert.strictEqual(template({x: null}), '');
assert.strictEqual(template({x: void 0}), '');
strictEqual(template({x: null}), '');
strictEqual(template({x: undefined}), '');
var templateEscaped = _.template('<%-x%>');
assert.strictEqual(templateEscaped({x: null}), '');
assert.strictEqual(templateEscaped({x: void 0}), '');
strictEqual(templateEscaped({x: null}), '');
strictEqual(templateEscaped({x: undefined}), '');
var templateWithProperty = _.template('<%=x.foo%>');
assert.strictEqual(templateWithProperty({x: {}}), '');
assert.strictEqual(templateWithProperty({x: {}}), '');
strictEqual(templateWithProperty({x: {}}), '');
strictEqual(templateWithProperty({x: {}}), '');
var templateWithPropertyEscaped = _.template('<%-x.foo%>');
assert.strictEqual(templateWithPropertyEscaped({x: {}}), '');
assert.strictEqual(templateWithPropertyEscaped({x: {}}), '');
strictEqual(templateWithPropertyEscaped({x: {}}), '');
strictEqual(templateWithPropertyEscaped({x: {}}), '');
});
QUnit.test('interpolate evaluates code only once.', function(assert) {
assert.expect(2);
test('interpolate evaluates code only once.', 2, function() {
var count = 0;
var template = _.template('<%= f() %>');
template({f: function(){ assert.ok(!count++); }});
template({f: function(){ ok(!count++); }});
var countEscaped = 0;
var templateEscaped = _.template('<%- f() %>');
templateEscaped({f: function(){ assert.ok(!countEscaped++); }});
templateEscaped({f: function(){ ok(!countEscaped++); }});
});
QUnit.test('#746 - _.template settings are not modified.', function(assert) {
assert.expect(1);
test('#746 - _.template settings are not modified.', 1, function() {
var settings = {};
_.template('', null, settings);
assert.deepEqual(settings, {});
deepEqual(settings, {});
});
QUnit.test('#779 - delimeters are applied to unescaped text.', function(assert) {
assert.expect(1);
test('#779 - delimeters are applied to unescaped text.', 1, function() {
var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
assert.strictEqual(template(), '<<\nx\n>>');
strictEqual(template(), '<<\nx\n>>');
});
}());

File diff suppressed because it is too large Load Diff