mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 14:37:49 +00:00
Compare commits
207 Commits
1.0.0-rc.3
...
1.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7467a2a2eb | ||
|
|
2459a53350 | ||
|
|
7093e9c0d4 | ||
|
|
4bc49978d1 | ||
|
|
96bac9c149 | ||
|
|
8dcc15f4d3 | ||
|
|
8183740c04 | ||
|
|
25e4231d7b | ||
|
|
3ed9e0e905 | ||
|
|
45bec0c440 | ||
|
|
5133e39d45 | ||
|
|
cb3b4e446e | ||
|
|
9829a2f3b4 | ||
|
|
7eadf11145 | ||
|
|
2a2bc44f43 | ||
|
|
9ccfa5cec9 | ||
|
|
02687f3c78 | ||
|
|
7ea7a6cbb1 | ||
|
|
a15a28fe5b | ||
|
|
265dedfae1 | ||
|
|
5ddbb8bc56 | ||
|
|
4101b8e937 | ||
|
|
56b6d50479 | ||
|
|
506f585d78 | ||
|
|
577dfb7220 | ||
|
|
7e4286adde | ||
|
|
1090228628 | ||
|
|
aeea861b73 | ||
|
|
997c43bbdd | ||
|
|
958d4dbd2e | ||
|
|
f2b350eb62 | ||
|
|
a3464780a1 | ||
|
|
fe1eb92196 | ||
|
|
0b2d26ec92 | ||
|
|
8024a25f2b | ||
|
|
d287ecbb34 | ||
|
|
d9c95e7730 | ||
|
|
c3b1af31ce | ||
|
|
465576b5cb | ||
|
|
9ecbcd0075 | ||
|
|
c1f62d72ae | ||
|
|
1b27834c41 | ||
|
|
77804907b6 | ||
|
|
9dfa2609be | ||
|
|
8ffb3ab3c4 | ||
|
|
65e1da34fa | ||
|
|
282110807c | ||
|
|
25e5f43d1c | ||
|
|
ce0441694d | ||
|
|
db29699927 | ||
|
|
9a4e2d7617 | ||
|
|
fbf64585b7 | ||
|
|
6d1c6dfd16 | ||
|
|
e78df4d981 | ||
|
|
a757b4d5dc | ||
|
|
d28036ee91 | ||
|
|
d2ba0d4e7a | ||
|
|
5787436177 | ||
|
|
f5ab24b8d2 | ||
|
|
05c0f32a24 | ||
|
|
7b918f77a9 | ||
|
|
d87929d61c | ||
|
|
a926829c33 | ||
|
|
d58e366c40 | ||
|
|
0fb4f7e1c4 | ||
|
|
6ee606e3e2 | ||
|
|
22d4a7690f | ||
|
|
f3a2f5018a | ||
|
|
d2a7589f7c | ||
|
|
f87b4e04f1 | ||
|
|
b5aa4c1f0c | ||
|
|
0c1eb6d288 | ||
|
|
8a03c5f998 | ||
|
|
60aa50ae45 | ||
|
|
aae6bbbb66 | ||
|
|
5ca903c428 | ||
|
|
e86b07f760 | ||
|
|
d7fea5dc78 | ||
|
|
c1eff5aebb | ||
|
|
f2dc490d6f | ||
|
|
b296e1b340 | ||
|
|
8adb060edb | ||
|
|
c3b984fea7 | ||
|
|
afbb2c338b | ||
|
|
6632241ab5 | ||
|
|
be50df81db | ||
|
|
9763b6e2cf | ||
|
|
812b848daf | ||
|
|
4907a7389f | ||
|
|
17dff36b65 | ||
|
|
904921d8c4 | ||
|
|
ac4c075d32 | ||
|
|
ddde64ece9 | ||
|
|
91c097e88d | ||
|
|
894658a3f5 | ||
|
|
a4454ea5f9 | ||
|
|
8ea8fa3a8a | ||
|
|
7480603295 | ||
|
|
079b749d5d | ||
|
|
4815600e85 | ||
|
|
1c63e2d295 | ||
|
|
cf13eca58c | ||
|
|
3cf4607870 | ||
|
|
23c3ba6ad7 | ||
|
|
17fc3c2317 | ||
|
|
af234cbe54 | ||
|
|
c8517c0ec9 | ||
|
|
20b226454b | ||
|
|
98eccf223a | ||
|
|
0fc2ab4d41 | ||
|
|
641b6efe7f | ||
|
|
4c83435b4b | ||
|
|
9f7319cff4 | ||
|
|
dd9baa1502 | ||
|
|
41b4d0daa1 | ||
|
|
e41b181163 | ||
|
|
288ac115d0 | ||
|
|
6774d46a6f | ||
|
|
607abf89f7 | ||
|
|
27f1e5e2f2 | ||
|
|
a457675ce1 | ||
|
|
82049096e6 | ||
|
|
6c965e0223 | ||
|
|
8b4d952929 | ||
|
|
873cc63f94 | ||
|
|
39fc839ff2 | ||
|
|
4edef4c959 | ||
|
|
1d9ced8037 | ||
|
|
4cb77d1429 | ||
|
|
b52d9d1bdd | ||
|
|
5fe7ca5e70 | ||
|
|
62fb440de2 | ||
|
|
96fbd7c7ba | ||
|
|
c9bec8e636 | ||
|
|
769e03e7f2 | ||
|
|
ab83f2d5e2 | ||
|
|
b60d0cdb17 | ||
|
|
677503dbf1 | ||
|
|
25efa29470 | ||
|
|
21a90f8f8f | ||
|
|
64e8d6ae99 | ||
|
|
16a204335e | ||
|
|
0a53f762fe | ||
|
|
6ba4778c1b | ||
|
|
0404c2266c | ||
|
|
e5e914282f | ||
|
|
9867d4bdc3 | ||
|
|
e4cb7112cf | ||
|
|
2d202e90b7 | ||
|
|
016391e442 | ||
|
|
1eff48a429 | ||
|
|
ce33af6bb5 | ||
|
|
fb9d4303f1 | ||
|
|
4e631c9e8f | ||
|
|
766d67d80d | ||
|
|
e2c2a37221 | ||
|
|
2b23020695 | ||
|
|
8d43c6b1a8 | ||
|
|
7362dd1a7c | ||
|
|
316caf7e8c | ||
|
|
87dc6631ee | ||
|
|
62246d7d43 | ||
|
|
a14be3a42c | ||
|
|
7fdf00d5e9 | ||
|
|
99e02f30fb | ||
|
|
716a5b9b5a | ||
|
|
87f880ca52 | ||
|
|
8ec7b84a78 | ||
|
|
05cf5bc8db | ||
|
|
ac25e21a0c | ||
|
|
cc1e0daaa4 | ||
|
|
f4120a9c8c | ||
|
|
e3b80a5e09 | ||
|
|
ef7cb26b01 | ||
|
|
408a5c168f | ||
|
|
0ad6ac95b2 | ||
|
|
bda4747e9c | ||
|
|
bd8f882c94 | ||
|
|
32b5b5b1c4 | ||
|
|
c1e543c9fe | ||
|
|
3908fa5c57 | ||
|
|
1b347fc185 | ||
|
|
282a5e0b01 | ||
|
|
e9d23cc1ea | ||
|
|
34173fd60f | ||
|
|
d0d3c8ef57 | ||
|
|
11912008dd | ||
|
|
c122007e17 | ||
|
|
69dfa1a175 | ||
|
|
bfea443e55 | ||
|
|
680798c28f | ||
|
|
9f0cc45c45 | ||
|
|
0ac97f467f | ||
|
|
647746ea72 | ||
|
|
7bea30b2e6 | ||
|
|
12bc852c89 | ||
|
|
0d42e84045 | ||
|
|
897b85b607 | ||
|
|
5c55cf0efb | ||
|
|
eccd6463f6 | ||
|
|
4a0897c734 | ||
|
|
c86a16df7f | ||
|
|
2ae0e9d902 | ||
|
|
bba18cd56b | ||
|
|
2f20781e16 | ||
|
|
3bee212876 | ||
|
|
6c8893a550 |
@@ -1,6 +1,7 @@
|
||||
.*
|
||||
*.custom.*
|
||||
*.d.ts
|
||||
CONTRIBUTING.md
|
||||
doc/*.php
|
||||
node_modules/
|
||||
perf/*.html
|
||||
@@ -12,8 +13,8 @@ test/*.sh
|
||||
vendor/*.gz
|
||||
vendor/backbone/
|
||||
vendor/benchmark.js/*.jar
|
||||
vendor/closure-compiler
|
||||
vendor/docdown
|
||||
vendor/closure-compiler/
|
||||
vendor/docdown/
|
||||
vendor/firebug-lite/
|
||||
vendor/json3/
|
||||
vendor/jquery/
|
||||
@@ -21,5 +22,5 @@ vendor/qunit/qunit/*.css
|
||||
vendor/qunit/qunit/*-1.8.0.js
|
||||
vendor/requirejs/
|
||||
vendor/underscore/*-min.js
|
||||
vendor/uglifyjs
|
||||
vendor/uglifyjs/
|
||||
vendor/underscore/test/
|
||||
|
||||
19
.travis.yml
19
.travis.yml
@@ -1,7 +1,20 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
- 0.9
|
||||
env:
|
||||
- TEST_COMMAND="phantomjs ./test/test.js ../dist/lodash.compat.js"
|
||||
- TEST_COMMAND="phantomjs ./test/test.js ../dist/lodash.compat.min.js"
|
||||
- TEST_COMMAND="node ./test/test.js ../dist/lodash.js"
|
||||
- TEST_COMMAND="node ./test/test.js ../dist/lodash.min.js"
|
||||
- TEST_COMMAND="node ./test/test-build.js --time-limit 49m40s"
|
||||
git:
|
||||
depth: 1
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
before_script:
|
||||
- "curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/bestiejs/lodash/git/blobs/a2787b470c577cee2404d186c562dd9835f779f5 | tar xvz -C vendor"
|
||||
- "curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/bestiejs/lodash/git/blobs/7ecae09d413eb48dd5785fe877f24e60ac3bbcef | tar xvz -C vendor"
|
||||
- "tar -xzvf vendor/closure-compiler.tar.gz -C vendor"
|
||||
- "tar -xzvf vendor/uglifyjs.tar.gz -C vendor"
|
||||
script:
|
||||
$TEST_COMMAND
|
||||
|
||||
@@ -7,12 +7,12 @@ Please make sure to [search the issue tracker](https://github.com/bestiejs/lodas
|
||||
|
||||
Include updated unit tests in the `test` directory as part of your pull request.
|
||||
You can run the tests from the command line via `npm test`, or open `test/index.html` in a web browser.
|
||||
The `test/run-test.sh` script attempts to run the tests in [Rhino](http://www.mozilla.org/rhino/), [RingoJS](http://ringojs.org/), [Narwhal](https://github.com/280north/narwhal), and [Node](http://nodejs.org/), before running them in your default browser.
|
||||
The `test/run-test.sh` script attempts to run the tests in [Rhino](https://developer.mozilla.org/en-US/docs/Rhino), [Narwhal](https://github.com/280north/narwhal), [RingoJS](http://ringojs.org/), [PhantomJS](http://phantomjs.org/), and [Node](http://nodejs.org/), before running them in your default browser.
|
||||
The [Backbone](http://backbonejs.org/) and [Underscore](http://http://underscorejs.org/) test suites are included as well.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Lo-Dash is preparing to join [Dojo Foundation](http://dojofoundation.org/).
|
||||
Lo-Dash 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 Russell’s excellent post, ["Why Do I Need to Sign This?"](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Based on Underscore.js 1.4.3, copyright 2009-2012 Jeremy Ashkenas,
|
||||
DocumentCloud Inc. <http://documentcloud.github.com/underscore>
|
||||
Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
|
||||
Based on Underscore.js 1.4.3, copyright 2009-2013 Jeremy Ashkenas,
|
||||
DocumentCloud Inc. <http://underscorejs.org/>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
269
README.md
269
README.md
@@ -1,169 +1,30 @@
|
||||
# Lo-Dash <sup>v1.0.0-rc.3</sup>
|
||||
[](http://travis-ci.org/bestiejs/lodash)
|
||||
# Lo-Dash v1.0.2
|
||||
|
||||
An alternative to Underscore.js, delivering [consistency](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), [customization](https://github.com/bestiejs/lodash#custom-builds), [performance](http://lodash.com/benchmarks), and [extra features](https://github.com/bestiejs/lodash#features).
|
||||
A utility library delivering consistency, [customization](https://lodash.com/custom-builds), [performance](https://lodash.com/benchmarks), & [extras](https://lodash.com/#features).
|
||||
|
||||
## Download
|
||||
|
||||
* Lo-Dash builds:<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.3/lodash.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.3/lodash.min.js)
|
||||
* Lo-Dash builds (for modern environments):<br>
|
||||
[Development](https://raw.github.com/lodash/lodash/1.0.2/dist/lodash.js) and
|
||||
[Production](https://raw.github.com/lodash/lodash/1.0.2/dist/lodash.min.js)
|
||||
|
||||
* Lo-Dash compatibility builds (for legacy and modern environments):<br>
|
||||
[Development](https://raw.github.com/lodash/lodash/1.0.2/dist/lodash.compat.js) and
|
||||
[Production](https://raw.github.com/lodash/lodash/1.0.2/dist/lodash.compat.min.js)
|
||||
|
||||
* Underscore compatibility builds:<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.3/lodash.underscore.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.3/lodash.underscore.min.js)
|
||||
[Development](https://raw.github.com/lodash/lodash/1.0.2/dist/lodash.underscore.js) and
|
||||
[Production](https://raw.github.com/lodash/lodash/1.0.2/dist/lodash.underscore.min.js)
|
||||
|
||||
* CDN copies of ≤ v1.0.0-rc.3’s builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/):<br>
|
||||
[Lo-Dash dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.3/lodash.js),
|
||||
[Lo-Dash prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.3/lodash.min.js),
|
||||
[Underscore compat-dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.3/lodash.underscore.js), and
|
||||
[Underscore compat-prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.3/lodash.underscore.min.js)
|
||||
|
||||
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
||||
* For optimal file size, [create a custom build](https://lodash.com/custom-builds) with only the features you need
|
||||
|
||||
## Dive in
|
||||
|
||||
We’ve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
|
||||
We’ve got [API docs](https://lodash.com/docs), [benchmarks](https://lodash.com/benchmarks), and [unit tests](https://lodash.com/tests).
|
||||
|
||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/lodash/wiki/Roadmap).
|
||||
For a list of upcoming features, check out our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap).
|
||||
|
||||
## Screencasts
|
||||
|
||||
For more information check out these screencasts over Lo-Dash:
|
||||
|
||||
* [Introducing Lo-Dash](https://vimeo.com/44154599)
|
||||
* [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
|
||||
* [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600)
|
||||
* [Unit testing in Lo-Dash](https://vimeo.com/45865290)
|
||||
* [Lo-Dash’s approach to native method use](https://vimeo.com/48576012)
|
||||
* [CascadiaJS: Lo-Dash for a better utility belt](http://www.youtube.com/watch?v=dpPy4f_SeEk)
|
||||
|
||||
## Features
|
||||
|
||||
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
||||
* [_(…)](http://lodash.com/docs#_) supports intuitive chaining
|
||||
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
|
||||
* [_.cloneDeep](http://lodash.com/docs#cloneDeep) for *“deep”* cloning arrays and objects
|
||||
* [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument
|
||||
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
|
||||
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
||||
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties
|
||||
* [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
|
||||
* [_.merge](http://lodash.com/docs#merge) for a *“deep”* [_.extend](http://lodash.com/docs#extend)
|
||||
* [_.partial](http://lodash.com/docs#partial) for partial application without `this` binding
|
||||
* [_.pick](http://lodash.com/docs#pick) and [_.omit](http://lodash.com/docs#omit) accepts `callback` and `thisArg` arguments
|
||||
* [_.template](http://lodash.com/docs#template) supports [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6) and utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
||||
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
|
||||
[and more…](http://lodash.com/docs "_.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
|
||||
|
||||
## Support
|
||||
|
||||
Lo-Dash has been tested in at least Chrome 5~23, Firefox 1~17, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.16, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
|
||||
## Custom builds
|
||||
|
||||
Custom builds make it easy to create lightweight versions of Lo-Dash containing only the methods you need.
|
||||
To top it off, we handle all method dependency and alias mapping for you.
|
||||
|
||||
* Backbone builds, with only methods required by Backbone, may be created using the `backbone` modifier argument.
|
||||
```bash
|
||||
lodash backbone
|
||||
```
|
||||
|
||||
* CSP builds, supporting default [Content Security Policy](http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html) restrictions, may be created using the `csp` modifier argument.
|
||||
The `csp` modifier is an alais of the `mobile` modifier. Chrome extensions will require [sandboxing](http://developer.chrome.com/trunk/extensions/sandboxingEval.html) or the use of either the `csp`, `mobile`, or `underscore` build.
|
||||
```bash
|
||||
lodash csp
|
||||
```
|
||||
|
||||
* Legacy builds, tailored for older browsers without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
|
||||
```bash
|
||||
lodash legacy
|
||||
```
|
||||
|
||||
* Mobile builds, with IE < 9 bug fixes and method compilation removed, may be created using the `mobile` modifier argument.
|
||||
```bash
|
||||
lodash mobile
|
||||
```
|
||||
|
||||
* Strict builds, with `_.bindAll`, `_.defaults`, and `_.extend` in [strict mode](http://es5.github.com/#C), may be created using the `strict` modifier argument.
|
||||
```bash
|
||||
lodash strict
|
||||
```
|
||||
|
||||
* Underscore builds, tailored for projects already using Underscore, may be created using the `underscore` modifier argument.
|
||||
```bash
|
||||
lodash underscore
|
||||
```
|
||||
|
||||
Custom builds may be created using the following commands:
|
||||
|
||||
* Use the `category` argument to pass comma separated categories of methods to include in the build.<br>
|
||||
Valid categories (case-insensitive) are *“arrays”*, *“chaining”*, *“collections”*, *“functions”*, *“objects”*, and *“utilities”*.
|
||||
```bash
|
||||
lodash category=collections,functions
|
||||
lodash category="collections, functions"
|
||||
```
|
||||
|
||||
* Use the `exports` argument to pass comma separated names of ways to export the `LoDash` function.<br>
|
||||
Valid exports are *“amd”*, *“commonjs”*, *“global”*, *“node”*, and *“none”*.
|
||||
```bash
|
||||
lodash exports=amd,commonjs,node
|
||||
lodash exports="amd, commonjs, node"
|
||||
```
|
||||
|
||||
* Use the `iife` argument to specify code to replace the immediately-invoked function expression that wraps Lo-Dash.
|
||||
```bash
|
||||
lodash iife="!function(window,undefined){%output%}(this)"
|
||||
```
|
||||
|
||||
* Use the `include` argument to pass comma separated method/category names to include in the build.
|
||||
```bash
|
||||
lodash include=each,filter,map
|
||||
lodash include="each, filter, map"
|
||||
```
|
||||
|
||||
* Use the `minus` argument to pass comma separated method/category names to remove from those included in the build.
|
||||
```bash
|
||||
lodash underscore minus=result,shuffle
|
||||
lodash underscore minus="result, shuffle"
|
||||
```
|
||||
|
||||
* Use the `plus` argument to pass comma separated method/category names to add to those included in the build.
|
||||
```bash
|
||||
lodash backbone plus=random,template
|
||||
lodash backbone plus="random, template"
|
||||
```
|
||||
|
||||
* Use the `template` argument to pass the file path pattern used to match template files to precompile.
|
||||
```bash
|
||||
lodash template="./*.jst"
|
||||
```
|
||||
|
||||
* Use the `settings` argument to pass the template settings used when precompiling templates.
|
||||
```bash
|
||||
lodash settings="{interpolate:/\\{\\{([\\s\\S]+?)\\}\\}/g}"
|
||||
```
|
||||
|
||||
* Use the `moduleId` argument to specify the AMD module ID of Lo-Dash, which defaults to “lodash”, used by precompiled templates.
|
||||
```bash
|
||||
lodash moduleId="underscore"
|
||||
```
|
||||
|
||||
All arguments, except `legacy` with `csp` or `mobile`, may be combined.<br>
|
||||
Unless specified by `-o` or `--output`, all files created are saved to the current working directory.
|
||||
|
||||
The following options are also supported:
|
||||
|
||||
* `-c`, `--stdout` Write output to standard output
|
||||
* `-d`, `--debug` Write only the debug output
|
||||
* `-h`, `--help` Display help information
|
||||
* `-m`, `--minify` Write only the minified output
|
||||
* `-o`, `--output` Write output to a given path/filename
|
||||
* `-s`, `--silent` Skip status updates normally logged to the console
|
||||
* `-V`, `--version` Output current version of Lo-Dash
|
||||
|
||||
The `lodash` command-line utility is available when Lo-Dash is installed as a global package (i.e. `npm install -g lodash`).
|
||||
The full changelog is available [here](https://github.com/lodash/lodash/wiki/Changelog).
|
||||
|
||||
## Installation and usage
|
||||
|
||||
@@ -224,76 +85,44 @@ require({
|
||||
});
|
||||
```
|
||||
|
||||
## Resolved Underscore.js issues
|
||||
## Resources
|
||||
|
||||
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L605-L611)]
|
||||
* Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L618-L642)]
|
||||
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L140-L146)]
|
||||
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L807-L812)]
|
||||
* `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/v8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L888-L900)]
|
||||
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L982-L984)]
|
||||
* `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.3/test/test.js#L1383-L1386)]
|
||||
For more information check out these articles, screencasts, and other videos over Lo-Dash:
|
||||
|
||||
## Release Notes
|
||||
* Posts
|
||||
- [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)
|
||||
|
||||
### <sup>v1.0.0-rc.3</sup>
|
||||
* Videos
|
||||
- [Introducing Lo-Dash](https://vimeo.com/44154599)
|
||||
- [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
|
||||
- [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600)
|
||||
- [Unit testing in Lo-Dash](https://vimeo.com/45865290)
|
||||
- [Lo-Dash’s approach to native method use](https://vimeo.com/48576012)
|
||||
- [CascadiaJS: Lo-Dash for a better utility belt](http://www.youtube.com/watch?v=dpPy4f_SeEk)
|
||||
|
||||
#### Compatibility Warnings
|
||||
## Features
|
||||
|
||||
* Made `_#join`, `_#pop`, and `_#shift` wrapper methods return unwrapped values
|
||||
* Made *“Functions”* methods wrapper counterparts return wrapped values
|
||||
* Removed `_.chain` and `_#chain` methods
|
||||
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
||||
* [_(…)](https://lodash.com/docs#_) supports intuitive chaining
|
||||
* [_.at](https://lodash.com/docs#at) for cherry-picking collection values
|
||||
* [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
|
||||
* [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays and objects
|
||||
* [_.contains](https://lodash.com/docs#contains) accepts a `fromIndex` argument
|
||||
* [_.forEach](https://lodash.com/docs#forEach) is chainable and supports exiting iteration early
|
||||
* [_.forIn](https://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
||||
* [_.forOwn](https://lodash.com/docs#forOwn) for iterating over an object’s own properties
|
||||
* [_.isPlainObject](https://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
|
||||
* [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend)
|
||||
* [_.partial](https://lodash.com/docs#partial) and [_.partialRight](https://lodash.com/docs#partialRight) for partial application without `this` binding
|
||||
* [_.template](https://lodash.com/docs#template) supports [*“imports”* options](https://lodash.com/docs#templateSettings_imports), [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6), and [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
|
||||
* [_.where](https://lodash.com/docs#where) supports deep object comparisons
|
||||
* [_.clone](https://lodash.com/docs#clone), [_.omit](https://lodash.com/docs#omit), [_.pick](https://lodash.com/docs#pick),
|
||||
[and more…](https://lodash.com/docs "_.assign, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept `callback` and `thisArg` arguments
|
||||
* [_.contains](https://lodash.com/docs#contains), [_.size](https://lodash.com/docs#size), [_.toArray](https://lodash.com/docs#toArray),
|
||||
[and more…](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
|
||||
* [_.filter](https://lodash.com/docs#filter), [_.find](https://lodash.com/docs#find), [_.map](https://lodash.com/docs#map),
|
||||
[and more…](https://lodash.com/docs "_.countBy, _.every, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* and *“_.where”* `callback` shorthands
|
||||
|
||||
#### Changes
|
||||
## Support
|
||||
|
||||
* Added [_.cloneDeep](http://lodash.com/docs#cloneDeep) alias of `_.clone(…, true)`
|
||||
* Added `_.once` to the `backbone` build method dependencies
|
||||
* Ensured `backbone` builds implement Underscore’s chaining behavior
|
||||
* Ensured the `settings=…` build option doesn’t clobber the default `moduleId`
|
||||
* Ensured Lo-Dash’s `npm` package installation avoids erroring when no other modules have been globally installed
|
||||
* Made compiled templates loaded via AMD use the Lo-Dash module for their `_` references
|
||||
* Removed the *“Collections”* method `_.forEach` dependency from *“Arrays”* method `_.intersection`
|
||||
* Optimized `_.isArray` and `_.isFunction` fallbacks as well as<br>
|
||||
`_.intersection`, `_.isDate`, `_.isRegExp`, `_.reduce`, `_.reduceRight`, `_.union`, and `_.uniq`
|
||||
|
||||
### <sup>v1.0.0-rc.2</sup>
|
||||
|
||||
* Specified more method chaining behaviors
|
||||
* Updated `underscore` build compatibility to v1.4.3
|
||||
|
||||
### <sup>v1.0.0-rc.1</sup>
|
||||
|
||||
#### Compatibility Warnings
|
||||
|
||||
* Made `_(…)` intuitively chain without needing to call `_#chain`
|
||||
* Made `_.isEqual` equate `arguments` objects to similar `Object` objects
|
||||
* Made `_.clone` copy the enumerable properties of `arguments` objects and objects<br>
|
||||
created by constructors other than `Object` are cloned to plain `Object` objects
|
||||
|
||||
#### Changes
|
||||
|
||||
* Ensure Lo-Dash runs in the JS engine embedded in Adobe products
|
||||
* Ensured `_.reduce` and `_.reduceRight` pass the correct number of `callback` arguments
|
||||
* Ensured `_.throttle` nulls the `timeoutId`
|
||||
* Made deep `_.clone` more closely follow the structured clone algorithm and copy array properties assigned by `RegExp#exec`
|
||||
* Optimized compiled templates in Firefox
|
||||
* Optimized `_.forEach`, `_.forOwn`, `_.isNumber`, and `_.isString`
|
||||
* Simplified `iteratorTemplate`
|
||||
|
||||
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
|
||||
|
||||
## BestieJS
|
||||
|
||||
Lo-Dash is part of the BestieJS *“Best in Class”* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
|
||||
|
||||
## Author
|
||||
|
||||
* [John-David Dalton](http://allyoucanleet.com/)
|
||||
[](https://twitter.com/jdalton "Follow @jdalton on Twitter")
|
||||
|
||||
## Contributors
|
||||
|
||||
* [Kit Cambridge](http://kitcambridge.github.com/)
|
||||
[](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter")
|
||||
* [Mathias Bynens](http://mathiasbynens.be/)
|
||||
[](https://twitter.com/mathias "Follow @mathias on Twitter")
|
||||
Lo-Dash has been tested in at least Chrome 5~24, Firefox 1~18, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.20, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5.
|
||||
|
||||
517
build/minify.js
517
build/minify.js
@@ -2,26 +2,57 @@
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** The Node filesystem, path, `zlib`, and child process modules */
|
||||
/** Load Node modules */
|
||||
var fs = require('fs'),
|
||||
gzip = require('zlib').gzip,
|
||||
https = require('https'),
|
||||
path = require('path'),
|
||||
spawn = require('child_process').spawn;
|
||||
spawn = require('child_process').spawn,
|
||||
zlib = require('zlib'),
|
||||
tar = require('../vendor/tar/tar.js'),
|
||||
_ = require('../lodash.js');
|
||||
|
||||
/** Load other modules */
|
||||
var preprocess = require('./pre-compile.js'),
|
||||
postprocess = require('./post-compile.js');
|
||||
|
||||
/** The Git object ID of `closure-compiler.tar.gz` */
|
||||
var closureId = '23cf67d0f0b979d97631fc108a2a43bb82225994';
|
||||
|
||||
/** The Git object ID of `uglifyjs.tar.gz` */
|
||||
var uglifyId = 'a934fb18f8fa2768c6a68de44b6e035fe96a268b';
|
||||
|
||||
/** The path of the directory that is the base of the repository */
|
||||
var basePath = fs.realpathSync(path.join(__dirname, '..'));
|
||||
|
||||
/** The path of the directory where the Closure Compiler is located */
|
||||
var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar');
|
||||
/** The path of the `vendor` directory */
|
||||
var vendorPath = path.join(basePath, 'vendor');
|
||||
|
||||
/** Load other modules */
|
||||
var preprocess = require('./pre-compile.js'),
|
||||
postprocess = require('./post-compile.js'),
|
||||
uglifyJS = require('../vendor/uglifyjs/uglify-js.js');
|
||||
/** The path to the Closure Compiler `.jar` */
|
||||
var closurePath = path.join(vendorPath, 'closure-compiler', 'compiler.jar');
|
||||
|
||||
/** The path to the UglifyJS module */
|
||||
var uglifyPath = path.join(vendorPath, 'uglifyjs', 'tools', 'node.js');
|
||||
|
||||
/** The Closure Compiler command-line options */
|
||||
var closureOptions = ['--warning_level=QUIET'];
|
||||
|
||||
/** The media type for raw blob data */
|
||||
var mediaType = 'application/vnd.github.v3.raw';
|
||||
|
||||
/** Used to reference parts of the blob href */
|
||||
var location = (function() {
|
||||
var host = 'api.github.com',
|
||||
origin = 'https://api.github.com',
|
||||
pathname = '/repos/bestiejs/lodash/git/blobs';
|
||||
|
||||
return {
|
||||
'host': host,
|
||||
'href': origin + pathname,
|
||||
'origin': origin,
|
||||
'pathname': pathname
|
||||
};
|
||||
}());
|
||||
|
||||
/** The Closure Compiler optimization modes */
|
||||
var optimizationModes = {
|
||||
'simple': 'SIMPLE_OPTIMIZATIONS',
|
||||
@@ -50,6 +81,12 @@
|
||||
* onComplete - The function called once minification has finished.
|
||||
*/
|
||||
function minify(source, options) {
|
||||
// used to specify the source map URL
|
||||
var sourceMapURL;
|
||||
|
||||
// used to specify the default minifer modes
|
||||
var modes = ['simple', 'advanced', 'hybrid'];
|
||||
|
||||
source || (source = '');
|
||||
options || (options = {});
|
||||
|
||||
@@ -58,11 +95,46 @@
|
||||
// convert commands to an options object
|
||||
options = source;
|
||||
|
||||
// used to report invalid command-line arguments
|
||||
var invalidArgs = _.reject(options.slice(options[0] == 'node' ? 2 : 0), function(value, index, options) {
|
||||
if (/^(?:-o|--output)$/.test(options[index - 1]) ||
|
||||
/^modes=.*$/.test(value)) {
|
||||
return true;
|
||||
}
|
||||
var result = [
|
||||
'-o', '--output',
|
||||
'-p', '--source-map',
|
||||
'-s', '--silent',
|
||||
'-t', '--template'
|
||||
].indexOf(value) > -1;
|
||||
|
||||
if (!result && /^(?:-p|--source-map)$/.test(options[index - 1])) {
|
||||
result = true;
|
||||
sourceMapURL = value;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
// report invalid arguments
|
||||
if (invalidArgs.length) {
|
||||
console.log(
|
||||
'\n' +
|
||||
'Invalid argument' + (invalidArgs.length > 1 ? 's' : '') +
|
||||
' passed: ' + invalidArgs.join(', ')
|
||||
);
|
||||
return;
|
||||
}
|
||||
var filePath = options[options.length - 1],
|
||||
isMapped = options.indexOf('-p') > -1 || options.indexOf('--source-map') > -1,
|
||||
isSilent = options.indexOf('-s') > -1 || options.indexOf('--silent') > -1,
|
||||
isTemplate = options.indexOf('-t') > -1 || options.indexOf('--template') > -1,
|
||||
outputPath = path.join(path.dirname(filePath), path.basename(filePath, '.js') + '.min.js');
|
||||
|
||||
modes = options.reduce(function(result, value) {
|
||||
var match = value.match(/modes=(.*)$/);
|
||||
return match ? match[1].split(/, */) : result;
|
||||
}, modes);
|
||||
|
||||
outputPath = options.reduce(function(result, value, index) {
|
||||
if (/-o|--output/.test(value)) {
|
||||
result = options[index + 1];
|
||||
@@ -72,14 +144,55 @@
|
||||
}, outputPath);
|
||||
|
||||
options = {
|
||||
'filePath': filePath,
|
||||
'isMapped': isMapped,
|
||||
'isSilent': isSilent,
|
||||
'isTemplate': isTemplate,
|
||||
'outputPath': outputPath
|
||||
'modes': modes,
|
||||
'outputPath': outputPath,
|
||||
'sourceMapURL': sourceMapURL
|
||||
};
|
||||
|
||||
source = fs.readFileSync(filePath, 'utf8');
|
||||
}
|
||||
new Minify(source, options);
|
||||
|
||||
modes = options.modes || modes;
|
||||
if (options.isMapped) {
|
||||
modes = modes.filter(function(mode) {
|
||||
return mode != 'hybrid';
|
||||
});
|
||||
}
|
||||
if (options.isTemplate) {
|
||||
modes = modes.filter(function(mode) {
|
||||
return mode != 'advanced';
|
||||
});
|
||||
}
|
||||
options.modes = modes;
|
||||
|
||||
// fetch the Closure Compiler
|
||||
getDependency({
|
||||
'id': 'closure-compiler',
|
||||
'hashId': closureId,
|
||||
'path': vendorPath,
|
||||
'title': 'the Closure Compiler',
|
||||
'onComplete': function(exception) {
|
||||
var error = exception;
|
||||
|
||||
// fetch UglifyJS
|
||||
getDependency({
|
||||
'id': 'uglifyjs',
|
||||
'hashId': uglifyId,
|
||||
'title': 'UglifyJS',
|
||||
'path': vendorPath,
|
||||
'onComplete': function(exception) {
|
||||
error || (error = exception);
|
||||
if (!error) {
|
||||
new Minify(source, options);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,19 +217,114 @@
|
||||
this.hybrid = { 'simple': {}, 'advanced': {} };
|
||||
this.uglified = {};
|
||||
|
||||
this.filePath = options.filePath;
|
||||
this.isMapped = !!options.isMapped;
|
||||
this.isSilent = !!options.isSilent;
|
||||
this.isTemplate = !!options.isTemplate;
|
||||
this.outputPath = options.outputPath;
|
||||
this.sourceMapURL = options.sourceMapURL;
|
||||
|
||||
source = preprocess(source, options);
|
||||
this.source = source;
|
||||
var modes = this.modes = options.modes;
|
||||
source = this.source = preprocess(source, options);
|
||||
|
||||
this.onComplete = options.onComplete || function(source) {
|
||||
fs.writeFileSync(this.outputPath, source, 'utf8');
|
||||
this.onComplete = options.onComplete || function(data) {
|
||||
var outputPath = this.outputPath,
|
||||
sourceMap = data.sourceMap;
|
||||
|
||||
fs.writeFileSync(outputPath, data.source, 'utf8');
|
||||
if (sourceMap) {
|
||||
fs.writeFileSync(getMapPath(outputPath), sourceMap, 'utf8');
|
||||
}
|
||||
};
|
||||
|
||||
// begin the minification process
|
||||
closureCompile.call(this, source, 'simple', onClosureSimpleCompile.bind(this));
|
||||
if (modes.indexOf('simple') > -1) {
|
||||
closureCompile.call(this, source, 'simple', onClosureSimpleCompile.bind(this));
|
||||
} else if (modes.indexOf('advanced') > -1) {
|
||||
onClosureSimpleGzip.call(this);
|
||||
} else {
|
||||
onClosureAdvancedGzip.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Fetches a required `.tar.gz` dependency with the given Git object ID from
|
||||
* the Lo-Dash repo on GitHub. The object ID may be obtained by running
|
||||
* `git hash-object path/to/dependency.tar.gz`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} options The options object.
|
||||
* id - The Git object ID of the `.tar.gz` file.
|
||||
* onComplete - The function called once the extraction has finished.
|
||||
* path - The path of the extraction directory.
|
||||
* title - The dependency's title used in status updates logged to the console.
|
||||
*/
|
||||
function getDependency(options) {
|
||||
options || (options = {});
|
||||
|
||||
var ran,
|
||||
destPath = options.path,
|
||||
hashId = options.hashId,
|
||||
id = options.id,
|
||||
onComplete = options.onComplete,
|
||||
title = options.title;
|
||||
|
||||
// exit early if dependency exists
|
||||
if (fs.existsSync(path.join(destPath, id))) {
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
var callback = function(exception) {
|
||||
if (ran) {
|
||||
return;
|
||||
}
|
||||
if (exception) {
|
||||
console.error([
|
||||
'There was a problem installing ' + title + '.',
|
||||
'Try running the command as root, via `sudo`, or manually install by running:',
|
||||
'',
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + hashId + " | tar xvz -C '" + destPath + "'",
|
||||
''
|
||||
].join('\n'));
|
||||
}
|
||||
ran = true;
|
||||
process.removeListener('uncaughtException', callback);
|
||||
onComplete(exception);
|
||||
};
|
||||
|
||||
console.log('Downloading ' + title + '...');
|
||||
process.on('uncaughtException', callback);
|
||||
|
||||
https.get({
|
||||
'host': location.host,
|
||||
'path': location.pathname + '/' + hashId,
|
||||
'headers': {
|
||||
// By default, all GitHub blob API endpoints return a JSON document
|
||||
// containing Base64-encoded blob data. Overriding the `Accept` header
|
||||
// with the GitHub raw media type returns the blob data directly.
|
||||
// See http://developer.github.com/v3/media/.
|
||||
'Accept': mediaType
|
||||
}
|
||||
}, function(response) {
|
||||
var decompressor = zlib.createUnzip(),
|
||||
parser = new tar.Extract({ 'path': destPath });
|
||||
|
||||
parser.on('end', callback);
|
||||
response.pipe(decompressor).pipe(parser);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the source map path from the given output path.
|
||||
*
|
||||
* @private
|
||||
* @param {String} outputPath The output path.
|
||||
* @returns {String} Returns the source map path.
|
||||
*/
|
||||
function getMapPath(outputPath) {
|
||||
return path.join(path.dirname(outputPath), path.basename(outputPath, '.js') + '.map');
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -131,36 +339,82 @@
|
||||
* @param {Function} callback The function called once the process has completed.
|
||||
*/
|
||||
function closureCompile(source, mode, callback) {
|
||||
// use simple optimizations when minifying template files
|
||||
var options = closureOptions.slice();
|
||||
options.push('--compilation_level=' + optimizationModes[this.isTemplate ? 'simple' : mode]);
|
||||
var filePath = this.filePath,
|
||||
isAdvanced = mode == 'advanced',
|
||||
isMapped = this.isMapped,
|
||||
options = closureOptions.slice(),
|
||||
outputPath = this.outputPath,
|
||||
mapPath = getMapPath(outputPath),
|
||||
sourceMapURL = this.sourceMapURL || path.basename(mapPath);
|
||||
|
||||
// the standard error stream, standard output stream, and the Closure Compiler process
|
||||
var error = '',
|
||||
output = '',
|
||||
compiler = spawn('java', ['-jar', closurePath].concat(options));
|
||||
|
||||
if (!this.isSilent) {
|
||||
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using the Closure Compiler (' + mode + ')...');
|
||||
// remove copyright header to make other modifications easier
|
||||
var license = (/^(?:\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*/.exec(source) || [''])[0];
|
||||
if (license) {
|
||||
source = source.replace(license, '');
|
||||
}
|
||||
compiler.stdout.on('data', function(data) {
|
||||
// append the data to the output stream
|
||||
output += data;
|
||||
|
||||
var hasIIFE = /^;?\(function[^{]+{\s*/.test(source),
|
||||
isStrict = hasIIFE && /^;?\(function[^{]+{\s*["']use strict["']/.test(source);
|
||||
|
||||
// to avoid stripping the IIFE, convert it to a function call
|
||||
if (hasIIFE && isAdvanced) {
|
||||
source = source
|
||||
.replace(/\(function/, '__iife__$&')
|
||||
.replace(/\(this\)\)([\s;]*(\n\/\/.+)?)$/, ', this)$1');
|
||||
}
|
||||
|
||||
options.push('--compilation_level=' + optimizationModes[mode]);
|
||||
if (isMapped) {
|
||||
options.push('--create_source_map=' + mapPath, '--source_map_format=V3');
|
||||
}
|
||||
|
||||
var compiler = spawn('java', ['-jar', closurePath].concat(options));
|
||||
if (!this.isSilent) {
|
||||
console.log('Compressing ' + path.basename(outputPath, '.js') + ' using the Closure Compiler (' + mode + ')...');
|
||||
}
|
||||
|
||||
var error = '';
|
||||
compiler.stderr.on('data', function(data) {
|
||||
error += data;
|
||||
});
|
||||
|
||||
compiler.stderr.on('data', function(data) {
|
||||
// append the error message to the error stream
|
||||
error += data;
|
||||
var output = '';
|
||||
compiler.stdout.on('data', function(data) {
|
||||
output += data;
|
||||
});
|
||||
|
||||
compiler.on('exit', function(status) {
|
||||
// `status` contains the process exit code
|
||||
var exception = null;
|
||||
if (status) {
|
||||
exception = new Error(error);
|
||||
var exception = new Error(error);
|
||||
exception.status = status;
|
||||
}
|
||||
callback(exception, output);
|
||||
// restore IIFE and move exposed vars inside the IIFE
|
||||
if (hasIIFE && isAdvanced) {
|
||||
output = output
|
||||
.replace(/__iife__\(/, '(')
|
||||
.replace(/,\s*this\)([\s;]*(\n\/\/.+)?)$/, '(this))$1')
|
||||
.replace(/^((?:var (?:\w+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^{]+{)/, '$2$1');
|
||||
}
|
||||
// inject "use strict" directive
|
||||
if (isStrict) {
|
||||
output = output.replace(/^[\s\S]*?function[^{]+{/, '$&"use strict";');
|
||||
}
|
||||
// restore copyright header
|
||||
if (license) {
|
||||
output = license + output;
|
||||
}
|
||||
if (isMapped) {
|
||||
var mapOutput = fs.readFileSync(mapPath, 'utf8');
|
||||
fs.unlinkSync(mapPath);
|
||||
output = output.replace(/[\s;]*$/, '\n/*\n//@ sourceMappingURL=' + sourceMapURL) + '\n*/';
|
||||
|
||||
mapOutput = JSON.parse(mapOutput);
|
||||
mapOutput.file = path.basename(outputPath);
|
||||
mapOutput.sources = [path.basename(filePath)];
|
||||
mapOutput = JSON.stringify(mapOutput, null, 2);
|
||||
}
|
||||
callback(exception, output, mapOutput);
|
||||
});
|
||||
|
||||
// proxy the standard input to the Closure Compiler
|
||||
@@ -178,31 +432,46 @@
|
||||
* @param {Function} callback The function called once the process has completed.
|
||||
*/
|
||||
function uglify(source, label, callback) {
|
||||
var exception,
|
||||
result,
|
||||
ugly = uglifyJS.uglify;
|
||||
|
||||
if (!this.isSilent) {
|
||||
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using ' + label + '...');
|
||||
}
|
||||
try {
|
||||
result = ugly.gen_code(
|
||||
// enable unsafe transformations
|
||||
ugly.ast_squeeze_more(
|
||||
ugly.ast_squeeze(
|
||||
// munge variable and function names, excluding the special `define`
|
||||
// function exposed by AMD loaders
|
||||
ugly.ast_mangle(uglifyJS.parser.parse(source), {
|
||||
'except': ['define']
|
||||
}
|
||||
))), {
|
||||
'ascii_only': true
|
||||
var uglifyJS = require(uglifyPath);
|
||||
|
||||
// 1. parse
|
||||
var toplevel = uglifyJS.parse(source);
|
||||
|
||||
// 2. compress
|
||||
// enable unsafe comparisons
|
||||
toplevel.figure_out_scope();
|
||||
toplevel = toplevel.transform(uglifyJS.Compressor({
|
||||
'comparisons': false,
|
||||
'unsafe_comps': true,
|
||||
'warnings': false
|
||||
}));
|
||||
|
||||
// 3. mangle
|
||||
// excluding the `define` function exposed by AMD loaders
|
||||
toplevel.figure_out_scope();
|
||||
toplevel.compute_char_frequency();
|
||||
toplevel.mangle_names({
|
||||
'except': ['define']
|
||||
});
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
|
||||
// 4. output
|
||||
// restrict lines to 500 characters for consistency with the Closure Compiler
|
||||
var stream = uglifyJS.OutputStream({
|
||||
'ascii_only': true,
|
||||
'comments': /@cc_on|@license|@preserve/i,
|
||||
'max_line_len': 500,
|
||||
});
|
||||
|
||||
toplevel.print(stream);
|
||||
}
|
||||
// lines are restricted to 500 characters for consistency with the Closure Compiler
|
||||
callback(exception, result && ugly.split_lines(result, 500));
|
||||
catch(e) {
|
||||
var exception = e;
|
||||
}
|
||||
callback(exception, stream && String(stream));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -213,14 +482,18 @@
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {String} result The resulting minified source.
|
||||
* @param {String} map The source map output.
|
||||
*/
|
||||
function onClosureSimpleCompile(exception, result) {
|
||||
function onClosureSimpleCompile(exception, result, map) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.compiled.simple.source = result;
|
||||
gzip(result, onClosureSimpleGzip.bind(this));
|
||||
|
||||
var simple = this.compiled.simple;
|
||||
simple.source = result;
|
||||
simple.sourceMap = map;
|
||||
zlib.gzip(result, onClosureSimpleGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,13 +507,18 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.compiled.simple.gzip = result;
|
||||
}
|
||||
// compile the source using advanced optimizations
|
||||
if (this.modes.indexOf('advanced') > -1) {
|
||||
closureCompile.call(this, this.source, 'advanced', onClosureAdvancedCompile.bind(this));
|
||||
} else {
|
||||
onClosureAdvancedGzip.call(this);
|
||||
}
|
||||
this.compiled.simple.gzip = result;
|
||||
|
||||
// next, compile the source using advanced optimizations
|
||||
closureCompile.call(this, this.source, 'advanced', onClosureAdvancedCompile.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,14 +527,18 @@
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
* @param {String} result The resulting minified source.
|
||||
* @param {String} map The source map output.
|
||||
*/
|
||||
function onClosureAdvancedCompile(exception, result) {
|
||||
function onClosureAdvancedCompile(exception, result, map) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.compiled.advanced.source = result;
|
||||
gzip(result, onClosureAdvancedGzip.bind(this));
|
||||
|
||||
var advanced = this.compiled.advanced;
|
||||
advanced.source = result;
|
||||
advanced.sourceMap = map;
|
||||
zlib.gzip(result, onClosureAdvancedGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,13 +552,18 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.compiled.advanced.gzip = result;
|
||||
}
|
||||
// minify the source using UglifyJS
|
||||
if (!this.isMapped) {
|
||||
uglify.call(this, this.source, 'UglifyJS', onUglify.bind(this));
|
||||
} else {
|
||||
onComplete.call(this);
|
||||
}
|
||||
this.compiled.advanced.gzip = result;
|
||||
|
||||
// next, minify the source using only UglifyJS
|
||||
uglify.call(this, this.source, 'UglifyJS', onUglify.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +579,7 @@
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.uglified.source = result;
|
||||
gzip(result, onUglifyGzip.bind(this));
|
||||
zlib.gzip(result, onUglifyGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,13 +593,23 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.uglified.gzip = result;
|
||||
}
|
||||
// minify the already Closure Compiler simple optimized source using UglifyJS
|
||||
var modes = this.modes;
|
||||
if (modes.indexOf('hybrid') > -1) {
|
||||
if (modes.indexOf('simple') > -1) {
|
||||
uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this));
|
||||
} else if (modes.indexOf('advanced') > -1) {
|
||||
onSimpleHybridGzip.call(this);
|
||||
}
|
||||
} else {
|
||||
onComplete.call(this);
|
||||
}
|
||||
this.uglified.gzip = result;
|
||||
|
||||
// next, minify the already Closure Compiler simple optimized source using UglifyJS
|
||||
uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,7 +625,7 @@
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.hybrid.simple.source = result;
|
||||
gzip(result, onSimpleHybridGzip.bind(this));
|
||||
zlib.gzip(result, onSimpleHybridGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,13 +639,18 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.hybrid.simple.gzip = result;
|
||||
}
|
||||
// minify the already Closure Compiler advance optimized source using UglifyJS
|
||||
if (this.modes.indexOf('advanced') > -1) {
|
||||
uglify.call(this, this.compiled.advanced.source, 'hybrid (advanced)', onAdvancedHybrid.bind(this));
|
||||
} else {
|
||||
onComplete.call(this);
|
||||
}
|
||||
this.hybrid.simple.gzip = result;
|
||||
|
||||
// next, minify the already Closure Compiler advance optimized source using UglifyJS
|
||||
uglify.call(this, this.compiled.advanced.source, 'hybrid (advanced)', onAdvancedHybrid.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,7 +666,7 @@
|
||||
}
|
||||
result = postprocess(result);
|
||||
this.hybrid.advanced.source = result;
|
||||
gzip(result, onAdvancedHybridGzip.bind(this));
|
||||
zlib.gzip(result, onAdvancedHybridGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,11 +680,12 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.hybrid.advanced.gzip = result;
|
||||
}
|
||||
this.hybrid.advanced.gzip = result;
|
||||
|
||||
// finish by choosing the smallest compressed file
|
||||
onComplete.call(this);
|
||||
}
|
||||
@@ -399,20 +702,32 @@
|
||||
hybridSimple = this.hybrid.simple,
|
||||
hybridAdvanced = this.hybrid.advanced;
|
||||
|
||||
var objects = [
|
||||
compiledSimple,
|
||||
compiledAdvanced,
|
||||
uglified,
|
||||
hybridSimple,
|
||||
hybridAdvanced
|
||||
];
|
||||
|
||||
var gzips = objects
|
||||
.map(function(data) { return data.gzip; })
|
||||
.filter(Boolean);
|
||||
|
||||
// select the smallest gzipped file and use its minified counterpart as the
|
||||
// official minified release (ties go to the Closure Compiler)
|
||||
var min = Math.min(
|
||||
compiledSimple.gzip.length,
|
||||
compiledAdvanced.gzip.length,
|
||||
uglified.gzip.length,
|
||||
hybridSimple.gzip.length,
|
||||
hybridAdvanced.gzip.length
|
||||
);
|
||||
var min = gzips.reduce(function(min, gzip) {
|
||||
var length = gzip.length;
|
||||
return min > length ? length : min;
|
||||
}, Infinity);
|
||||
|
||||
// pass the minified source to the "onComplete" callback
|
||||
[compiledSimple, compiledAdvanced, uglified, hybridSimple, hybridAdvanced].some(function(data) {
|
||||
if (data.gzip.length == min) {
|
||||
this.onComplete(data.source);
|
||||
objects.some(function(data) {
|
||||
var gzip = data.gzip;
|
||||
if (gzip && gzip.length == min) {
|
||||
data.outputPath = this.outputPath;
|
||||
this.onComplete(data);
|
||||
return true;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
var fs = require('fs');
|
||||
|
||||
/** The minimal license/copyright template */
|
||||
var licenseTemplate = {
|
||||
'lodash':
|
||||
'/*!\n' +
|
||||
' Lo-Dash <%= VERSION %> lodash.com/license\n' +
|
||||
' Underscore.js 1.4.3 underscorejs.org/LICENSE\n' +
|
||||
'*/',
|
||||
'underscore':
|
||||
'/*! Underscore.js <%= VERSION %> underscorejs.org/LICENSE */'
|
||||
};
|
||||
var licenseTemplate = [
|
||||
'/**',
|
||||
' * @license',
|
||||
' * Lo-Dash <%= VERSION %> lodash.com/license',
|
||||
' * Underscore.js 1.4.4 underscorejs.org/LICENSE',
|
||||
' */'
|
||||
].join('\n');
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -26,36 +24,35 @@
|
||||
* @returns {String} Returns the processed source.
|
||||
*/
|
||||
function postprocess(source) {
|
||||
// move vars exposed by the Closure Compiler into the IIFE
|
||||
source = source.replace(/^((?:(['"])use strict\2;)?(?:var (?:[a-z]+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^)]+\){)/, '$3$1');
|
||||
// remove copyright header
|
||||
source = source.replace(/^\/\**[\s\S]+?\*\/\n/, '');
|
||||
|
||||
// correct overly aggressive Closure Compiler advanced optimizations
|
||||
source = source.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}');
|
||||
|
||||
// unescape properties (e.g. foo["bar"] => foo.bar)
|
||||
source = source.replace(/(\w)\["([^."]+)"\]/g, function(match, left, right) {
|
||||
return /\W/.test(right) ? match : (left + '.' + right);
|
||||
});
|
||||
source = source
|
||||
.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}')
|
||||
.replace(/(document[^&]+&&)\s*(?:\w+|!\d)/, '$1!({toString:0}+"")');
|
||||
|
||||
// flip `typeof` expressions to help optimize Safari and
|
||||
// correct the AMD module definition for AMD build optimizers
|
||||
// (e.g. from `"number" == typeof x` to `typeof x == "number")
|
||||
source = source.replace(/(return)?("[^"]+")\s*([!=]=)\s*(typeof(?:\s*\([^)]+\)|\s+[\w.]+))/g, function(match, ret, type, equality, expression) {
|
||||
return (ret ? ret + ' ' : '') + expression + equality + type;
|
||||
source = source.replace(/(\w)?("[^"]+")\s*([!=]=)\s*(typeof(?:\s*\([^)]+\)|\s+[.\w]+(?!\[)))/g, function(match, other, type, equality, expression) {
|
||||
return (other ? other + ' ' : '') + expression + equality + type;
|
||||
});
|
||||
|
||||
// add trailing semicolon
|
||||
if (source) {
|
||||
source = source.replace(/[\s;]*$/, ';');
|
||||
source = source.replace(/[\s;]*?(\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*$/, ';$1');
|
||||
}
|
||||
// exit early if version snippet isn't found
|
||||
var snippet = /VERSION\s*[=:]\s*([\'"])(.*?)\1/.exec(source);
|
||||
if (!snippet) {
|
||||
return source;
|
||||
}
|
||||
// add copyright/license header
|
||||
return licenseTemplate[/call\(this\);?$/.test(source) ? 'underscore' : 'lodash']
|
||||
.replace('<%= VERSION %>', snippet[2]) + '\n;' + source;
|
||||
// add new copyright header
|
||||
var version = snippet[2];
|
||||
source = licenseTemplate.replace('<%= VERSION %>', version) + '\n;' + source;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** Load Node modules */
|
||||
var exec = require('child_process').exec,
|
||||
fs = require('fs'),
|
||||
https = require('https'),
|
||||
path = require('path'),
|
||||
tar = require('../vendor/tar/tar.js'),
|
||||
zlib = require('zlib');
|
||||
|
||||
/** The path of the directory that is the base of the repository */
|
||||
var basePath = fs.realpathSync(path.join(__dirname, '..'));
|
||||
|
||||
/** The path of the `vendor` directory */
|
||||
var vendorPath = path.join(basePath, 'vendor');
|
||||
|
||||
/** The Git object ID of `closure-compiler.tar.gz` */
|
||||
var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';
|
||||
|
||||
/** The Git object ID of `uglifyjs.tar.gz` */
|
||||
var uglifyId = '7ecae09d413eb48dd5785fe877f24e60ac3bbcef';
|
||||
|
||||
/** The media type for raw blob data */
|
||||
var mediaType = 'application/vnd.github.v3.raw';
|
||||
|
||||
/** Reassign `existsSync` for older versions of Node */
|
||||
fs.existsSync || (fs.existsSync = path.existsSync);
|
||||
|
||||
/** Used to reference parts of the blob href */
|
||||
var location = (function() {
|
||||
var host = 'api.github.com',
|
||||
origin = 'https://api.github.com',
|
||||
pathname = '/repos/bestiejs/lodash/git/blobs';
|
||||
|
||||
return {
|
||||
'host': host,
|
||||
'href': host + origin + pathname,
|
||||
'origin': origin,
|
||||
'pathname': pathname
|
||||
};
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Fetches a required `.tar.gz` dependency with the given Git object ID from
|
||||
* the Lo-Dash repo on GitHub. The object ID may be obtained by running
|
||||
* `git hash-object path/to/dependency.tar.gz`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} options The options object.
|
||||
* id - The Git object ID of the `.tar.gz` file.
|
||||
* onComplete - The function, invoked with one argument (exception),
|
||||
* called once the extraction has finished.
|
||||
* path - The path of the extraction directory.
|
||||
* title - The dependency's title used in status updates logged to the console.
|
||||
*/
|
||||
function getDependency(options) {
|
||||
options || (options = {});
|
||||
|
||||
var id = options.id,
|
||||
onComplete = options.onComplete,
|
||||
path = options.path,
|
||||
title = options.title;
|
||||
|
||||
function callback(exception) {
|
||||
if (exception) {
|
||||
console.error([
|
||||
'There was a problem installing ' + title + '. To manually install, run:',
|
||||
'',
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
|
||||
].join('\n'));
|
||||
}
|
||||
onComplete(exception);
|
||||
}
|
||||
|
||||
console.log('Downloading ' + title + '...');
|
||||
|
||||
https.get({
|
||||
'host': location.host,
|
||||
'path': location.pathname + '/' + id,
|
||||
'headers': {
|
||||
// By default, all GitHub blob API endpoints return a JSON document
|
||||
// containing Base64-encoded blob data. Overriding the `Accept` header
|
||||
// with the GitHub raw media type returns the blob data directly.
|
||||
// See http://developer.github.com/v3/media/.
|
||||
'Accept': mediaType
|
||||
}
|
||||
}, function(response) {
|
||||
var decompressor = zlib.createUnzip(),
|
||||
parser = new tar.Extract({ 'path': path });
|
||||
|
||||
decompressor.on('error', callback)
|
||||
parser.on('end', callback).on('error', callback);
|
||||
response.pipe(decompressor).pipe(parser);
|
||||
})
|
||||
.on('error', callback);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
exec('npm -g root', function(exception, stdout) {
|
||||
if (!exception) {
|
||||
try {
|
||||
var root = stdout.trim(),
|
||||
isGlobal = fs.existsSync(root) && path.resolve(basePath, '..') == fs.realpathSync(root);
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
if (exception) {
|
||||
console.error([
|
||||
'Oops! There was a problem detecting the install mode. If you’re installing the',
|
||||
'Lo-Dash command-line executable (via `npm install -g lodash`), you’ll need to',
|
||||
'manually install UglifyJS and the Closure Compiler by running:',
|
||||
'',
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId + " | tar xvz -C '" + vendorPath + "'",
|
||||
'',
|
||||
'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
|
||||
].join('\n'));
|
||||
|
||||
console.error(exception);
|
||||
}
|
||||
if (!isGlobal) {
|
||||
return;
|
||||
}
|
||||
// download the Closure Compiler
|
||||
getDependency({
|
||||
'title': 'the Closure Compiler',
|
||||
'id': closureId,
|
||||
'path': vendorPath,
|
||||
'onComplete': function() {
|
||||
// download UglifyJS
|
||||
getDependency({
|
||||
'title': 'UglifyJS',
|
||||
'id': uglifyId,
|
||||
'path': vendorPath,
|
||||
'onComplete': function() {
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}());
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
/** Used to minify variables embedded in compiled strings */
|
||||
var compiledVars = [
|
||||
'args',
|
||||
'argsIndex',
|
||||
'argsLength',
|
||||
'callback',
|
||||
@@ -17,15 +18,15 @@
|
||||
'hasOwnProperty',
|
||||
'index',
|
||||
'isArguments',
|
||||
'isArray',
|
||||
'isString',
|
||||
'iteratee',
|
||||
'iterable',
|
||||
'length',
|
||||
'nativeKeys',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'ownIndex',
|
||||
'ownProps',
|
||||
'propertyIsEnumerable',
|
||||
'result',
|
||||
'skipProto',
|
||||
'source',
|
||||
@@ -35,18 +36,18 @@
|
||||
/** Used to minify `compileIterator` option properties */
|
||||
var iteratorOptions = [
|
||||
'args',
|
||||
'arrayLoop',
|
||||
'arrays',
|
||||
'bottom',
|
||||
'firstArg',
|
||||
'hasDontEnumBug',
|
||||
'hasEnumPrototype',
|
||||
'isKeysFast',
|
||||
'objectLoop',
|
||||
'loop',
|
||||
'nonEnumArgs',
|
||||
'noCharByIndex',
|
||||
'shadowed',
|
||||
'top',
|
||||
'useHas',
|
||||
'useStrict'
|
||||
'useHas'
|
||||
];
|
||||
|
||||
/** Used to minify variables and string values to a single character */
|
||||
@@ -64,10 +65,12 @@
|
||||
'amd',
|
||||
'any',
|
||||
'assign',
|
||||
'at',
|
||||
'attachEvent',
|
||||
'bind',
|
||||
'bindAll',
|
||||
'bindKey',
|
||||
'clearTimeout',
|
||||
'clone',
|
||||
'cloneDeep',
|
||||
'collect',
|
||||
@@ -104,6 +107,7 @@
|
||||
'groupBy',
|
||||
'has',
|
||||
'head',
|
||||
'imports',
|
||||
'identity',
|
||||
'include',
|
||||
'index',
|
||||
@@ -150,6 +154,7 @@
|
||||
'opera',
|
||||
'pairs',
|
||||
'partial',
|
||||
'partialRight',
|
||||
'pick',
|
||||
'pluck',
|
||||
'random',
|
||||
@@ -160,6 +165,8 @@
|
||||
'rest',
|
||||
'result',
|
||||
'select',
|
||||
'setImmediate',
|
||||
'setTimeout',
|
||||
'shuffle',
|
||||
'size',
|
||||
'some',
|
||||
@@ -191,10 +198,7 @@
|
||||
// properties used by the `backbone` and `underscore` builds
|
||||
'__chain__',
|
||||
'chain',
|
||||
|
||||
// properties used by underscore.js
|
||||
'_chain',
|
||||
'_wrapped'
|
||||
'findWhere'
|
||||
];
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -216,9 +220,6 @@
|
||||
if (options.isTemplate) {
|
||||
return source;
|
||||
}
|
||||
// remove copyright/license header to add later in post-compile.js
|
||||
source = source.replace(/\/\*![\s\S]+?\*\//, '');
|
||||
|
||||
// add brackets to whitelisted properties so the Closure Compiler won't mung them
|
||||
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
|
||||
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), function(match, prop) {
|
||||
@@ -228,9 +229,6 @@
|
||||
// remove brackets from `_.escape()` in `_.template`
|
||||
source = source.replace(/__e *= *_\['escape']/g, '__e=_.escape');
|
||||
|
||||
// remove brackets from `_.escape()` in underscore.js `_.template`
|
||||
source = source.replace(/_\['escape'\]\(__t'/g, '_.escape(__t');
|
||||
|
||||
// remove brackets from `collection.indexOf` in `_.contains`
|
||||
source = source.replace("collection['indexOf'](target)", 'collection.indexOf(target)');
|
||||
|
||||
@@ -238,27 +236,21 @@
|
||||
source = source.replace("result[length]['value']", 'result[length].value');
|
||||
|
||||
// remove whitespace from string literals
|
||||
source = source.replace(/^([ "'\w]+:)? *"(?:(?=(\\?))\2.)*?"|'(?:(?=(\\?))\3.)*?'/gm, function(string, captured) {
|
||||
source = source.replace(/^([ "'\w]+:)? *"[^"\\\n]*(?:\\.[^"\\\n]*)*"|'[^'\\\n]*(?:\\.[^'\\\n]*)*'/gm, function(string, captured) {
|
||||
// remove object literal property name
|
||||
if (/:$/.test(captured)) {
|
||||
string = string.slice(captured.length);
|
||||
}
|
||||
// avoids removing the '\n' of the `stringEscapes` object
|
||||
string = string.replace(/\[object |delete |else |function | in |return\s+[\w"']|throw |typeof |use strict|var |@ |(["'])\\n\1|\\\\n|\\n|\s+/g, function(match) {
|
||||
string = string.replace(/\[object |delete |else (?!{)|function | in |return\s+[\w"']|throw |typeof |use strict|var |@ |(["'])\\n\1|\\\\n|\\n|\s+/g, function(match) {
|
||||
return match == false || match == '\\n' ? '' : match;
|
||||
});
|
||||
// prepend object literal property name
|
||||
return (captured || '') + string;
|
||||
});
|
||||
|
||||
// add newline to `+"__p+='"` in underscore.js `_.template`
|
||||
source = source.replace(/\+"__p\+='"/g, '+"\\n__p+=\'"');
|
||||
|
||||
// add newline to `body + '}'` in `createFunction`
|
||||
source = source.replace(/body *\+ *'}'/, 'body+"\\n}"');
|
||||
|
||||
// remove whitespace from `_.template` related regexes
|
||||
source = source.replace(/(?:reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
|
||||
source = source.replace(/reEmptyString\w+ *=.+/g, function(match) {
|
||||
return match.replace(/ |\\n/g, '');
|
||||
});
|
||||
|
||||
@@ -267,9 +259,6 @@
|
||||
.replace('"__p += \'"', '"__p+=\'"')
|
||||
.replace('"\';\n"', '"\';"')
|
||||
|
||||
// remove `useSourceURL` variable
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
||||
|
||||
// remove debug sourceURL use in `_.template`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)* *var sourceURL[^;]+;|\+ *sourceURL/g, '');
|
||||
|
||||
@@ -286,14 +275,15 @@
|
||||
|
||||
// minify properties
|
||||
properties.forEach(function(property, index) {
|
||||
var reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
var minName = minNames[index],
|
||||
reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
||||
rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + property + "\\2 *:", 'g');
|
||||
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, "['" + minNames[index] + "']")
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':");
|
||||
.replace(reBracketProp, "['" + minName + "']")
|
||||
.replace(reDotProp, "['" + minName + "']")
|
||||
.replace(rePropColon, "$1'" + minName + "':");
|
||||
});
|
||||
|
||||
// replace with modified snippet
|
||||
@@ -331,36 +321,30 @@
|
||||
});
|
||||
|
||||
if (isCreateIterator) {
|
||||
// replace with modified snippet early and clip snippet to the `factory`
|
||||
// call so other arguments aren't minified
|
||||
// clip before the `factory` call to avoid minifying its arguments
|
||||
source = source.replace(snippet, modified);
|
||||
snippet = modified = modified.replace(/factory\([\s\S]+$/, '');
|
||||
snippet = modified = modified.replace(/return factory\([\s\S]+$/, '');
|
||||
}
|
||||
// minify `createIterator` option property names
|
||||
iteratorOptions.forEach(function(property, index) {
|
||||
var minName = minNames[index];
|
||||
|
||||
// minify variables in `iteratorTemplate` or property names in everything else
|
||||
modified = isIteratorTemplate
|
||||
? modified.replace(RegExp('\\b' + property + '\\b', 'g'), minName)
|
||||
: modified.replace(RegExp("'" + property + "'", 'g'), "'" + minName + "'");
|
||||
});
|
||||
|
||||
// minify snippet variables / arguments
|
||||
compiledVars.forEach(function(variable, index) {
|
||||
var minName = minNames[index];
|
||||
|
||||
// ensure properties in compiled strings aren't minified
|
||||
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
|
||||
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minName);
|
||||
|
||||
// correct `typeof` values
|
||||
if (/^(?:boolean|function|object|number|string|undefined)$/.test(variable)) {
|
||||
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), '$1' + variable + "'");
|
||||
}
|
||||
});
|
||||
|
||||
// minify `createIterator` option property names
|
||||
iteratorOptions.forEach(function(property, index) {
|
||||
if (isIteratorTemplate) {
|
||||
// minify property names as interpolated template variables
|
||||
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||
}
|
||||
else {
|
||||
// minify property name strings
|
||||
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||
// minify property names in accessors
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('\\.' + property + '\\b' , 'g'), '.' + minNames[index]);
|
||||
}
|
||||
modified = modified.replace(RegExp("(typeof [^']+')" + minName + "'", 'g'), '$1' + variable + "'");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
5152
dist/lodash.compat.js
vendored
Normal file
5152
dist/lodash.compat.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
42
dist/lodash.compat.min.js
vendored
Normal file
42
dist/lodash.compat.min.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @license
|
||||
* Lo-Dash 1.0.2 (Custom Build) lodash.com/license
|
||||
* Build: `lodash -o ./dist/lodash.compat.js`
|
||||
* Underscore.js 1.4.4 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(n,t){function r(n){return n&&typeof n=="object"&&n.__wrapped__?n:this instanceof r?(this.__wrapped__=n,void 0):new r(n)}function e(n,t,r){t||(t=0);var e=n.length,u=e-t>=(r||at);if(u){var o={};for(r=t-1;++r<e;){var i=n[r]+"";(St.call(o,i)?o[i]:o[i]=[]).push(n[r])}}return function(r){if(u){var e=r+"";return St.call(o,e)&&-1<z(o[e],r)}return-1<z(n,r,t)}}function u(n){return n.charCodeAt(0)}function o(n,t){var r=n.b,e=t.b;if(n=n.a,t=t.a,n!==t){if(n>t||typeof n=="undefined")return 1;if(n<t||typeof t=="undefined")return-1
|
||||
}return r<e?-1:1}function i(n,t,r,e){function u(){var a=arguments,c=i?this:t;return o||(n=t[f]),r.length&&(a=a.length?(a=v(a),e?a.concat(r):r.concat(a)):r),this instanceof u?(s.prototype=n.prototype,c=new s,s.prototype=W,a=n.apply(c,a),x(a)?a:c):n.apply(c,a)}var o=w(n),i=!r,f=t;return i&&(r=t),o||(t=n),u}function f(n,t,r){if(n==W)return G;var e=typeof n;if("function"!=e){if("object"!=e)return function(t){return t[n]};var u=vr(n);return function(t){for(var r=u.length,e=X;r--&&(e=j(t[u[r]],n[u[r]],ft)););return e
|
||||
}}return typeof t!="undefined"?1===r?function(r){return n.call(t,r)}:2===r?function(r,e){return n.call(t,r,e)}:4===r?function(r,e,u,o){return n.call(t,r,e,u,o)}:function(r,e,u){return n.call(t,r,e,u)}:n}function a(){for(var n,t={e:tt,f:rt,g:Jt,i:Wt,j:Zt,k:jt,b:"l(n)",c:"",h:"",l:"",m:Q},r=0;n=arguments[r];r++)for(var e in n)t[e]=n[e];if(n=t.a,t.d=/^[^,]+/.exec(n)[0],r="var j,n="+t.d+",u=n;if(!n)return u;"+t.l+";",t.b?(r+="var o=n.length;j=-1;if("+t.b+"){",t.j&&(r+="if(m(n)){n=n.split('')}"),r+="while(++j<o){"+t.h+"}}else{"):t.i&&(r+="var o=n.length;j=-1;if(o&&k(n)){while(++j<o){j+='';"+t.h+"}}else{"),t.f&&(r+="var v=typeof n=='function';"),t.g&&t.m?(r+="var s=-1,t=r[typeof n]?p(n):[],o=t.length;while(++s<o){j=t[s];",t.f&&(r+="if(!(v&&j=='prototype')){"),r+=t.h+"",t.f&&(r+="}")):(r+="for(j in n){",(t.f||t.m)&&(r+="if(",t.f&&(r+="!(v&&j=='prototype')"),t.f&&t.m&&(r+="&&"),t.m&&(r+="i.call(n,j)"),r+="){"),r+=t.h+";",(t.f||t.m)&&(r+="}")),r+="}",t.e)for(r+="var g=n.constructor;",e=0;7>e;e++)r+="j='"+t.k[e]+"';if(","constructor"==t.k[e]&&(r+="!(g&&g.prototype===n)&&"),r+="i.call(n,j)){"+t.h+"}";
|
||||
return(t.b||t.i)&&(r+="}"),r+=t.c+";return u",Function("f,i,k,l,m,r,p","return function("+n+"){"+r+"}")(f,St,y,sr,A,ur,Ft)}function c(n){return"\\"+or[n]}function l(n){return gr[n]}function p(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}function s(){}function v(n,t,r){t||(t=0),typeof r=="undefined"&&(r=n?n.length:0);var e=-1;r=r-t||0;for(var u=Array(0>r?0:r);++e<r;)u[e]=n[t+e];return u}function g(n){return yr[n]}function y(n){return kt.call(n)==Bt}function h(n){var t=X;if(!n||typeof n!="object"||y(n))return t;
|
||||
var r=n.constructor;return!w(r)&&(!nr||!p(n))||r instanceof r?et?(lr(n,function(n,r,e){return t=!St.call(e,r),X}),t===X):(lr(n,function(n,r){t=r}),t===X||St.call(n,t)):t}function m(n){var t=[];return pr(n,function(n,r){t.push(r)}),t}function d(n,r,e,u,o,i){var a=n;if(typeof r=="function"&&(u=e,e=r,r=X),typeof e=="function"){e=typeof u=="undefined"?e:f(e,u,1);var a=e(a),c=typeof a!="undefined";c||(a=n)}if(u=x(a)){var l=kt.call(a);if(!rr[l]||nr&&p(a))return a;var s=sr(a)}if(!u||!r)return u&&!c?s?v(a):hr({},a):a;
|
||||
switch(u=er[l],l){case Pt:case zt:return c?a:new u(+a);case Ct:case Ut:return c?a:new u(a);case Lt:return c?a:u(a.source,gt.exec(a))}for(o||(o=[]),i||(i=[]),l=o.length;l--;)if(o[l]==n)return i[l];return c||(a=s?u(a.length):{},s&&(St.call(n,"index")&&(a.index=n.index),St.call(n,"input")&&(a.input=n.input))),o.push(n),i.push(a),(s?$:pr)(c?a:n,function(n,u){a[u]=d(n,r,e,t,o,i)}),a}function _(n){var t=[];return lr(n,function(n,r){w(n)&&t.push(r)}),t.sort()}function b(n){for(var t=-1,r=vr(n),e=r.length,u={};++t<e;){var o=r[t];
|
||||
u[n[o]]=o}return u}function j(n,t,r,e,u,o){var i=r===ft;if(r&&!i){r=typeof e=="undefined"?r:f(r,e,2);var a=r(n,t);if(typeof a!="undefined")return!!a}if(n===t)return 0!==n||1/n==1/t;var c=typeof n,l=typeof t;if(n===n&&(!n||"function"!=c&&"object"!=c)&&(!t||"function"!=l&&"object"!=l))return X;if(n==W||t==W)return n===t;if(l=kt.call(n),c=kt.call(t),l==Bt&&(l=Kt),c==Bt&&(c=Kt),l!=c)return X;switch(l){case Pt:case zt:return+n==+t;case Ct:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case Lt:case Ut:return n==t+""
|
||||
}if(c=l==Mt,!c){if(n.__wrapped__||t.__wrapped__)return j(n.__wrapped__||n,t.__wrapped__||t,r,e,u,o);if(l!=Kt||nr&&(p(n)||p(t)))return X;var l=!Xt&&y(n)?Object:n.constructor,s=!Xt&&y(t)?Object:t.constructor;if(l!=s&&(!w(l)||!(l instanceof l&&w(s)&&s instanceof s)))return X}for(u||(u=[]),o||(o=[]),l=u.length;l--;)if(u[l]==n)return o[l]==t;var v=0,a=Q;if(u.push(n),o.push(t),c){if(l=n.length,v=t.length,a=v==n.length,!a&&!i)return a;for(;v--;)if(c=l,s=t[v],i)for(;c--&&!(a=j(n[c],s,r,e,u,o)););else if(!(a=j(n[v],s,r,e,u,o)))break;
|
||||
return a}return lr(t,function(t,i,f){return St.call(f,i)?(v++,a=St.call(n,i)&&j(n[i],t,r,e,u,o)):void 0}),a&&!i&&lr(n,function(n,t,r){return St.call(r,t)?a=-1<--v:void 0}),a}function w(n){return typeof n=="function"}function x(n){return n?ur[typeof n]:X}function O(n){return typeof n=="number"||kt.call(n)==Ct}function A(n){return typeof n=="string"||kt.call(n)==Ut}function S(n,t,r){var e=arguments,u=0,o=2;if(!x(n))return n;if(r===ft)var i=e[3],a=e[4],c=e[5];else a=[],c=[],typeof r!="number"&&(o=e.length),3<o&&"function"==typeof e[o-2]?i=f(e[--o-1],e[o--],2):2<o&&"function"==typeof e[o-1]&&(i=e[--o]);
|
||||
for(;++u<o;)(sr(e[u])?$:pr)(e[u],function(t,r){var e,u,o=t,f=n[r];if(t&&((u=sr(t))||dr(t))){for(o=a.length;o--;)if(e=a[o]==t){f=c[o];break}e||(f=u?sr(f)?f:[]:dr(f)?f:{},i&&(o=i(f,t),typeof o!="undefined"&&(f=o)),a.push(t),c.push(f),i||(f=S(f,t,ft,i,a,c)))}else i&&(o=i(f,t),typeof o=="undefined"&&(o=t)),typeof o!="undefined"&&(f=o);n[r]=f});return n}function E(n){for(var t=-1,r=vr(n),e=r.length,u=Array(e);++t<e;)u[t]=n[r[t]];return u}function k(n,t,r){var e=-1,u=n?n.length:0,o=X;return r=(0>r?qt(0,u+r):r)||0,typeof u=="number"?o=-1<(A(n)?n.indexOf(t,r):z(n,t,r)):cr(n,function(n){return++e<r?void 0:!(o=n===t)
|
||||
}),o}function I(n,t,r){var e=Q;if(t=f(t,r),sr(n)){r=-1;for(var u=n.length;++r<u&&(e=!!t(n[r],r,n)););}else cr(n,function(n,r,u){return e=!!t(n,r,u)});return e}function N(n,t,r){var e=[];if(t=f(t,r),sr(n)){r=-1;for(var u=n.length;++r<u;){var o=n[r];t(o,r,n)&&e.push(o)}}else cr(n,function(n,r,u){t(n,r,u)&&e.push(n)});return e}function R(n,t,r){var e;return t=f(t,r),$(n,function(n,r,u){return t(n,r,u)?(e=n,X):void 0}),e}function $(n,t,r){if(t&&typeof r=="undefined"&&sr(n)){r=-1;for(var e=n.length;++r<e&&t(n[r],r,n)!==X;);}else cr(n,t,r);
|
||||
return n}function F(n,t,r){var e=-1,u=n?n.length:0,o=Array(typeof u=="number"?u:0);if(t=f(t,r),sr(n))for(;++e<u;)o[e]=t(n[e],e,n);else cr(n,function(n,r,u){o[++e]=t(n,r,u)});return o}function q(n,t,r){var e=-1/0,o=e;if(!t&&sr(n)){r=-1;for(var i=n.length;++r<i;){var a=n[r];a>o&&(o=a)}}else t=!t&&A(n)?u:f(t,r),cr(n,function(n,r,u){r=t(n,r,u),r>e&&(e=r,o=n)});return o}function D(n,t,r,e){var u=3>arguments.length;if(t=f(t,e,4),sr(n)){var o=-1,i=n.length;for(u&&(r=n[++o]);++o<i;)r=t(r,n[o],o,n)}else cr(n,function(n,e,o){r=u?(u=X,n):t(r,n,e,o)
|
||||
});return r}function T(n,t,r,e){var u=n,o=n?n.length:0,i=3>arguments.length;if(typeof o!="number")var a=vr(n),o=a.length;else Zt&&A(n)&&(u=n.split(""));return t=f(t,e,4),$(n,function(n,e,f){e=a?a[--o]:--o,r=i?(i=X,u[e]):t(r,u[e],e,f)}),r}function B(n,t,r){var e;if(t=f(t,r),sr(n)){r=-1;for(var u=n.length;++r<u&&!(e=t(n[r],r,n)););}else cr(n,function(n,r,u){return!(e=t(n,r,u))});return!!e}function M(n,t,r){if(n){var e=0,u=n.length;if(typeof t!="number"&&t!=W){var o=-1;for(t=f(t,r);++o<u&&t(n[o],o,n);)e++
|
||||
}else if(e=t,e==W||r)return n[0];return v(n,0,Dt(qt(0,e),u))}}function P(n,t){for(var r=-1,e=n?n.length:0,u=[];++r<e;){var o=n[r];sr(o)?Et.apply(u,t?o:P(o)):u.push(o)}return u}function z(n,t,r){var e=-1,u=n?n.length:0;if(typeof r=="number")e=(0>r?qt(0,u+r):r||0)-1;else if(r)return e=K(n,t),n[e]===t?e:-1;for(;++e<u;)if(n[e]===t)return e;return-1}function C(n,t,r){if(typeof t!="number"&&t!=W){var e=0,u=-1,o=n?n.length:0;for(t=f(t,r);++u<o&&t(n[u],u,n);)e++}else e=t==W||r?1:qt(0,t);return v(n,e)}function K(n,t,r,e){var u=0,o=n?n.length:u;
|
||||
for(r=r?f(r,e,1):G,t=r(t);u<o;)e=u+o>>>1,r(n[e])<t?u=e+1:o=e;return u}function L(n,t,r,e){var u=-1,o=n?n.length:0,i=[],a=i;typeof t=="function"&&(e=r,r=t,t=X);var c=!t&&75<=o;if(c)var l={};for(r&&(a=[],r=f(r,e));++u<o;){e=n[u];var p=r?r(e,u,n):e;if(c)var s=p+"",s=St.call(l,s)?!(a=l[s]):a=l[s]=[];(t?!u||a[a.length-1]!==p:s||0>z(a,p))&&((r||c)&&a.push(p),i.push(e))}return i}function U(n,t){return Ht||It&&2<arguments.length?It.call.apply(It,arguments):i(n,t,v(arguments,2))}function V(n){var r=v(arguments,1);
|
||||
return setTimeout(function(){n.apply(t,r)},1)}function G(n){return n}function H(n){$(_(n),function(t){var e=r[t]=n[t];r.prototype[t]=function(){var n=[this.__wrapped__];return Et.apply(n,arguments),new r(e.apply(r,n))}})}function J(){return this.__wrapped__}var Q=!0,W=null,X=!1,Y=typeof exports=="object"&&exports,Z=typeof module=="object"&&module&&module.exports==Y&&module,nt=typeof global=="object"&&global;nt.global===nt&&(n=nt);var tt,rt,et,ut=[],ot={},it=0,ft=ot,at=30,ct=n._,lt=/&(?:amp|lt|gt|quot|#39);/g,pt=/\b__p\+='';/g,st=/\b(__p\+=)''\+/g,vt=/(__e\(.*?\)|\b__t\))\+'';/g,gt=/\w*$/,yt=RegExp("^"+(ot.valueOf+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),ht=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,mt=/<%=([\s\S]+?)%>/g,dt=/($^)/,_t=/[&<>"']/g,bt=/['\n\r\t\u2028\u2029\\]/g,jt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),wt=Math.ceil,xt=ut.concat,Ot=Math.floor,At=yt.test(At=Object.getPrototypeOf)&&At,St=ot.hasOwnProperty,Et=ut.push,kt=ot.toString,It=yt.test(It=v.bind)&&It,Nt=yt.test(Nt=Array.isArray)&&Nt,Rt=n.isFinite,$t=n.isNaN,Ft=yt.test(Ft=Object.keys)&&Ft,qt=Math.max,Dt=Math.min,Tt=Math.random,Bt="[object Arguments]",Mt="[object Array]",Pt="[object Boolean]",zt="[object Date]",Ct="[object Number]",Kt="[object Object]",Lt="[object RegExp]",Ut="[object String]",Vt=!!n.attachEvent,Gt=It&&!/\n|true/.test(It+Vt),Ht=It&&!Gt,Jt=Ft&&(Vt||Gt),Qt=(Qt={0:1,length:1},ut.splice.call(Qt,0,1),Qt[0]),Wt=Q;
|
||||
(function(){function n(){this.x=1}var t=[];n.prototype={valueOf:1,y:1};for(var r in new n)t.push(r);for(r in arguments)Wt=!r;tt=!/valueOf/.test(t),rt=n.propertyIsEnumerable("prototype"),et="x"!=t[0]})(1);var Xt=arguments.constructor==Object,Yt=!y(arguments),Zt="xx"!="x"[0]+Object("x")[0];try{var nr=kt.call(document)==Kt&&!({toString:0}+"")}catch(tr){}var rr={"[object Function]":X};rr[Bt]=rr[Mt]=rr[Pt]=rr[zt]=rr[Ct]=rr[Kt]=rr[Lt]=rr[Ut]=Q;var er={};er[Mt]=Array,er[Pt]=Boolean,er[zt]=Date,er[Kt]=Object,er[Ct]=Number,er[Lt]=RegExp,er[Ut]=String;
|
||||
var ur={"boolean":X,"function":Q,object:Q,number:X,string:X,undefined:X},or={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};r.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:mt,variable:"",imports:{_:r}};var ir={a:"q,w,h",l:"var a=arguments,b=0,c=typeof h=='number'?2:a.length;while(++b<c){n=a[b];if(n&&r[typeof n]){",h:"if(typeof u[j]=='undefined')u[j]=n[j]",c:"}}"},fr={a:"e,d,x",l:"d=d&&typeof x=='undefined'?d:f(d,x)",b:"typeof o=='number'",h:"if(d(n[j],j,e)===false)return u"},ar={l:"if(!r[typeof n])return u;"+fr.l,b:X},cr=a(fr);
|
||||
Yt&&(y=function(n){return n?St.call(n,"callee"):X});var lr=a(fr,ar,{m:X}),pr=a(fr,ar),sr=Nt||function(n){return Xt&&n instanceof Array||kt.call(n)==Mt},vr=Ft?function(n){return x(n)?rt&&typeof n=="function"||Wt&&n.length&&y(n)?m(n):Ft(n):[]}:m,gr={"&":"&","<":"<",">":">",'"':""","'":"'"},yr=b(gr),hr=a(ir,{l:ir.l.replace(";",";if(c>3&&typeof a[c-2]=='function'){var d=f(a[--c-1],a[c--],2);}else if(c>2&&typeof a[c-1]=='function'){d=a[--c];}"),h:"u[j]=d?d(u[j],n[j]):n[j]"}),mr=a(ir);
|
||||
w(/x/)&&(w=function(n){return n instanceof Function||"[object Function]"==kt.call(n)});var dr=At?function(n){if(!n||typeof n!="object")return X;var t=n.valueOf,r=typeof t=="function"&&(r=At(t))&&At(r);return r?n==r||At(n)==r&&!y(n):h(n)}:h,_r=F,br=N;Gt&&Z&&typeof setImmediate=="function"&&(V=U(setImmediate,n)),r.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},r.assign=hr,r.at=function(n){var t=-1,r=xt.apply(ut,v(arguments,1)),e=r.length,u=Array(e);for(Zt&&A(n)&&(n=n.split(""));++t<e;)u[t]=n[r[t]];
|
||||
return u},r.bind=U,r.bindAll=function(n){for(var t=xt.apply(ut,arguments),r=1<t.length?0:(t=_(n),-1),e=t.length;++r<e;){var u=t[r];n[u]=U(n[u],n)}return n},r.bindKey=function(n,t){return i(n,t,v(arguments,2))},r.compact=function(n){for(var t=-1,r=n?n.length:0,e=[];++t<r;){var u=n[t];u&&e.push(u)}return e},r.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length;r--;)t=[n[r].apply(this,t)];return t[0]}},r.countBy=function(n,t,r){var e={};return t=f(t,r),$(n,function(n,r,u){r=t(n,r,u)+"",St.call(e,r)?e[r]++:e[r]=1
|
||||
}),e},r.debounce=function(n,t,r){function e(){f=W,r||(o=n.apply(i,u))}var u,o,i,f;return function(){var a=r&&!f;return u=arguments,i=this,clearTimeout(f),f=setTimeout(e,t),a&&(o=n.apply(i,u)),o}},r.defaults=mr,r.defer=V,r.delay=function(n,r){var e=v(arguments,2);return setTimeout(function(){n.apply(t,e)},r)},r.difference=function(n){for(var t=-1,r=n?n.length:0,u=xt.apply(ut,arguments),u=e(u,r),o=[];++t<r;){var i=n[t];u(i)||o.push(i)}return o},r.filter=N,r.flatten=P,r.forEach=$,r.forIn=lr,r.forOwn=pr,r.functions=_,r.groupBy=function(n,t,r){var e={};
|
||||
return t=f(t,r),$(n,function(n,r,u){r=t(n,r,u)+"",(St.call(e,r)?e[r]:e[r]=[]).push(n)}),e},r.initial=function(n,t,r){if(!n)return[];var e=0,u=n.length;if(typeof t!="number"&&t!=W){var o=u;for(t=f(t,r);o--&&t(n[o],o,n);)e++}else e=t==W||r?1:t||e;return v(n,0,Dt(qt(0,u-e),u))},r.intersection=function(n){var t=arguments,r=t.length,u={0:{}},o=-1,i=n?n.length:0,f=100<=i,a=[],c=a;n:for(;++o<i;){var l=n[o];if(f)var p=l+"",p=St.call(u[0],p)?!(c=u[0][p]):c=u[0][p]=[];if(p||0>z(c,l)){f&&c.push(l);for(var s=r;--s;)if(!(u[s]||(u[s]=e(t[s],0,100)))(l))continue n;
|
||||
a.push(l)}}return a},r.invert=b,r.invoke=function(n,t){var r=v(arguments,2),e=-1,u=typeof t=="function",o=n?n.length:0,i=Array(typeof o=="number"?o:0);return $(n,function(n){i[++e]=(u?t:n[t]).apply(n,r)}),i},r.keys=vr,r.map=F,r.max=q,r.memoize=function(n,t){var r={};return function(){var e=(t?t.apply(this,arguments):arguments[0])+"";return St.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},r.merge=S,r.min=function(n,t,r){var e=1/0,o=e;if(!t&&sr(n)){r=-1;for(var i=n.length;++r<i;){var a=n[r];a<o&&(o=a)
|
||||
}}else t=!t&&A(n)?u:f(t,r),cr(n,function(n,r,u){r=t(n,r,u),r<e&&(e=r,o=n)});return o},r.object=function(n,t){for(var r=-1,e=n?n.length:0,u={};++r<e;){var o=n[r];t?u[o]=t[r]:u[o[0]]=o[1]}return u},r.omit=function(n,t,r){var e=typeof t=="function",u={};if(e)t=f(t,r);else var o=xt.apply(ut,arguments);return lr(n,function(n,r,i){(e?!t(n,r,i):0>z(o,r,1))&&(u[r]=n)}),u},r.once=function(n){var t,r;return function(){return t?r:(t=Q,r=n.apply(this,arguments),n=W,r)}},r.pairs=function(n){for(var t=-1,r=vr(n),e=r.length,u=Array(e);++t<e;){var o=r[t];
|
||||
u[t]=[o,n[o]]}return u},r.partial=function(n){return i(n,v(arguments,1))},r.partialRight=function(n){return i(n,v(arguments,1),W,ft)},r.pick=function(n,t,r){var e={};if(typeof t!="function")for(var u=0,o=xt.apply(ut,arguments),i=x(n)?o.length:0;++u<i;){var a=o[u];a in n&&(e[a]=n[a])}else t=f(t,r),lr(n,function(n,r,u){t(n,r,u)&&(e[r]=n)});return e},r.pluck=_r,r.range=function(n,t,r){n=+n||0,r=+r||1,t==W&&(t=n,n=0);var e=-1;t=qt(0,wt((t-n)/r));for(var u=Array(t);++e<t;)u[e]=n,n+=r;return u},r.reject=function(n,t,r){return t=f(t,r),N(n,function(n,r,e){return!t(n,r,e)
|
||||
})},r.rest=C,r.shuffle=function(n){var t=-1,r=n?n.length:0,e=Array(typeof r=="number"?r:0);return $(n,function(n){var r=Ot(Tt()*(++t+1));e[t]=e[r],e[r]=n}),e},r.sortBy=function(n,t,r){var e=-1,u=n?n.length:0,i=Array(typeof u=="number"?u:0);for(t=f(t,r),$(n,function(n,r,u){i[++e]={a:t(n,r,u),b:e,c:n}}),u=i.length,i.sort(o);u--;)i[u]=i[u].c;return i},r.tap=function(n,t){return t(n),n},r.throttle=function(n,t){function r(){f=new Date,i=W,u=n.apply(o,e)}var e,u,o,i,f=0;return function(){var a=new Date,c=t-(a-f);
|
||||
return e=arguments,o=this,0<c?i||(i=setTimeout(r,c)):(clearTimeout(i),i=W,f=a,u=n.apply(o,e)),u}},r.times=function(n,t,r){n=+n||0;for(var e=-1,u=Array(n);++e<n;)u[e]=t.call(r,e);return u},r.toArray=function(n){return n&&typeof n.length=="number"?Zt&&A(n)?n.split(""):v(n):E(n)},r.union=function(){return L(xt.apply(ut,arguments))},r.uniq=L,r.values=E,r.where=br,r.without=function(n){for(var t=-1,r=n?n.length:0,u=e(arguments,1),o=[];++t<r;){var i=n[t];u(i)||o.push(i)}return o},r.wrap=function(n,t){return function(){var r=[n];
|
||||
return Et.apply(r,arguments),t.apply(this,r)}},r.zip=function(n){for(var t=-1,r=n?q(_r(arguments,"length")):0,e=Array(r);++t<r;)e[t]=_r(arguments,t);return e},r.collect=F,r.drop=C,r.each=$,r.extend=hr,r.methods=_,r.select=N,r.tail=C,r.unique=L,H(r),r.clone=d,r.cloneDeep=function(n,t,r){return d(n,Q,t,r)},r.contains=k,r.escape=function(n){return n==W?"":(n+"").replace(_t,l)},r.every=I,r.find=R,r.has=function(n,t){return n?St.call(n,t):X},r.identity=G,r.indexOf=z,r.isArguments=y,r.isArray=sr,r.isBoolean=function(n){return n===Q||n===X||kt.call(n)==Pt
|
||||
},r.isDate=function(n){return n instanceof Date||kt.call(n)==zt},r.isElement=function(n){return n?1===n.nodeType:X},r.isEmpty=function(n){var t=Q;if(!n)return t;var r=kt.call(n),e=n.length;return r==Mt||r==Ut||r==Bt||Yt&&y(n)||r==Kt&&typeof e=="number"&&w(n.splice)?!e:(pr(n,function(){return t=X}),t)},r.isEqual=j,r.isFinite=function(n){return Rt(n)&&!$t(parseFloat(n))},r.isFunction=w,r.isNaN=function(n){return O(n)&&n!=+n},r.isNull=function(n){return n===W},r.isNumber=O,r.isObject=x,r.isPlainObject=dr,r.isRegExp=function(n){return n instanceof RegExp||kt.call(n)==Lt
|
||||
},r.isString=A,r.isUndefined=function(n){return typeof n=="undefined"},r.lastIndexOf=function(n,t,r){var e=n?n.length:0;for(typeof r=="number"&&(e=(0>r?qt(0,e+r):Dt(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},r.mixin=H,r.noConflict=function(){return n._=ct,this},r.random=function(n,t){return n==W&&t==W&&(t=1),n=+n||0,t==W&&(t=n,n=0),n+Ot(Tt()*((+t||0)-n+1))},r.reduce=D,r.reduceRight=T,r.result=function(n,r){var e=n?n[r]:t;return w(e)?n[r]():e},r.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:vr(n).length
|
||||
},r.some=B,r.sortedIndex=K,r.template=function(n,e,u){var o=r.templateSettings;n||(n=""),u=mr({},u,o);var i,f=mr({},u.imports,o.imports),o=vr(f),f=E(f),a=0,l=u.interpolate||dt,p="__p+='";n.replace(RegExp((u.escape||dt).source+"|"+l.source+"|"+(l===mt?ht:dt).source+"|"+(u.evaluate||dt).source+"|$","g"),function(t,r,e,u,o,f){return e||(e=u),p+=n.slice(a,f).replace(bt,c),r&&(p+="'+__e("+r+")+'"),o&&(i=Q,p+="';"+o+";__p+='"),e&&(p+="'+((__t=("+e+"))==null?'':__t)+'"),a=f+t.length,t}),p+="';\n",l=u=u.variable,l||(u="obj",p="with("+u+"){"+p+"}"),p=(i?p.replace(pt,""):p).replace(st,"$1").replace(vt,"$1;"),p="function("+u+"){"+(l?"":u+"||("+u+"={});")+"var __t,__p='',__e=_.escape"+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+p+"return __p}";
|
||||
try{var s=Function(o,"return "+p).apply(t,f)}catch(v){throw v.source=p,v}return e?s(e):(s.source=p,s)},r.unescape=function(n){return n==W?"":(n+"").replace(lt,g)},r.uniqueId=function(n){var t=++it;return(n==W?"":n+"")+t},r.all=I,r.any=B,r.detect=R,r.foldl=D,r.foldr=T,r.include=k,r.inject=D,pr(r,function(n,t){r.prototype[t]||(r.prototype[t]=function(){var t=[this.__wrapped__];return Et.apply(t,arguments),n.apply(r,t)})}),r.first=M,r.last=function(n,t,r){if(n){var e=0,u=n.length;if(typeof t!="number"&&t!=W){var o=u;
|
||||
for(t=f(t,r);o--&&t(n[o],o,n);)e++}else if(e=t,e==W||r)return n[u-1];return v(n,qt(0,u-e))}},r.take=M,r.head=M,pr(r,function(n,t){r.prototype[t]||(r.prototype[t]=function(t,e){var u=n(this.__wrapped__,t,e);return t==W||e&&typeof t!="function"?u:new r(u)})}),r.VERSION="1.0.2",r.prototype.toString=function(){return this.__wrapped__+""},r.prototype.value=J,r.prototype.valueOf=J,cr(["join","pop","shift"],function(n){var t=ut[n];r.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)}}),cr(["push","reverse","sort","unshift"],function(n){var t=ut[n];
|
||||
r.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),cr(["concat","slice","splice"],function(n){var t=ut[n];r.prototype[n]=function(){return new r(t.apply(this.__wrapped__,arguments))}}),Qt&&cr(["pop","shift","splice"],function(n){var t=ut[n],e="splice"==n;r.prototype[n]=function(){var n=this.__wrapped__,u=t.apply(n,arguments);return 0===n.length&&delete n[0],e?new r(u):u}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=r,define(function(){return r
|
||||
})):Y?Z?(Z.exports=r)._=r:Y._=r:n._=r})(this);
|
||||
4983
dist/lodash.js
vendored
Normal file
4983
dist/lodash.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
41
dist/lodash.min.js
vendored
Normal file
41
dist/lodash.min.js
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @license
|
||||
* Lo-Dash 1.0.2 (Custom Build) lodash.com/license
|
||||
* Build: `lodash modern -o ./dist/lodash.js`
|
||||
* Underscore.js 1.4.4 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(n,r){function t(n){return n&&"object"==typeof n&&n.__wrapped__?n:this instanceof t?(this.__wrapped__=n,r):new t(n)}function e(n,r,t){r||(r=0);var e=n.length,u=e-r>=(t||ut);if(u)for(var a={},o=r-1;++o<e;){var i=n[o]+"";(wt.call(a,i)?a[i]:a[i]=[]).push(n[o])}return function(t){if(u){var e=t+"";return wt.call(a,e)&&sr(a[e],t)>-1}return sr(n,t,r)>-1}}function u(n){return n.charCodeAt(0)}function a(n,r){var t=n.index,e=r.index;if(n=n.criteria,r=r.criteria,n!==r){if(n>r||"undefined"==typeof n)return 1;
|
||||
if(n<r||"undefined"==typeof r)return-1}return t<e?-1:1}function o(n,r,t,e){function u(){var f=arguments,l=o?this:r;if(a||(n=r[i]),t.length&&(f=f.length?(f=p(f),e?f.concat(t):t.concat(f)):t),this instanceof u){s.prototype=n.prototype,l=new s,s.prototype=null;var c=n.apply(l,f);return S(c)?c:l}return n.apply(l,f)}var a=E(n),o=!t,i=r;return o&&(t=r),a||(r=n),u}function i(n,r,t){if(null==n)return Br;var e=typeof n;if("function"!=e){if("object"!=e)return function(r){return r[n]};var u=ue(n);return function(r){for(var t=u.length,e=!1;t--&&(e=O(r[u[t]],n[u[t]],et)););return e
|
||||
}}return"undefined"!=typeof r?1===t?function(t){return n.call(r,t)}:2===t?function(t,e){return n.call(r,t,e)}:4===t?function(t,e,u,a){return n.call(r,t,e,u,a)}:function(t,e,u){return n.call(r,t,e,u)}:n}function f(){for(var n,r={isKeysFast:Ut,arrays:"isArray(iterable)",bottom:"",loop:"",top:"",useHas:!0},t=0;n=arguments[t];t++)for(var e in n)r[e]=n[e];var u=r.args;r.firstArg=/^[^,]+/.exec(u)[0];var a=Function("createCallback, hasOwnProperty, isArguments, isArray, isString, objectTypes, nativeKeys","return function("+u+") {\n"+Wt(r)+"\n}");
|
||||
return a(i,wt,v,ee,N,Jt,St)}function l(n){return"\\"+Qt[n]}function c(n){return ae[n]}function s(){}function p(n,r,t){r||(r=0),"undefined"==typeof t&&(t=n?n.length:0);for(var e=-1,u=t-r||0,a=Array(u<0?0:u);++e<u;)a[e]=n[r+e];return a}function g(n){return oe[n]}function v(n){return At.call(n)==Ft}function y(n){var r=!1;if(!n||"object"!=typeof n||v(n))return r;var t=n.constructor;return!E(t)||t instanceof t?(re(n,function(n,t){r=t}),r===!1||wt.call(n,r)):r}function h(n){var r=[];return te(n,function(n,t){r.push(t)
|
||||
}),r}function d(n,t,e,u,a,o){var f=n;if("function"==typeof t&&(u=e,e=t,t=!1),"function"==typeof e){e="undefined"==typeof u?e:i(e,u,1),f=e(f);var l="undefined"!=typeof f;l||(f=n)}var c=S(f);if(c){var s=At.call(f);if(!Vt[s])return f;var g=ee(f)}if(!c||!t)return c&&!l?g?p(f):ie({},f):f;var v=Gt[s];switch(s){case $t:case Pt:return l?f:new v(+f);case qt:case Ct:return l?f:new v(f);case Ht:return l?f:v(f.source,ct.exec(f))}a||(a=[]),o||(o=[]);for(var y=a.length;y--;)if(a[y]==n)return o[y];return l||(f=g?v(f.length):{},g&&(wt.call(n,"index")&&(f.index=n.index),wt.call(n,"input")&&(f.input=n.input))),a.push(n),o.push(f),(g?G:te)(l?f:n,function(n,u){f[u]=d(n,t,e,r,a,o)
|
||||
}),f}function m(n,r,t){return d(n,!0,r,t)}function b(n){var r=[];return re(n,function(n,t){E(n)&&r.push(t)}),r.sort()}function _(n,r){return n?wt.call(n,r):!1}function x(n){for(var r=-1,t=ue(n),e=t.length,u={};++r<e;){var a=t[r];u[n[a]]=a}return u}function w(n){return n===!0||n===!1||At.call(n)==$t}function j(n){return n instanceof Date||At.call(n)==Pt}function A(n){return n?1===n.nodeType:!1}function k(n){var r=!0;if(!n)return r;var t=At.call(n),e=n.length;return t==Nt||t==Ct||t==Ft||t==Bt&&"number"==typeof e&&E(n.splice)?!e:(te(n,function(){return r=!1
|
||||
}),r)}function O(n,t,e,u,a,o){var f=e===et;if(e&&!f){e="undefined"==typeof u?e:i(e,u,2);var l=e(n,t);if("undefined"!=typeof l)return!!l}if(n===t)return 0!==n||1/n==1/t;var c=typeof n,s=typeof t;if(n===n&&(!n||"function"!=c&&"object"!=c)&&(!t||"function"!=s&&"object"!=s))return!1;if(null==n||null==t)return n===t;var p=At.call(n),g=At.call(t);if(p==Ft&&(p=Bt),g==Ft&&(g=Bt),p!=g)return!1;switch(p){case $t:case Pt:return+n==+t;case qt:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case Ht:case Ct:return n==t+""
|
||||
}var v=p==Nt;if(!v){if(n.__wrapped__||t.__wrapped__)return O(n.__wrapped__||n,t.__wrapped__||t,e,u,a,o);if(p!=Bt)return!1;var y=n.constructor,h=t.constructor;if(y!=h&&!(E(y)&&y instanceof y&&E(h)&&h instanceof h))return!1}a||(a=[]),o||(o=[]);for(var d=a.length;d--;)if(a[d]==n)return o[d]==t;var m=0;if(l=!0,a.push(n),o.push(t),v){if(d=n.length,m=t.length,l=m==n.length,!l&&!f)return l;for(;m--;){var b=d,_=t[m];if(f)for(;b--&&!(l=O(n[b],_,e,u,a,o)););else if(!(l=O(n[m],_,e,u,a,o)))break}return l}return re(t,function(t,i,f){return wt.call(f,i)?(m++,l=wt.call(n,i)&&O(n[i],t,e,u,a,o)):r
|
||||
}),l&&!f&&re(n,function(n,t,e){return wt.call(e,t)?l=--m>-1:r}),l}function I(n){return It(n)&&!Et(parseFloat(n))}function E(n){return"function"==typeof n}function S(n){return n?Jt[typeof n]:!1}function L(n){return T(n)&&n!=+n}function R(n){return null===n}function T(n){return"number"==typeof n||At.call(n)==qt}function F(n){return n instanceof RegExp||At.call(n)==Ht}function N(n){return"string"==typeof n||At.call(n)==Ct}function $(n){return"undefined"==typeof n}function P(n,r,t){var e=arguments,u=0,a=2;
|
||||
if(!S(n))return n;if(t===et)var o=e[3],f=e[4],l=e[5];else f=[],l=[],"number"!=typeof t&&(a=e.length),a>3&&"function"==typeof e[a-2]?o=i(e[--a-1],e[a--],2):a>2&&"function"==typeof e[a-1]&&(o=e[--a]);for(;++u<a;)(ee(e[u])?G:te)(e[u],function(r,t){var e,u,a=r,i=n[t];if(r&&((u=ee(r))||le(r))){for(var c=f.length;c--;)if(e=f[c]==r){i=l[c];break}e||(i=u?ee(i)?i:[]:le(i)?i:{},o&&(a=o(i,r),"undefined"!=typeof a&&(i=a)),f.push(r),l.push(i),o||(i=P(i,r,et,o,f,l)))}else o&&(a=o(i,r),"undefined"==typeof a&&(a=r)),"undefined"!=typeof a&&(i=a);
|
||||
n[t]=i});return n}function D(n,r,t){var e="function"==typeof r,u={};if(e)r=i(r,t);else var a=bt.apply(nt,arguments);return re(n,function(n,t,o){(e?!r(n,t,o):sr(a,t,1)<0)&&(u[t]=n)}),u}function q(n){for(var r=-1,t=ue(n),e=t.length,u=Array(e);++r<e;){var a=t[r];u[r]=[a,n[a]]}return u}function B(n,r,t){var e={};if("function"!=typeof r)for(var u=0,a=bt.apply(nt,arguments),o=S(n)?a.length:0;++u<o;){var f=a[u];f in n&&(e[f]=n[f])}else r=i(r,t),re(n,function(n,t,u){r(n,t,u)&&(e[t]=n)});return e}function H(n){for(var r=-1,t=ue(n),e=t.length,u=Array(e);++r<e;)u[r]=n[t[r]];
|
||||
return u}function C(n){for(var r=-1,t=bt.apply(nt,p(arguments,1)),e=t.length,u=Array(e);++r<e;)u[r]=n[t[r]];return u}function K(n,t,e){var u=-1,a=n?n.length:0,o=!1;return e=(e<0?Lt(0,a+e):e)||0,"number"==typeof a?o=(N(n)?n.indexOf(t,e):sr(n,t,e))>-1:ne(n,function(n){return++u<e?r:!(o=n===t)}),o}function M(n,r,t){var e={};return r=i(r,t),G(n,function(n,t,u){t=r(n,t,u)+"",wt.call(e,t)?e[t]++:e[t]=1}),e}function z(n,r,t){var e=!0;if(r=i(r,t),ee(n))for(var u=-1,a=n.length;++u<a&&(e=!!r(n[u],u,n)););else ne(n,function(n,t,u){return e=!!r(n,t,u)
|
||||
});return e}function U(n,r,t){var e=[];if(r=i(r,t),ee(n))for(var u=-1,a=n.length;++u<a;){var o=n[u];r(o,u,n)&&e.push(o)}else ne(n,function(n,t,u){r(n,t,u)&&e.push(n)});return e}function V(n,t,e){var u;return t=i(t,e),G(n,function(n,e,a){return t(n,e,a)?(u=n,!1):r}),u}function G(n,r,t){if(r&&"undefined"==typeof t&&ee(n))for(var e=-1,u=n.length;++e<u&&r(n[e],e,n)!==!1;);else ne(n,r,t);return n}function J(n,r,t){var e={};return r=i(r,t),G(n,function(n,t,u){t=r(n,t,u)+"",(wt.call(e,t)?e[t]:e[t]=[]).push(n)
|
||||
}),e}function Q(n,r){var t=p(arguments,2),e=-1,u="function"==typeof r,a=n?n.length:0,o=Array("number"==typeof a?a:0);return G(n,function(n){o[++e]=(u?r:n[r]).apply(n,t)}),o}function W(n,r,t){var e=-1,u=n?n.length:0,a=Array("number"==typeof u?u:0);if(r=i(r,t),ee(n))for(;++e<u;)a[e]=r(n[e],e,n);else ne(n,function(n,t,u){a[++e]=r(n,t,u)});return a}function X(n,r,t){var e=-1/0,a=e;if(!r&&ee(n))for(var o=-1,f=n.length;++o<f;){var l=n[o];l>a&&(a=l)}else r=!r&&N(n)?u:i(r,t),ne(n,function(n,t,u){var o=r(n,t,u);
|
||||
o>e&&(e=o,a=n)});return a}function Y(n,r,t){var e=1/0,a=e;if(!r&&ee(n))for(var o=-1,f=n.length;++o<f;){var l=n[o];l<a&&(a=l)}else r=!r&&N(n)?u:i(r,t),ne(n,function(n,t,u){var o=r(n,t,u);o<e&&(e=o,a=n)});return a}function Z(n,r,t,e){var u=arguments.length<3;if(r=i(r,e,4),ee(n)){var a=-1,o=n.length;for(u&&(t=n[++a]);++a<o;)t=r(t,n[a],a,n)}else ne(n,function(n,e,a){t=u?(u=!1,n):r(t,n,e,a)});return t}function nr(n,r,t,e){var u=n,a=n?n.length:0,o=arguments.length<3;if("number"!=typeof a){var f=ue(n);a=f.length
|
||||
}return r=i(r,e,4),G(n,function(n,e,i){e=f?f[--a]:--a,t=o?(o=!1,u[e]):r(t,u[e],e,i)}),t}function rr(n,r,t){return r=i(r,t),U(n,function(n,t,e){return!r(n,t,e)})}function tr(n){var r=-1,t=n?n.length:0,e=Array("number"==typeof t?t:0);return G(n,function(n){var t=_t(Tt()*(++r+1));e[r]=e[t],e[t]=n}),e}function er(n){var r=n?n.length:0;return"number"==typeof r?r:ue(n).length}function ur(n,r,t){var e;if(r=i(r,t),ee(n))for(var u=-1,a=n.length;++u<a&&!(e=r(n[u],u,n)););else ne(n,function(n,t,u){return!(e=r(n,t,u))
|
||||
});return!!e}function ar(n,r,t){var e=-1,u=n?n.length:0,o=Array("number"==typeof u?u:0);for(r=i(r,t),G(n,function(n,t,u){o[++e]={criteria:r(n,t,u),index:e,value:n}}),u=o.length,o.sort(a);u--;)o[u]=o[u].value;return o}function or(n){return n&&"number"==typeof n.length?p(n):H(n)}function ir(n){for(var r=-1,t=n?n.length:0,e=[];++r<t;){var u=n[r];u&&e.push(u)}return e}function fr(n){for(var r=-1,t=n?n.length:0,u=bt.apply(nt,arguments),a=e(u,t),o=[];++r<t;){var i=n[r];a(i)||o.push(i)}return o}function lr(n,r,t){if(n){var e=0,u=n.length;
|
||||
if("number"!=typeof r&&null!=r){var a=-1;for(r=i(r,t);++a<u&&r(n[a],a,n);)e++}else if(e=r,null==e||t)return n[0];return p(n,0,Rt(Lt(0,e),u))}}function cr(n,r){for(var t=-1,e=n?n.length:0,u=[];++t<e;){var a=n[t];ee(a)?jt.apply(u,r?a:cr(a)):u.push(a)}return u}function sr(n,r,t){var e=-1,u=n?n.length:0;if("number"==typeof t)e=(t<0?Lt(0,u+t):t||0)-1;else if(t)return e=br(n,r),n[e]===r?e:-1;for(;++e<u;)if(n[e]===r)return e;return-1}function pr(n,r,t){if(!n)return[];var e=0,u=n.length;if("number"!=typeof r&&null!=r){var a=u;
|
||||
for(r=i(r,t);a--&&r(n[a],a,n);)e++}else e=null==r||t?1:r||e;return p(n,0,Rt(Lt(0,u-e),u))}function gr(n){var r=arguments,t=r.length,u={0:{}},a=-1,o=n?n.length:0,i=o>=100,f=[],l=f;n:for(;++a<o;){var c=n[a];if(i)var s=c+"",p=wt.call(u[0],s)?!(l=u[0][s]):l=u[0][s]=[];if(p||sr(l,c)<0){i&&l.push(c);for(var g=t;--g;)if(!(u[g]||(u[g]=e(r[g],0,100)))(c))continue n;f.push(c)}}return f}function vr(n,r,t){if(n){var e=0,u=n.length;if("number"!=typeof r&&null!=r){var a=u;for(r=i(r,t);a--&&r(n[a],a,n);)e++}else if(e=r,null==e||t)return n[u-1];
|
||||
return p(n,Lt(0,u-e))}}function yr(n,r,t){var e=n?n.length:0;for("number"==typeof t&&(e=(t<0?Lt(0,e+t):Rt(t,e-1))+1);e--;)if(n[e]===r)return e;return-1}function hr(n,r){for(var t=-1,e=n?n.length:0,u={};++t<e;){var a=n[t];r?u[a]=r[t]:u[a[0]]=a[1]}return u}function dr(n,r,t){n=+n||0,t=+t||1,null==r&&(r=n,n=0);for(var e=-1,u=Lt(0,mt((r-n)/t)),a=Array(u);++e<u;)a[e]=n,n+=t;return a}function mr(n,r,t){if("number"!=typeof r&&null!=r){var e=0,u=-1,a=n?n.length:0;for(r=i(r,t);++u<a&&r(n[u],u,n);)e++}else e=null==r||t?1:Lt(0,r);
|
||||
return p(n,e)}function br(n,r,t,e){var u=0,a=n?n.length:u;for(t=t?i(t,e,1):Br,r=t(r);u<a;){var o=u+a>>>1;t(n[o])<r?u=o+1:a=o}return u}function _r(){return xr(bt.apply(nt,arguments))}function xr(n,r,t,e){var u=-1,a=n?n.length:0,o=[],f=o;"function"==typeof r&&(e=t,t=r,r=!1);var l=!r&&a>=75;if(l)var c={};for(t&&(f=[],t=i(t,e));++u<a;){var s=n[u],p=t?t(s,u,n):s;if(l)var g=p+"",v=wt.call(c,g)?!(f=c[g]):f=c[g]=[];(r?!u||f[f.length-1]!==p:v||sr(f,p)<0)&&((t||l)&&f.push(p),o.push(s))}return o}function wr(n){for(var r=-1,t=n?n.length:0,u=e(arguments,1),a=[];++r<t;){var o=n[r];
|
||||
u(o)||a.push(o)}return a}function jr(n){for(var r=-1,t=n?X(ce(arguments,"length")):0,e=Array(t);++r<t;)e[r]=ce(arguments,r);return e}function Ar(n,t){return n<1?t():function(){return--n<1?t.apply(this,arguments):r}}function kr(n,r){return zt||kt&&arguments.length>2?kt.call.apply(kt,arguments):o(n,r,p(arguments,2))}function Or(n){for(var r=bt.apply(nt,arguments),t=r.length>1?0:(r=b(n),-1),e=r.length;++t<e;){var u=r[t];n[u]=kr(n[u],n)}return n}function Ir(n,r){return o(n,r,p(arguments,2))}function Er(){var n=arguments;
|
||||
return function(){for(var r=arguments,t=n.length;t--;)r=[n[t].apply(this,r)];return r[0]}}function Sr(n,r,t){function e(){i=null,t||(a=n.apply(o,u))}var u,a,o,i;return function(){var f=t&&!i;return u=arguments,o=this,clearTimeout(i),i=setTimeout(e,r),f&&(a=n.apply(o,u)),a}}function Lr(n,t){var e=p(arguments,2);return setTimeout(function(){n.apply(r,e)},t)}function Rr(n){var t=p(arguments,1);return setTimeout(function(){n.apply(r,t)},1)}function Tr(n,r){var t={};return function(){var e=(r?r.apply(this,arguments):arguments[0])+"";
|
||||
return wt.call(t,e)?t[e]:t[e]=n.apply(this,arguments)}}function Fr(n){var r,t;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}}function Nr(n){return o(n,p(arguments,1))}function $r(n){return o(n,p(arguments,1),null,et)}function Pr(n,r){function t(){i=new Date,o=null,u=n.apply(a,e)}var e,u,a,o,i=0;return function(){var f=new Date,l=r-(f-i);return e=arguments,a=this,l>0?o||(o=setTimeout(t,l)):(clearTimeout(o),o=null,i=f,u=n.apply(a,e)),u}}function Dr(n,r){return function(){var t=[n];
|
||||
return jt.apply(t,arguments),r.apply(this,t)}}function qr(n){return null==n?"":(n+"").replace(yt,c)}function Br(n){return n}function Hr(n){G(b(n),function(r){var e=t[r]=n[r];t.prototype[r]=function(){var n=[this.__wrapped__];return jt.apply(n,arguments),new t(e.apply(t,n))}})}function Cr(){return n._=at,this}function Kr(n,r){return null==n&&null==r&&(r=1),n=+n||0,null==r&&(r=n,n=0),n+_t(Tt()*((+r||0)-n+1))}function Mr(n,t){var e=n?n[t]:r;return E(e)?n[t]():e}function zr(n,e,u){var a=t.templateSettings;
|
||||
n||(n=""),u=fe({},u,a);var o,i=fe({},u.imports,a.imports),f=ue(i),c=H(i),s=0,p=u.interpolate||vt,g="__p += '",v=RegExp((u.escape||vt).source+"|"+p.source+"|"+(p===gt?pt:vt).source+"|"+(u.evaluate||vt).source+"|$","g");n.replace(v,function(r,t,e,u,a,i){return e||(e=u),g+=n.slice(s,i).replace(ht,l),t&&(g+="' +\n__e("+t+") +\n'"),a&&(o=!0,g+="';\n"+a+";\n__p += '"),e&&(g+="' +\n((__t = ("+e+")) == null ? '' : __t) +\n'"),s=i+r.length,r}),g+="';\n";var y=u.variable,h=y;h||(y="obj",g="with ("+y+") {\n"+g+"\n}\n"),g=(o?g.replace(it,""):g).replace(ft,"$1").replace(lt,"$1;"),g="function("+y+") {\n"+(h?"":y+" || ("+y+" = {});\n")+"var __t, __p = '', __e = _.escape"+(o?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+g+"return __p\n}";
|
||||
var d="\n/*\n//@ sourceURL="+(u.sourceURL||"/lodash/template/source["+dt++ +"]")+"\n*/";try{var m=Function(f,"return "+g+d).apply(r,c)}catch(b){throw b.source=g,b}return e?m(e):(m.source=g,m)}function Ur(n,r,t){n=+n||0;for(var e=-1,u=Array(n);++e<n;)u[e]=r.call(t,e);return u}function Vr(n){return null==n?"":(n+"").replace(ot,g)}function Gr(n){var r=++tt;return(null==n?"":n+"")+r}function Jr(n,r){return r(n),n}function Qr(){return this.__wrapped__+""}function Wr(){return this.__wrapped__}var Xr="object"==typeof exports&&exports,Yr="object"==typeof module&&module&&module.exports==Xr&&module,Zr="object"==typeof global&&global;
|
||||
Zr.global===Zr&&(n=Zr);var nt=[],rt={},tt=0,et=rt,ut=30,at=n._,ot=/&(?:amp|lt|gt|quot|#39);/g,it=/\b__p \+= '';/g,ft=/\b(__p \+=) '' \+/g,lt=/(__e\(.*?\)|\b__t\)) \+\n'';/g,ct=/\w*$/,st=RegExp("^"+(rt.valueOf+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),pt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,gt=/<%=([\s\S]+?)%>/g,vt=/($^)/,yt=/[&<>"']/g,ht=/['\n\r\t\u2028\u2029\\]/g,dt=0,mt=Math.ceil,bt=nt.concat,_t=Math.floor,xt=st.test(xt=Object.getPrototypeOf)&&xt,wt=rt.hasOwnProperty,jt=nt.push,At=rt.toString,kt=st.test(kt=p.bind)&&kt,Ot=st.test(Ot=Array.isArray)&&Ot,It=n.isFinite,Et=n.isNaN,St=st.test(St=Object.keys)&&St,Lt=Math.max,Rt=Math.min,Tt=Math.random,Ft="[object Arguments]",Nt="[object Array]",$t="[object Boolean]",Pt="[object Date]",Dt="[object Function]",qt="[object Number]",Bt="[object Object]",Ht="[object RegExp]",Ct="[object String]",Kt=!!n.attachEvent,Mt=kt&&!/\n|true/.test(kt+Kt),zt=kt&&!Mt,Ut=St&&(Kt||Mt),Vt={};
|
||||
Vt[Dt]=!1,Vt[Ft]=Vt[Nt]=Vt[$t]=Vt[Pt]=Vt[qt]=Vt[Bt]=Vt[Ht]=Vt[Ct]=!0;var Gt={};Gt[Nt]=Array,Gt[$t]=Boolean,Gt[Pt]=Date,Gt[Bt]=Object,Gt[qt]=Number,Gt[Ht]=RegExp,Gt[Ct]=String;var Jt={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},Qt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};t.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:gt,variable:"",imports:{_:t}};var Wt=function(n){var r="var index, iterable = "+n.firstArg+", result = iterable;\nif (!iterable) return result;\n"+n.top+";\n";
|
||||
return n.arrays&&(r+="var length = iterable.length; index = -1;\nif ("+n.arrays+") {\n while (++index < length) {\n "+n.loop+"\n }\n}\nelse { "),n.isKeysFast&&n.useHas?r+="\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n "+n.loop+"\n } ":(r+="\n for (index in iterable) {",n.useHas&&(r+="\n if (",n.useHas&&(r+="hasOwnProperty.call(iterable, index)"),r+=") { "),r+=n.loop+"; ",n.useHas&&(r+="\n }"),r+="\n } "),n.arrays&&(r+="\n}"),r+=n.bottom+";\nreturn result"
|
||||
},Xt={args:"object, source, guard",top:"var args = arguments,\n argsIndex = 0,\n argsLength = typeof guard == 'number' ? 2 : args.length;\nwhile (++argsIndex < argsLength) {\n iterable = args[argsIndex];\n if (iterable && objectTypes[typeof iterable]) {",loop:"if (typeof result[index] == 'undefined') result[index] = iterable[index]",bottom:" }\n}"},Yt={args:"collection, callback, thisArg",top:"callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",arrays:"typeof length == 'number'",loop:"if (callback(iterable[index], index, collection) === false) return result"},Zt={top:"if (!objectTypes[typeof iterable]) return result;\n"+Yt.top,arrays:!1},ne=f(Yt),re=f(Yt,Zt,{useHas:!1}),te=f(Yt,Zt),ee=Ot||function(n){return n instanceof Array||At.call(n)==Nt
|
||||
},ue=St?function(n){return S(n)?St(n):[]}:h,ae={"&":"&","<":"<",">":">",'"':""","'":"'"},oe=x(ae),ie=f(Xt,{top:Xt.top.replace(";",";\nif (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n callback = args[--argsLength];\n}"),loop:"result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]"}),fe=f(Xt);
|
||||
E(/x/)&&(E=function(n){return n instanceof Function||At.call(n)==Dt});var le=xt?function(n){if(!n||"object"!=typeof n)return!1;var r=n.valueOf,t="function"==typeof r&&(t=xt(r))&&xt(t);return t?n==t||xt(n)==t&&!v(n):y(n)}:y,ce=W,se=U;Mt&&Yr&&"function"==typeof setImmediate&&(Rr=kr(setImmediate,n)),t.after=Ar,t.assign=ie,t.at=C,t.bind=kr,t.bindAll=Or,t.bindKey=Ir,t.compact=ir,t.compose=Er,t.countBy=M,t.debounce=Sr,t.defaults=fe,t.defer=Rr,t.delay=Lr,t.difference=fr,t.filter=U,t.flatten=cr,t.forEach=G,t.forIn=re,t.forOwn=te,t.functions=b,t.groupBy=J,t.initial=pr,t.intersection=gr,t.invert=x,t.invoke=Q,t.keys=ue,t.map=W,t.max=X,t.memoize=Tr,t.merge=P,t.min=Y,t.object=hr,t.omit=D,t.once=Fr,t.pairs=q,t.partial=Nr,t.partialRight=$r,t.pick=B,t.pluck=ce,t.range=dr,t.reject=rr,t.rest=mr,t.shuffle=tr,t.sortBy=ar,t.tap=Jr,t.throttle=Pr,t.times=Ur,t.toArray=or,t.union=_r,t.uniq=xr,t.values=H,t.where=se,t.without=wr,t.wrap=Dr,t.zip=jr,t.collect=W,t.drop=mr,t.each=G,t.extend=ie,t.methods=b,t.select=U,t.tail=mr,t.unique=xr,Hr(t),t.clone=d,t.cloneDeep=m,t.contains=K,t.escape=qr,t.every=z,t.find=V,t.has=_,t.identity=Br,t.indexOf=sr,t.isArguments=v,t.isArray=ee,t.isBoolean=w,t.isDate=j,t.isElement=A,t.isEmpty=k,t.isEqual=O,t.isFinite=I,t.isFunction=E,t.isNaN=L,t.isNull=R,t.isNumber=T,t.isObject=S,t.isPlainObject=le,t.isRegExp=F,t.isString=N,t.isUndefined=$,t.lastIndexOf=yr,t.mixin=Hr,t.noConflict=Cr,t.random=Kr,t.reduce=Z,t.reduceRight=nr,t.result=Mr,t.size=er,t.some=ur,t.sortedIndex=br,t.template=zr,t.unescape=Vr,t.uniqueId=Gr,t.all=z,t.any=ur,t.detect=V,t.foldl=Z,t.foldr=nr,t.include=K,t.inject=Z,te(t,function(n,r){t.prototype[r]||(t.prototype[r]=function(){var r=[this.__wrapped__];
|
||||
return jt.apply(r,arguments),n.apply(t,r)})}),t.first=lr,t.last=vr,t.take=lr,t.head=lr,te(t,function(n,r){t.prototype[r]||(t.prototype[r]=function(r,e){var u=n(this.__wrapped__,r,e);return null==r||e&&"function"!=typeof r?u:new t(u)})}),t.VERSION="1.0.2",t.prototype.toString=Qr,t.prototype.value=Wr,t.prototype.valueOf=Wr,ne(["join","pop","shift"],function(n){var r=nt[n];t.prototype[n]=function(){return r.apply(this.__wrapped__,arguments)}}),ne(["push","reverse","sort","unshift"],function(n){var r=nt[n];
|
||||
t.prototype[n]=function(){return r.apply(this.__wrapped__,arguments),this}}),ne(["concat","slice","splice"],function(n){var r=nt[n];t.prototype[n]=function(){return new t(r.apply(this.__wrapped__,arguments))}}),"function"==typeof define&&"object"==typeof define.amd&&define.amd?(n._=t,define(function(){return t})):Xr?Yr?(Yr.exports=t)._=t:Xr._=t:n._=t})(this);
|
||||
1585
lodash.underscore.js → dist/lodash.underscore.js
vendored
1585
lodash.underscore.js → dist/lodash.underscore.js
vendored
File diff suppressed because it is too large
Load Diff
34
dist/lodash.underscore.min.js
vendored
Normal file
34
dist/lodash.underscore.min.js
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @license
|
||||
* Lo-Dash 1.0.2 (Custom Build) lodash.com/license
|
||||
* Build: `lodash underscore -o ./dist/lodash.underscore.js`
|
||||
* Underscore.js 1.4.4 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(n,t){function r(n,t){var r;if(n&&qt[typeof n])for(r in t||(t=G),n)if(t(n[r],r,n)===tt)break}function e(n,t,r){if(n){t=t&&typeof r=="undefined"?t:a(t,r);var e=n.length;if(r=-1,typeof e=="number")for(;++r<e&&t(n[r],r,n)!==tt;);else for(r in n)if(pt.call(n,r)&&t(n[r],r,n)===tt)break}}function u(n){return n&&typeof n=="object"&&n.__wrapped__?n:this instanceof u?(this.__wrapped__=n,void 0):new u(n)}function o(n,t){var r=n.b,e=t.b;if(n=n.a,t=t.a,n!==t){if(n>t||typeof n=="undefined")return 1;if(n<t||typeof t=="undefined")return-1
|
||||
}return r<e?-1:1}function i(n,t,r){function e(){var a=arguments,f=o?this:t;return u||(n=t[i]),r.length&&(a=a.length?(a=p(a),r.concat(a)):r),this instanceof e?(l.prototype=n.prototype,f=new l,l.prototype=K,a=n.apply(f,a),w(a)?a:f):n.apply(f,a)}var u=j(n),o=!r,i=t;return o&&(r=t),u||(t=n),e}function a(n,t,r){if(n==K)return G;var e=typeof n;if("function"!=e){if("object"!=e)return function(t){return t[n]};var u=Dt(n);return function(t){for(var r=u.length,e=L;r--&&(e=t[u[r]]===n[u[r]]););return e}}return typeof t!="undefined"?1===r?function(r){return n.call(t,r)
|
||||
}:2===r?function(r,e){return n.call(t,r,e)}:4===r?function(r,e,u,o){return n.call(t,r,e,u,o)}:function(r,e,u){return n.call(t,r,e,u)}:n}function f(n){return"\\"+It[n]}function c(n){return Mt[n]}function l(){}function p(n,t,r){t||(t=0),typeof r=="undefined"&&(r=n?n.length:0);var e=-1;r=r-t||0;for(var u=Array(0>r?0:r);++e<r;)u[e]=n[t+e];return u}function s(n){return $t[n]}function v(n){return vt.call(n)==wt}function h(n){var t,r=[],e=function(n,t){r.push(t)};if(n&&qt[typeof n])for(t in e||(e=G),n)if(pt.call(n,t)&&e(n[t],t,n)===tt)break;
|
||||
return r}function g(n){if(!n)return n;for(var t=1,r=arguments.length;t<r;t++){var e=arguments[t];if(e)for(var u in e)n[u]=e[u]}return n}function y(n){if(!n)return n;for(var t=1,r=arguments.length;t<r;t++){var e=arguments[t];if(e)for(var u in e)n[u]==K&&(n[u]=e[u])}return n}function m(n){var t=[];return r(n,function(n,r){j(n)&&t.push(r)}),t.sort()}function _(n){for(var t=-1,r=Dt(n),e=r.length,u={};++t<e;){var o=r[t];u[n[o]]=o}return u}function d(n){if(!n)return J;if(Bt(n)||x(n))return!n.length;for(var t in n)if(pt.call(n,t))return L;
|
||||
return J}function b(n,t,e,u){if(n===t)return 0!==n||1/n==1/t;var o=typeof n,i=typeof t;if(n===n&&(!n||"function"!=o&&"object"!=o)&&(!t||"function"!=i&&"object"!=i))return L;if(n==K||t==K)return n===t;if(i=vt.call(n),o=vt.call(t),i!=o)return L;switch(i){case xt:case Et:return+n==+t;case Ot:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case Nt:case kt:return n==t+""}if(o=i==At,!o){if(n.__wrapped__||t.__wrapped__)return b(n.__wrapped__||n,t.__wrapped__||t,e,u);if(i!=St)return L;var i=n.constructor,a=t.constructor;
|
||||
if(i!=a&&(!j(i)||!(i instanceof i&&j(a)&&a instanceof a)))return L}for(e||(e=[]),u||(u=[]),i=e.length;i--;)if(e[i]==n)return u[i]==t;var f=J,c=0;if(e.push(n),u.push(t),o){if(c=t.length,f=c==n.length)for(;c--&&(f=b(n[c],t[c],e,u)););return f}return r(t,function(t,r,o){return pt.call(o,r)?(c++,!(f=pt.call(n,r)&&b(n[r],t,e,u))&&tt):void 0}),f&&r(n,function(n,t,r){return pt.call(r,t)?!(f=-1<--c)&&tt:void 0}),f}function j(n){return typeof n=="function"}function w(n){return n?qt[typeof n]:L}function A(n){return typeof n=="number"||vt.call(n)==Ot
|
||||
}function x(n){return typeof n=="string"||vt.call(n)==kt}function E(n){for(var t=-1,r=Dt(n),e=r.length,u=Array(e);++t<e;)u[t]=n[r[t]];return u}function O(n,t){var r=L;return typeof(n?n.length:0)=="number"?r=-1<z(n,t):e(n,function(n){return(r=n===t)&&tt}),r}function S(n,t,r){var u=J;if(t=a(t,r),Bt(n)){r=-1;for(var o=n.length;++r<o&&(u=!!t(n[r],r,n)););}else e(n,function(n,r,e){return!(u=!!t(n,r,e))&&tt});return u}function N(n,t,r){var u=[];if(t=a(t,r),Bt(n)){r=-1;for(var o=n.length;++r<o;){var i=n[r];
|
||||
t(i,r,n)&&u.push(i)}}else e(n,function(n,r,e){t(n,r,e)&&u.push(n)});return u}function k(n,t,r){var e;return t=a(t,r),F(n,function(n,r,u){return t(n,r,u)?(e=n,tt):void 0}),e}function F(n,t,r){if(t&&typeof r=="undefined"&&Bt(n)){r=-1;for(var u=n.length;++r<u&&t(n[r],r,n)!==tt;);}else e(n,t,r)}function R(n,t,r){var u=-1,o=n?n.length:0,i=Array(typeof o=="number"?o:0);if(t=a(t,r),Bt(n))for(;++u<o;)i[u]=t(n[u],u,n);else e(n,function(n,r,e){i[++u]=t(n,r,e)});return i}function T(n,t,r){var u=-1/0,o=u;if(!t&&Bt(n)){r=-1;
|
||||
for(var i=n.length;++r<i;){var f=n[r];f>o&&(o=f)}}else t=a(t,r),e(n,function(n,r,e){r=t(n,r,e),r>u&&(u=r,o=n)});return o}function q(n,t,r,u){var o=3>arguments.length;if(t=a(t,u,4),Bt(n)){var i=-1,f=n.length;for(o&&(r=n[++i]);++i<f;)r=t(r,n[i],i,n)}else e(n,function(n,e,u){r=o?(o=L,n):t(r,n,e,u)});return r}function I(n,t,r,e){var u=n?n.length:0,o=3>arguments.length;if(typeof u!="number")var i=Dt(n),u=i.length;return t=a(t,e,4),F(n,function(e,a,f){a=i?i[--u]:--u,r=o?(o=L,n[a]):t(r,n[a],a,f)}),r}function B(n,t,r){var u;
|
||||
if(t=a(t,r),Bt(n)){r=-1;for(var o=n.length;++r<o&&!(u=t(n[r],r,n)););}else e(n,function(n,r,e){return(u=t(n,r,e))&&tt});return!!u}function D(n,t,r){return r&&d(t)?K:(r?k:N)(n,t)}function M(n,t,r){if(n){var e=0,u=n.length;if(typeof t!="number"&&t!=K){var o=-1;for(t=a(t,r);++o<u&&t(n[o],o,n);)e++}else if(e=t,e==K||r)return n[0];return p(n,0,bt(dt(0,e),u))}}function $(n,t){for(var r=-1,e=n?n.length:0,u=[];++r<e;){var o=n[r];Bt(o)?st.apply(u,t?o:$(o)):u.push(o)}return u}function z(n,t,r){var e=-1,u=n?n.length:0;
|
||||
if(typeof r=="number")e=(0>r?dt(0,u+r):r||0)-1;else if(r)return e=P(n,t),n[e]===t?e:-1;for(;++e<u;)if(n[e]===t)return e;return-1}function C(n,t,r){if(typeof t!="number"&&t!=K){var e=0,u=-1,o=n?n.length:0;for(t=a(t,r);++u<o&&t(n[u],u,n);)e++}else e=t==K||r?1:dt(0,t);return p(n,e)}function P(n,t,r,e){var u=0,o=n?n.length:u;for(r=r?a(r,e,1):G,t=r(t);u<o;)e=u+o>>>1,r(n[e])<t?u=e+1:o=e;return u}function U(n,t,r,e){var u=-1,o=n?n.length:0,i=[],f=i;for(typeof t=="function"&&(e=r,r=t,t=L),r&&(f=[],r=a(r,e));++u<o;){e=n[u];
|
||||
var c=r?r(e,u,n):e;(t?!u||f[f.length-1]!==c:0>z(f,c))&&(r&&f.push(c),i.push(e))}return i}function V(n,t){return Ft||ht&&2<arguments.length?ht.call.apply(ht,arguments):i(n,t,p(arguments,2))}function W(n){var r=p(arguments,1);return setTimeout(function(){n.apply(t,r)},1)}function G(n){return n}function H(n){F(m(n),function(t){var r=u[t]=n[t];u.prototype[t]=function(){var n=[this.__wrapped__];return st.apply(n,arguments),n=r.apply(u,n),this.__chain__&&(n=new u(n),n.__chain__=J),n}})}var J=!0,K=null,L=!1,Q=typeof exports=="object"&&exports,X=typeof module=="object"&&module&&module.exports==Q&&module,Y=typeof global=="object"&&global;
|
||||
Y.global===Y&&(n=Y);var Z=[],Y={},nt=0,tt=Y,rt=n._,et=/&(?:amp|lt|gt|quot|#39);/g,ut=RegExp("^"+(Y.valueOf+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),ot=/($^)/,it=/[&<>"']/g,at=/['\n\r\t\u2028\u2029\\]/g,ft=Math.ceil,ct=Z.concat,lt=Math.floor,pt=Y.hasOwnProperty,st=Z.push,vt=Y.toString,ht=ut.test(ht=p.bind)&&ht,gt=ut.test(gt=Array.isArray)&>,yt=n.isFinite,mt=n.isNaN,_t=ut.test(_t=Object.keys)&&_t,dt=Math.max,bt=Math.min,jt=Math.random,wt="[object Arguments]",At="[object Array]",xt="[object Boolean]",Et="[object Date]",Ot="[object Number]",St="[object Object]",Nt="[object RegExp]",kt="[object String]",Y=!!n.attachEvent,Y=ht&&!/\n|true/.test(ht+Y),Ft=ht&&!Y,Rt=(Rt={0:1,length:1},Z.splice.call(Rt,0,1),Rt[0]),Tt=arguments.constructor==Object,qt={"boolean":L,"function":J,object:J,number:L,string:L,undefined:L},It={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};
|
||||
u.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},v(arguments)||(v=function(n){return n?pt.call(n,"callee"):L});var Bt=gt||function(n){return Tt&&n instanceof Array||vt.call(n)==At},Dt=_t?function(n){return w(n)?_t(n):[]}:h,Mt={"&":"&","<":"<",">":">",'"':""","'":"'"},$t=_(Mt);j(/x/)&&(j=function(n){return n instanceof Function||"[object Function]"==vt.call(n)});var zt=R;Y&&X&&typeof setImmediate=="function"&&(W=V(setImmediate,n)),u.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0
|
||||
}},u.bind=V,u.bindAll=function(n){for(var t=ct.apply(Z,arguments),r=1<t.length?0:(t=m(n),-1),e=t.length;++r<e;){var u=t[r];n[u]=V(n[u],n)}return n},u.compact=function(n){for(var t=-1,r=n?n.length:0,e=[];++t<r;){var u=n[t];u&&e.push(u)}return e},u.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length;r--;)t=[n[r].apply(this,t)];return t[0]}},u.countBy=function(n,t,r){var e={};return t=a(t,r),F(n,function(n,r,u){r=t(n,r,u)+"",pt.call(e,r)?e[r]++:e[r]=1}),e},u.debounce=function(n,t,r){function e(){a=K,r||(o=n.apply(i,u))
|
||||
}var u,o,i,a;return function(){var f=r&&!a;return u=arguments,i=this,clearTimeout(a),a=setTimeout(e,t),f&&(o=n.apply(i,u)),o}},u.defaults=y,u.defer=W,u.delay=function(n,r){var e=p(arguments,2);return setTimeout(function(){n.apply(t,e)},r)},u.difference=function(n){for(var t=-1,r=n.length,e=ct.apply(Z,arguments),u=[];++t<r;){var o=n[t];0>z(e,o,r)&&u.push(o)}return u},u.filter=N,u.flatten=$,u.forEach=F,u.functions=m,u.groupBy=function(n,t,r){var e={};return t=a(t,r),F(n,function(n,r,u){r=t(n,r,u)+"",(pt.call(e,r)?e[r]:e[r]=[]).push(n)
|
||||
}),e},u.initial=function(n,t,r){if(!n)return[];var e=0,u=n.length;if(typeof t!="number"&&t!=K){var o=u;for(t=a(t,r);o--&&t(n[o],o,n);)e++}else e=t==K||r?1:t||e;return p(n,0,bt(dt(0,u-e),u))},u.intersection=function(n){var t=arguments,r=t.length,e=-1,u=n?n.length:0,o=[];n:for(;++e<u;){var i=n[e];if(0>z(o,i)){for(var a=r;--a;)if(0>z(t[a],i))continue n;o.push(i)}}return o},u.invert=_,u.invoke=function(n,t){var r=p(arguments,2),e=-1,u=typeof t=="function",o=n?n.length:0,i=Array(typeof o=="number"?o:0);
|
||||
return F(n,function(n){i[++e]=(u?t:n[t]).apply(n,r)}),i},u.keys=Dt,u.map=R,u.max=T,u.memoize=function(n,t){var r={};return function(){var e=(t?t.apply(this,arguments):arguments[0])+"";return pt.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},u.min=function(n,t,r){var u=1/0,o=u;if(!t&&Bt(n)){r=-1;for(var i=n.length;++r<i;){var f=n[r];f<o&&(o=f)}}else t=a(t,r),e(n,function(n,r,e){r=t(n,r,e),r<u&&(u=r,o=n)});return o},u.object=function(n,t){for(var r=-1,e=n?n.length:0,u={};++r<e;){var o=n[r];t?u[o]=t[r]:u[o[0]]=o[1]
|
||||
}return u},u.omit=function(n){var t=ct.apply(Z,arguments),e={};return r(n,function(n,r){0>z(t,r,1)&&(e[r]=n)}),e},u.once=function(n){var t,r;return function(){return t?r:(t=J,r=n.apply(this,arguments),n=K,r)}},u.pairs=function(n){for(var t=-1,r=Dt(n),e=r.length,u=Array(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u},u.partial=function(n){return i(n,p(arguments,1))},u.pick=function(n){for(var t=0,r=ct.apply(Z,arguments),e=r.length,u={};++t<e;){var o=r[t];o in n&&(u[o]=n[o])}return u},u.pluck=zt,u.range=function(n,t,r){n=+n||0,r=+r||1,t==K&&(t=n,n=0);
|
||||
var e=-1;t=dt(0,ft((t-n)/r));for(var u=Array(t);++e<t;)u[e]=n,n+=r;return u},u.reject=function(n,t,r){return t=a(t,r),N(n,function(n,r,e){return!t(n,r,e)})},u.rest=C,u.shuffle=function(n){var t=-1,r=n?n.length:0,e=Array(typeof r=="number"?r:0);return F(n,function(n){var r=lt(jt()*(++t+1));e[t]=e[r],e[r]=n}),e},u.sortBy=function(n,t,r){var e=-1,u=n?n.length:0,i=Array(typeof u=="number"?u:0);for(t=a(t,r),F(n,function(n,r,u){i[++e]={a:t(n,r,u),b:e,c:n}}),u=i.length,i.sort(o);u--;)i[u]=i[u].c;return i
|
||||
},u.tap=function(n,t){return t(n),n},u.throttle=function(n,t){function r(){a=new Date,i=K,u=n.apply(o,e)}var e,u,o,i,a=0;return function(){var f=new Date,c=t-(f-a);return e=arguments,o=this,0<c?i||(i=setTimeout(r,c)):(clearTimeout(i),i=K,a=f,u=n.apply(o,e)),u}},u.times=function(n,t,r){n=+n||0;for(var e=-1,u=Array(n);++e<n;)u[e]=t.call(r,e);return u},u.toArray=function(n){return n&&typeof n.length=="number"?p(n):E(n)},u.union=function(){return U(ct.apply(Z,arguments))},u.uniq=U,u.values=E,u.where=D,u.without=function(n){for(var t=-1,r=n.length,e=[];++t<r;){var u=n[t];
|
||||
0>z(arguments,u,1)&&e.push(u)}return e},u.wrap=function(n,t){return function(){var r=[n];return st.apply(r,arguments),t.apply(this,r)}},u.zip=function(n){for(var t=-1,r=n?T(zt(arguments,"length")):0,e=Array(r);++t<r;)e[t]=zt(arguments,t);return e},u.collect=R,u.drop=C,u.each=F,u.extend=g,u.methods=m,u.select=N,u.tail=C,u.unique=U,u.clone=function(n){return w(n)?Bt(n)?p(n):g({},n):n},u.contains=O,u.escape=function(n){return n==K?"":(n+"").replace(it,c)},u.every=S,u.find=k,u.findWhere=function(n,t){return D(n,t,J)
|
||||
},u.has=function(n,t){return n?pt.call(n,t):L},u.identity=G,u.indexOf=z,u.isArguments=v,u.isArray=Bt,u.isBoolean=function(n){return n===J||n===L||vt.call(n)==xt},u.isDate=function(n){return n instanceof Date||vt.call(n)==Et},u.isElement=function(n){return n?1===n.nodeType:L},u.isEmpty=d,u.isEqual=b,u.isFinite=function(n){return yt(n)&&!mt(parseFloat(n))},u.isFunction=j,u.isNaN=function(n){return A(n)&&n!=+n},u.isNull=function(n){return n===K},u.isNumber=A,u.isObject=w,u.isRegExp=function(n){return n instanceof RegExp||vt.call(n)==Nt
|
||||
},u.isString=x,u.isUndefined=function(n){return typeof n=="undefined"},u.lastIndexOf=function(n,t,r){var e=n?n.length:0;for(typeof r=="number"&&(e=(0>r?dt(0,e+r):bt(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},u.mixin=H,u.noConflict=function(){return n._=rt,this},u.random=function(n,t){return n==K&&t==K&&(t=1),n=+n||0,t==K&&(t=n,n=0),n+lt(jt()*((+t||0)-n+1))},u.reduce=q,u.reduceRight=I,u.result=function(n,t){var r=n?n[t]:K;return j(r)?n[t]():r},u.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Dt(n).length
|
||||
},u.some=B,u.sortedIndex=P,u.template=function(n,t,r){n||(n=""),r=y({},r,u.templateSettings);var e=0,o="__p+='",i=r.variable;n.replace(RegExp((r.escape||ot).source+"|"+(r.interpolate||ot).source+"|"+(r.evaluate||ot).source+"|$","g"),function(t,r,u,i,a){return o+=n.slice(e,a).replace(at,f),r&&(o+="'+_['escape']("+r+")+'"),i&&(o+="';"+i+";__p+='"),u&&(o+="'+((__t=("+u+"))==null?'':__t)+'"),e=a+t.length,t}),o+="';\n",i||(i="obj",o="with("+i+"||{}){"+o+"}"),o="function("+i+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+o+"return __p}";
|
||||
try{var a=Function("_","return "+o)(u)}catch(c){throw c.source=o,c}return t?a(t):(a.source=o,a)},u.unescape=function(n){return n==K?"":(n+"").replace(et,s)},u.uniqueId=function(n){var t=++nt+"";return n?n+t:t},u.all=S,u.any=B,u.detect=k,u.foldl=q,u.foldr=I,u.include=O,u.inject=q,u.first=M,u.last=function(n,t,r){if(n){var e=0,u=n.length;if(typeof t!="number"&&t!=K){var o=u;for(t=a(t,r);o--&&t(n[o],o,n);)e++}else if(e=t,e==K||r)return n[u-1];return p(n,dt(0,u-e))}},u.take=M,u.head=M,u.chain=function(n){return n=new u(n),n.__chain__=J,n
|
||||
},u.VERSION="1.0.2",H(u),u.prototype.chain=function(){return this.__chain__=J,this},u.prototype.value=function(){return this.__wrapped__},e("pop push reverse shift sort splice unshift".split(" "),function(n){var t=Z[n];u.prototype[n]=function(){var n=this.__wrapped__;return t.apply(n,arguments),Rt&&0===n.length&&delete n[0],this}}),e(["concat","join","slice"],function(n){var t=Z[n];u.prototype[n]=function(){var n=t.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new u(n),n.__chain__=J),n
|
||||
}}),Q?X?(X.exports=u)._=u:Q._=u:n._=u})(this);
|
||||
2162
doc/README.md
2162
doc/README.md
File diff suppressed because it is too large
Load Diff
@@ -1,36 +1,38 @@
|
||||
<?php
|
||||
|
||||
// cleanup requested filepath
|
||||
$file = isset($_GET['f']) ? $_GET['f'] : 'lodash';
|
||||
$file = preg_replace('#(\.*[\/])+#', '', $file);
|
||||
$file .= preg_match('/\.[a-z]+$/', $file) ? '' : '.js';
|
||||
// cleanup requested file path
|
||||
$filePath = isset($_GET['f']) ? $_GET['f'] : 'lodash';
|
||||
$filePath = preg_replace('#(\.*[\/])+#', '', $filePath);
|
||||
$filePath .= preg_match('/\.[a-z]+$/', $filePath) ? '' : '.js';
|
||||
|
||||
// output filename
|
||||
if (isset($_GET['o'])) {
|
||||
$output = $_GET['o'];
|
||||
$outputName = $_GET['o'];
|
||||
} else if (isset($_SERVER['argv'][1])) {
|
||||
$output = $_SERVER['argv'][1];
|
||||
$outputName = $_SERVER['argv'][1];
|
||||
} else {
|
||||
$output = basename($file);
|
||||
$outputName = basename($filePath);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
require('../vendor/docdown/docdown.php');
|
||||
|
||||
// get package version
|
||||
$version = json_decode(file_get_contents('../package.json'))->version;
|
||||
|
||||
// generate Markdown
|
||||
$markdown = docdown(array(
|
||||
'path' => '../' . $file,
|
||||
'title' => 'Lo-Dash <sup>v1.0.0-rc.3</sup>',
|
||||
'path' => '../' . $filePath,
|
||||
'title' => '<a href="http://lodash.com/">Lo-Dash</a> <span>v' . $version . '</span>',
|
||||
'toc' => 'categories',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
||||
'url' => 'https://github.com/lodash/lodash/blob/' . $version . '/lodash.js'
|
||||
));
|
||||
|
||||
// save to a .md file
|
||||
file_put_contents($output . '.md', $markdown);
|
||||
// save to a `.md` file
|
||||
file_put_contents($outputName . '.md', $markdown);
|
||||
|
||||
// print
|
||||
header('Content-Type: text/plain;charset=utf-8');
|
||||
echo $markdown . PHP_EOL;
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
42
lodash.min.js
vendored
42
lodash.min.js
vendored
@@ -1,42 +0,0 @@
|
||||
/*!
|
||||
Lo-Dash 1.0.0-rc.3 lodash.com/license
|
||||
Underscore.js 1.4.3 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(e,t){function n(e){if(e&&typeof e=="object"&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||tt);if(i)for(var s={},n=t-1;++n<r;){var o=e[n]+"";(Et.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(n){if(i){var r=n+"";return Et.call(s,r)&&-1<R(s[r],n)}return-1<R(e,n,t)}}function i(e){return e.charCodeAt(0)}function s(e,t){var n=e.b,r=t.b,e=e.a,t=t.a;if(e!==t){if(e>t||typeof e=="undefined")return 1;if(
|
||||
e<t||typeof t=="undefined")return-1}return n<r?-1:1}function o(e,t,n){function r(){var u=arguments,a=s?this:t;return i||(e=t[o]),n.length&&(u=u.length?n.concat(p(u)):n),this instanceof r?(h.prototype=e.prototype,a=new h,h.prototype=null,u=e.apply(a,u),x(u)?u:a):e.apply(a,u)}var i=S(e),s=!n,o=t;return s&&(n=t),i||(t=e),r}function u(e,t,n){return e?typeof e!="function"?function(t){return t[e]}:typeof t!="undefined"?n?function(n,r,i,s){return e.call(t,n,r,i,s)}:function(n,r,i){return e.call(t,n,r,i)
|
||||
}:e:V}function a(){for(var e={b:"",c:"",e:Xt,f:Wt,g:"",h:Jt,i:Gt,j:mt,k:"",l:!0},t,n=0;t=arguments[n];n++)for(var r in t)e[r]=t[r];t=e.a,e.d=/^[^,]+/.exec(t)[0],n=Function,r="var i,l="+e.d+",t="+e.d+";if(!"+e.d+")return t;"+e.k+";",e.b?(r+="var m=l.length;i=-1;if(typeof m=='number'){",e.i&&(r+="if(k(l)){l=l.split('')}"),r+="while(++i<m){"+e.b+"}}else {"):e.h&&(r+="var m=l.length;i=-1;if(m&&j(l)){while(++i<m){i+='';"+e.g+"}}else {"),e.e||(r+="var u=typeof l=='function'&&s.call(l,'prototype');");if(
|
||||
e.f&&e.l)r+="var q=-1,r=p[typeof l]?n(l):[],m=r.length;while(++q<m){i=r[q];",e.e||(r+="if(!(u&&i=='prototype')){"),r+=e.g+"",e.e||(r+="}");else{r+="for(i in l){";if(!e.e||e.l)r+="if(",e.e||(r+="!(u&&i=='prototype')"),!e.e&&e.l&&(r+="&&"),e.l&&(r+="h.call(l,i)"),r+="){";r+=e.g+";";if(!e.e||e.l)r+="}"}r+="}";if(e.e){r+="var f=l.constructor;";for(var i=0;7>i;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t"
|
||||
,n("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(u,Et,v,N,nn,At,xt)}function f(e){return"\\"+rn[e]}function l(e){return hn[e]}function c(e){return typeof e.toString!="function"&&typeof (e+"")=="string"}function h(){}function p(e,t,n){t||(t=0),typeof n=="undefined"&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function d(e){return pn[e]}function v(e){return Tt.call(e)==Dt}function m(e){var t=!1;if(!e||typeof e!="object"||v(e))return t;var n=e.constructor;return!
|
||||
S(n)&&(!Yt||!c(e))||n instanceof n?Vt?(ln(e,function(e,n,r){return t=!Et.call(r,n),!1}),!1===t):(ln(e,function(e,n){t=n}),!1===t||Et.call(e,t)):t}function g(e){var t=[];return cn(e,function(e,n){t.push(n)}),t}function y(e,t,n,r,i){if(null==e)return e;n&&(t=!1);if(n=x(e)){var s=Tt.call(e);if(!en[s]||Yt&&c(e))return e;var o=vn(e)}if(!n||!t)return n?o?p(e):fn({},e):e;n=tn[s];switch(s){case Ht:case Bt:return new n(+e);case jt:case qt:return new n(e);case It:return n(e.source,at.exec(e))}r||(r=[]),i||
|
||||
(i=[]);for(s=r.length;s--;)if(r[s]==e)return i[s];var u=o?n(e.length):{};return r.push(e),i.push(u),(o?_:cn)(e,function(e,n){u[n]=y(e,t,null,r,i)}),o&&(Et.call(e,"index")&&(u.index=e.index),Et.call(e,"input")&&(u.input=e.input)),u}function b(e){var t=[];return ln(e,function(e,n){S(e)&&t.push(n)}),t.sort()}function w(e){var t={};return cn(e,function(e,n){t[e]=n}),t}function E(e,t,n,r){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;var i=Tt.call(e),s=Tt.call(t);i==Dt&&(i=Ft),s==Dt&&
|
||||
(s=Ft);if(i!=s)return!1;switch(i){case Ht:case Bt:return+e==+t;case jt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case It:case qt:return e==t+""}s=i==Pt;if(!s){if(e.__wrapped__||t.__wrapped__)return E(e.__wrapped__||e,t.__wrapped__||t);if(i!=Ft||Yt&&(c(e)||c(t)))return!1;var i=!Kt&&v(e)?Object:e.constructor,o=!Kt&&v(t)?Object:t.constructor;if(i!=o&&(!S(i)||!(i instanceof i&&S(o)&&o instanceof o)))return!1}n||(n=[]),r||(r=[]);for(i=n.length;i--;)if(n[i]==e)return r[i]==t;var u=!0,a=0;n.push(e),r.push(
|
||||
t);if(s){a=e.length;if(u=a==t.length)for(;a--&&(u=E(e[a],t[a],n,r)););return u}return ln(e,function(e,i,s){if(Et.call(s,i))return a++,u=Et.call(t,i)&&E(e,t[i],n,r)}),u&&ln(t,function(e,t,n){if(Et.call(n,t))return u=-1<--a}),u}function S(e){return typeof e=="function"}function x(e){return e?nn[typeof e]:!1}function T(e){return typeof e=="number"||Tt.call(e)==jt}function N(e){return typeof e=="string"||Tt.call(e)==qt}function C(e,t,n){var r=arguments,i=0,s=2,o=r[3],u=r[4];n!==et&&(o=[],u=[],typeof
|
||||
n!="number"&&(s=r.length));for(;++i<s;)cn(r[i],function(t,n){var r,i,s;if(t&&((i=vn(t))||mn(t))){for(var a=o.length;a--;)if(r=o[a]==t)break;r?e[n]=u[a]:(o.push(t),u.push(s=(s=e[n],i)?vn(s)?s:[]:mn(s)?s:{}),e[n]=C(s,t,et,o,u))}else t!=null&&(e[n]=t)});return e}function k(e){var t=[];return cn(e,function(e){t.push(e)}),t}function L(e,t,n){var r=-1,i=e?e.length:0,s=!1,n=(0>n?Ot(0,i+n):n)||0;return typeof i=="number"?s=-1<(N(e)?e.indexOf(t,n):R(e,t,n)):an(e,function(e){if(++r>=n)return!(s=e===t)}),s}
|
||||
function A(e,t,n){var r=!0,t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++n<i&&(r=!!t(e[n],n,e)););else an(e,function(e,n,i){return r=!!t(e,n,i)});return r}function O(e,t,n){var r=[],t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++n<i;){var s=e[n];t(s,n,e)&&r.push(s)}else an(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function M(e,t,n){var r,t=u(t,n);return _(e,function(e,n,i){if(t(e,n,i))return r=e,!1}),r}function _(e,t,n){if(t&&typeof n=="undefined"&&vn(e))for(var n=-1,r=e.length;++n<r&&!1!==t(e[
|
||||
n],n,e););else an(e,t,n);return e}function D(e,t,n){var r=-1,i=e?e.length:0,s=Array(typeof i=="number"?i:0),t=u(t,n);if(vn(e))for(;++r<i;)s[r]=t(e[r],r,e);else an(e,function(e,n,i){s[++r]=t(e,n,i)});return s}function P(e,t,n){var r=-Infinity,s=-1,o=e?e.length:0,a=r;if(t||!vn(e))t=!t&&N(e)?i:u(t,n),an(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,a=e)});else for(;++s<o;)e[s]>a&&(a=e[s]);return a}function H(e,t){return D(e,t+"")}function B(e,t,n,r){var i=3>arguments.length,t=u(t,r,et);if(vn(e)){var s=-1,o=
|
||||
e.length;for(i&&(n=e[++s]);++s<o;)n=t(n,e[s],s,e)}else an(e,function(e,r,s){n=i?(i=!1,e):t(n,e,r,s)});return n}function j(e,t,n,r){var i=e,s=e?e.length:0,o=3>arguments.length;if(typeof s!="number")var a=gn(e),s=a.length;else Gt&&N(e)&&(i=e.split(""));return t=u(t,r,et),_(e,function(e,r,u){r=a?a[--s]:--s,n=o?(o=!1,i[r]):t(n,i[r],r,u)}),n}function F(e,t,n){var r,t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else an(e,function(e,n,i){return!(r=t(e,n,i))});return!!r}function I(e
|
||||
,t,n){if(e){var r=e.length;return null==t||n?e[0]:p(e,0,Mt(Ot(0,t),r))}}function q(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];vn(s)?St.apply(i,t?s:q(s)):i.push(s)}return i}function R(e,t,n){var r=-1,i=e?e.length:0;if(typeof n=="number")r=(0>n?Ot(0,i+n):n||0)-1;else if(n)return r=z(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function U(e,t,n){return p(e,null==t||n?1:Ot(0,t))}function z(e,t,n,r){for(var i=0,s=e?e.length:i,n=n?u(n,r):V,t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=
|
||||
r+1:s=r;return i}function W(e,t,n,r){var i=-1,s=e?e.length:0,o=[],a=o;typeof t=="function"&&(r=n,n=t,t=!1);var f=!t&&75<=s;if(f)var l={};n&&(a=[],n=u(n,r));for(;++i<s;){var r=e[i],c=n?n(r,i,e):r;if(f)var h=c+"",h=Et.call(l,h)?!(a=l[h]):a=l[h]=[];if(t?!i||a[a.length-1]!==c:h||0>R(a,c))(n||f)&&a.push(c),o.push(r)}return o}function X(e,t){return zt||Nt&&2<arguments.length?Nt.call.apply(Nt,arguments):o(e,t,p(arguments,2))}function V(e){return e}function $(e){_(b(e),function(t){var r=n[t]=e[t];n.prototype
|
||||
[t]=function(){var e=[this.__wrapped__];return St.apply(e,arguments),e=r.apply(n,e),new n(e)}})}function J(){return this.__wrapped__}var K=typeof exports=="object"&&exports,Q=typeof global=="object"&&global;Q.global===Q&&(e=Q);var G=[],Y=new function(){},Z=0,et=Y,tt=30,nt=e._,rt=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,it=/&(?:amp|lt|gt|quot|#x27);/g,st=/\b__p\+='';/g,ot=/\b(__p\+=)''\+/g,ut=/(__e\(.*?\)|\b__t\))\+'';/g,at=/\w*$/,ft=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g
|
||||
,lt=RegExp("^"+(Y.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),ct=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,ht=/<%=([\s\S]+?)%>/g,pt=/($^)/,dt=/[&<>"']/g,vt=/['\n\r\t\u2028\u2029\\]/g,mt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),gt=Math.ceil,yt=G.concat,bt=Math.floor,wt=lt.test(wt=Object.getPrototypeOf)&&wt,Et=Y.hasOwnProperty,St=G.push,xt=Y.propertyIsEnumerable,Tt=Y.toString,Nt=lt.test(Nt=
|
||||
p.bind)&&Nt,Ct=lt.test(Ct=Array.isArray)&&Ct,kt=e.isFinite,Lt=e.isNaN,At=lt.test(At=Object.keys)&&At,Ot=Math.max,Mt=Math.min,_t=Math.random,Dt="[object Arguments]",Pt="[object Array]",Ht="[object Boolean]",Bt="[object Date]",jt="[object Number]",Ft="[object Object]",It="[object RegExp]",qt="[object String]",Rt=!!e.attachEvent,Ut=Nt&&!/\n|true/.test(Nt+Rt),zt=Nt&&!Ut,Wt=At&&(Rt||Ut),Xt,Vt,$t=($t={0:1,length:1},G.splice.call($t,0,1),$t[0]),Jt=!0;(function(){function e(){this.x=1}var t=[];e.prototype=
|
||||
{valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)Jt=!n;Xt=!/valueOf/.test(t),Vt="x"!=t[0]})(1);var Kt=arguments.constructor==Object,Qt=!v(arguments),Gt="xx"!="x"[0]+Object("x")[0];try{var Yt=("[object Object]",Tt.call(document)==Ft)}catch(Zt){}var en={"[object Function]":!1};en[Dt]=en[Pt]=en[Ht]=en[Bt]=en[jt]=en[Ft]=en[It]=en[qt]=!0;var tn={};tn[Pt]=Array,tn[Ht]=Boolean,tn[Bt]=Date,tn[Ft]=Object,tn[jt]=Number,tn[It]=RegExp,tn[qt]=String;var nn={"boolean":!1,"function":!0,object:!0,
|
||||
number:!1,string:!1,"undefined":!1},rn={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:ht,variable:""};var sn={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a<b;a++){if((l=arguments[a])){",g:"t[i]=l[i]",c:"}}"},on={a:"d,c,w",k:"c=c&&typeof w=='undefined'?c:e(c,w)",b:"if(c(l[i],i,d)===false)return t",g:"if(c(l[i],i,d)===false)return t"},un={b:null},an=a(on),fn=a(sn
|
||||
);Qt&&(v=function(e){return e?Et.call(e,"callee"):!1});var ln=a(on,un,{l:!1}),cn=a(on,un),hn={"&":"&","<":"<",">":">",'"':""","'":"'"},pn=w(hn),dn=a(sn,{g:"if(t[i]==null)"+sn.g}),vn=Ct||function(e){return Kt&&e instanceof Array||Tt.call(e)==Pt};S(/x/)&&(S=function(e){return e instanceof Function||"[object Function]"==Tt.call(e)});var mn=wt?function(e){if(!e||typeof e!="object")return!1;var t=e.valueOf,n=typeof t=="function"&&(n=wt(t))&&wt(n);return n?e==n||wt(e)==n&&!v(e):m(e)
|
||||
}:m,gn=At?function(e){return typeof e=="function"&&xt.call(e,"prototype")?g(e):x(e)?At(e):[]}:g;n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.assign=fn,n.bind=X,n.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=b(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=X(e[i],e)}return e},n.bindKey=function(e,t){return o(e,t,p(arguments,2))},n.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},n.compose=function(
|
||||
){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},n.countBy=function(e,t,n){var r={},t=u(t,n);return _(e,function(e,n,i){n=t(e,n,i),Et.call(r,n)?r[n]++:r[n]=1}),r},n.debounce=function(e,t,n){function r(){u=null,n||(s=e.apply(o,i))}var i,s,o,u;return function(){var a=n&&!u;return i=arguments,o=this,clearTimeout(u),u=setTimeout(r,t),a&&(s=e.apply(o,i)),s}},n.defaults=dn,n.defer=function(e){var n=p(arguments,1);return setTimeout(function(){e
|
||||
.apply(t,n)},1)},n.delay=function(e,n){var r=p(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},n.difference=function(e){for(var t=-1,n=e?e.length:0,i=yt.apply(G,arguments),i=r(i,n),s=[];++t<n;){var o=e[t];i(o)||s.push(o)}return s},n.filter=O,n.flatten=q,n.forEach=_,n.forIn=ln,n.forOwn=cn,n.functions=b,n.groupBy=function(e,t,n){var r={},t=u(t,n);return _(e,function(e,n,i){n=t(e,n,i),(Et.call(r,n)?r[n]:r[n]=[]).push(e)}),r},n.initial=function(e,t,n){if(!e)return[];var r=e.length;return p
|
||||
(e,0,Mt(Ot(0,r-(null==t||n?1:t||0)),r))},n.intersection=function(e){var t=arguments,n=t.length,i={0:{}},s=-1,o=e?e.length:0,u=100<=o,a=[],f=a;e:for(;++s<o;){var l=e[s];if(u)var c=l+"",c=Et.call(i[0],c)?!(f=i[0][c]):f=i[0][c]=[];if(c||0>R(f,l)){u&&f.push(l);for(var h=n;--h;)if(!(i[h]||(i[h]=r(t[h],0,100)))(l))continue e;a.push(l)}}return a},n.invert=w,n.invoke=function(e,t){var n=p(arguments,2),r=typeof t=="function",i=[];return _(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.keys=gn,n.map=D,
|
||||
n.max=P,n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Et.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.merge=C,n.min=function(e,t,n){var r=Infinity,s=-1,o=e?e.length:0,a=r;if(t||!vn(e))t=!t&&N(e)?i:u(t,n),an(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,a=e)});else for(;++s<o;)e[s]<a&&(a=e[s]);return a},n.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},n.omit=function(e,t,n){var r=typeof
|
||||
t=="function",i={};if(r)t=u(t,n);else var s=yt.apply(G,arguments);return ln(e,function(e,n,o){if(r?!t(e,n,o):0>R(s,n,1))i[n]=e}),i},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.pairs=function(e){var t=[];return cn(e,function(e,n){t.push([n,e])}),t},n.partial=function(e){return o(e,p(arguments,1))},n.pick=function(e,t,n){var r={};if(typeof t!="function")for(var i=0,s=yt.apply(G,arguments),o=s.length;++i<o;){var a=s[i];a in e&&(r[a]=e[a])}
|
||||
else t=u(t,n),ln(e,function(e,n,i){t(e,n,i)&&(r[n]=e)});return r},n.pluck=H,n.range=function(e,t,n){e=+e||0,n=+n||1,null==t&&(t=e,e=0);for(var r=-1,t=Ot(0,gt((t-e)/n)),i=Array(t);++r<t;)i[r]=e,e+=n;return i},n.reject=function(e,t,n){return t=u(t,n),O(e,function(e,n,r){return!t(e,n,r)})},n.rest=U,n.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return _(e,function(e){var r=bt(_t()*(++t+1));n[t]=n[r],n[r]=e}),n},n.sortBy=function(e,t,n){var r=[],t=u(t,n);_(e,function(e,n,i){r.push({a:t(e,n,i),b
|
||||
:n,c:e})}),e=r.length;for(r.sort(s);e--;)r[e]=r[e].c;return r},n.tap=function(e,t){return t(e),e},n.throttle=function(e,t){function n(){u=new Date,o=null,i=e.apply(s,r)}var r,i,s,o,u=0;return function(){var a=new Date,f=t-(a-u);return r=arguments,s=this,0>=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout(n,f)),i}},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},n.toArray=function(e){return typeof (e?e.length:0)=="number"?Gt&&N(e)?e.split("")
|
||||
:p(e):k(e)},n.union=function(){return W(yt.apply(G,arguments))},n.uniq=W,n.values=k,n.where=function(e,t){var n=gn(t);return O(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},n.without=function(e){for(var t=-1,n=e?e.length:0,i=r(arguments,1,20),s=[];++t<n;){var o=e[t];i(o)||s.push(o)}return s},n.wrap=function(e,t){return function(){var n=[e];return St.apply(n,arguments),t.apply(this,n)}},n.zip=function(e){for(var t=-1,n=e?P(H(arguments,"length")):0,r=Array(
|
||||
n);++t<n;)r[t]=H(arguments,t);return r},n.collect=D,n.drop=U,n.each=_,n.extend=fn,n.methods=b,n.select=O,n.tail=U,n.unique=W,$(n),n.clone=y,n.cloneDeep=function(e){return y(e,!0)},n.contains=L,n.escape=function(e){return null==e?"":(e+"").replace(dt,l)},n.every=A,n.find=M,n.has=function(e,t){return e?Et.call(e,t):!1},n.identity=V,n.indexOf=R,n.isArguments=v,n.isArray=vn,n.isBoolean=function(e){return!0===e||!1===e||Tt.call(e)==Ht},n.isDate=function(e){return e instanceof Date||Tt.call(e)==Bt},n.isElement=
|
||||
function(e){return e?1===e.nodeType:!1},n.isEmpty=function(e){var t=!0;if(!e)return t;var n=Tt.call(e),r=e.length;return n==Pt||n==qt||n==Dt||Qt&&v(e)||n==Ft&&typeof r=="number"&&S(e.splice)?!r:(cn(e,function(){return t=!1}),t)},n.isEqual=E,n.isFinite=function(e){return kt(e)&&!Lt(parseFloat(e))},n.isFunction=S,n.isNaN=function(e){return T(e)&&e!=+e},n.isNull=function(e){return null===e},n.isNumber=T,n.isObject=x,n.isPlainObject=mn,n.isRegExp=function(e){return e instanceof RegExp||Tt.call(e)==It
|
||||
},n.isString=N,n.isUndefined=function(e){return typeof e=="undefined"},n.lastIndexOf=function(e,t,n){var r=e?e.length:0;for(typeof n=="number"&&(r=(0>n?Ot(0,r+n):Mt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.mixin=$,n.noConflict=function(){return e._=nt,this},n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+bt(_t()*((+t||0)-e+1))},n.reduce=B,n.reduceRight=j,n.result=function(e,t){var n=e?e[t]:null;return S(n)?e[t]():n},n.size=function(e){var t=e?e.length:0;
|
||||
return typeof t=="number"?t:gn(e).length},n.some=F,n.sortedIndex=z,n.template=function(e,t,r){e||(e=""),r||(r={});var i,s,o=n.templateSettings,u=0,a=r.interpolate||o.interpolate||pt,l="__p+='",c=r.variable||o.variable,h=c;e.replace(RegExp((r.escape||o.escape||pt).source+"|"+a.source+"|"+(a===ht?ct:pt).source+"|"+(r.evaluate||o.evaluate||pt).source+"|$","g"),function(t,n,r,s,o,a){return r||(r=s),l+=e.slice(u,a).replace(vt,f),n&&(l+="'+__e("+n+")+'"),o&&(l+="';"+o+";__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"
|
||||
),i||(i=o||rt.test(n||r)),u=a+t.length,t}),l+="';\n",h||(c="obj",i?l="with("+c+"){"+l+"}":(r=RegExp("(\\(\\s*)"+c+"\\."+c+"\\b","g"),l=l.replace(ft,"$&"+c+".").replace(r,"$1__d"))),l=(i?l.replace(st,""):l).replace(ot,"$1").replace(ut,"$1;"),l="function("+c+"){"+(h?"":c+"||("+c+"={});")+"var __t,__p='',__e=_.escape"+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(h?"":",__d="+c+"."+c+"||"+c)+";")+l+"return __p}";try{s=Function("_","return "+l)(n)}catch(p){throw p.source=
|
||||
l,p}return t?s(t):(s.source=l,s)},n.unescape=function(e){return null==e?"":(e+"").replace(it,d)},n.uniqueId=function(e){return(null==e?"":e+"")+ ++Z},n.all=A,n.any=F,n.detect=M,n.foldl=B,n.foldr=j,n.include=L,n.inject=B,cn(n,function(e,t){n.prototype[t]||(n.prototype[t]=function(){var t=[this.__wrapped__];return St.apply(t,arguments),e.apply(n,t)})}),n.first=I,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:p(e,Ot(0,r-t))}},n.take=I,n.head=I,cn(n,function(e,t){n.prototype[t]||
|
||||
(n.prototype[t]=function(t,r){var i=e(this.__wrapped__,t,r);return null==t||r?i:new n(i)})}),n.VERSION="1.0.0-rc.3",n.prototype.toString=function(){return this.__wrapped__+""},n.prototype.value=J,n.prototype.valueOf=J,an(["join","pop","shift"],function(e){var t=G[e];n.prototype[e]=function(){return t.apply(this.__wrapped__,arguments)}}),an(["push","reverse","sort","unshift"],function(e){var t=G[e];n.prototype[e]=function(){return t.apply(this.__wrapped__,arguments),this}}),an(["concat","slice","splice"
|
||||
],function(e){var t=G[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return new n(e)}}),$t&&an(["pop","shift","splice"],function(e){var t=G[e],r="splice"==e;n.prototype[e]=function(){var e=this.__wrapped__,i=t.apply(e,arguments);return 0===e.length&&delete e[0],r?new n(i):i}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=n,define(function(){return n})):K?typeof module=="object"&&module&&module.exports==K?(module.exports=n)._=n:K._=n:e._=n})(this);
|
||||
33
lodash.underscore.min.js
vendored
33
lodash.underscore.min.js
vendored
@@ -1,33 +0,0 @@
|
||||
/*!
|
||||
Lo-Dash 1.0.0-rc.3 (Custom Build) lodash.com/license
|
||||
Build: `lodash underscore -m -o ./lodash.underscore.min.js`
|
||||
Underscore.js 1.4.3 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(e,t){function n(e){if(e&&typeof e=="object"&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t){var n=e.b,r=t.b,e=e.a,t=t.a;if(e!==t){if(e>t||typeof e=="undefined")return 1;if(e<t||typeof t=="undefined")return-1}return n<r?-1:1}function i(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(f(i)):n),this instanceof r?(a.prototype=e.prototype,s=new a,a.prototype=null,i=e.apply(s,i),y(i)?i:s):e.apply(s,i)}return r}function s
|
||||
(e,t,n){return e?typeof e!="function"?function(t){return t[e]}:typeof t!="undefined"?n?function(n,r,i,s){return e.call(t,n,r,i,s)}:function(n,r,i){return e.call(t,n,r,i)}:e:q}function o(e){return"\\"+Tt[e]}function u(e){return Lt[e]}function a(){}function f(e,t,n){t||(t=0),typeof n=="undefined"&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function l(e){return At[e]}function c(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)
|
||||
for(var i in r)e[i]=r[i]}return e}function h(e){var t=[];return kt(e,function(e,n){t.push(n)}),t}function p(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)null==e[i]&&(e[i]=r[i])}return e}function d(e){var t=[];return Ct(e,function(e,n){g(e)&&t.push(n)}),t.sort()}function v(e){var t={};return kt(e,function(e,n){t[e]=n}),t}function m(e,t,n,r){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;var i=it.call(e),s=it.call(t);if(i!=s)return!1
|
||||
;switch(i){case dt:case vt:return+e==+t;case mt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case yt:case bt:return e==t+""}s=i==pt;if(!s){if(e.__wrapped__||t.__wrapped__)return m(e.__wrapped__||e,t.__wrapped__||t);if(i!=gt)return!1;var i=e.constructor,o=t.constructor;if(i!=o&&(!g(i)||!(i instanceof i&&g(o)&&o instanceof o)))return!1}n||(n=[]),r||(r=[]);for(i=n.length;i--;)if(n[i]==e)return r[i]==t;var u=!0,a=0;n.push(e),r.push(t);if(s){a=e.length;if(u=a==t.length)for(;a--&&(u=m(e[a],t[a],n,r)););return u
|
||||
}return Ct(e,function(e,i,s){if(nt.call(s,i))return a++,!(u=nt.call(t,i)&&m(e,t[i],n,r))&&V}),u&&Ct(t,function(e,t,n){if(nt.call(n,t))return!(u=-1<--a)&&V}),u}function g(e){return typeof e=="function"}function y(e){return e?xt[typeof e]:!1}function b(e){return typeof e=="number"||it.call(e)==mt}function w(e){return typeof e=="string"||it.call(e)==bt}function E(e){var t=[];return kt(e,function(e){t.push(e)}),t}function S(e,t){var n=!1;return typeof (e?e.length:0)=="number"?n=-1<H(e,t):Nt(e,function(
|
||||
e){return(n=e===t)&&V}),n}function x(e,t,n){var r=!0,t=s(t,n);if(Ot(e))for(var n=-1,i=e.length;++n<i&&(r=!!t(e[n],n,e)););else Nt(e,function(e,n,i){return!(r=!!t(e,n,i))&&V});return r}function T(e,t,n){var r=[],t=s(t,n);if(Ot(e))for(var n=-1,i=e.length;++n<i;){var o=e[n];t(o,n,e)&&r.push(o)}else Nt(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function N(e,t,n){var r,t=s(t,n);return C(e,function(e,n,i){if(t(e,n,i))return r=e,V}),r}function C(e,t,n){if(t&&typeof n=="undefined"&&Ot(e))for(var n=-1
|
||||
,r=e.length;++n<r&&t(e[n],n,e)!==V;);else Nt(e,t,n)}function k(e,t,n){var r=-1,i=e?e.length:0,o=Array(typeof i=="number"?i:0),t=s(t,n);if(Ot(e))for(;++r<i;)o[r]=t(e[r],r,e);else Nt(e,function(e,n,i){o[++r]=t(e,n,i)});return o}function L(e,t,n){var r=-Infinity,i=-1,o=e?e.length:0,u=r;if(t||!Ot(e))t=s(t,n),Nt(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,u=e)});else for(;++i<o;)e[i]>u&&(u=e[i]);return u}function A(e,t){return k(e,t+"")}function O(e,t,n,r){var i=3>arguments.length,t=s(t,r,V);if(Ot(e)){var o=-1
|
||||
,u=e.length;for(i&&(n=e[++o]);++o<u;)n=t(n,e[o],o,e)}else Nt(e,function(e,r,s){n=i?(i=!1,e):t(n,e,r,s)});return n}function M(e,t,n,r){var i=e?e.length:0,o=3>arguments.length;if(typeof i!="number")var u=Mt(e),i=u.length;return t=s(t,r,V),C(e,function(r,s,a){s=u?u[--i]:--i,n=o?(o=!1,e[s]):t(n,e[s],s,a)}),n}function _(e,t,n){var r,t=s(t,n);if(Ot(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else Nt(e,function(e,n,i){return(r=t(e,n,i))&&V});return!!r}function D(e,t,n){if(e){var r=e.length;return null==
|
||||
t||n?e[0]:f(e,0,ct(lt(0,t),r))}}function P(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];Ot(s)?rt.apply(i,t?s:P(s)):i.push(s)}return i}function H(e,t,n){var r=-1,i=e?e.length:0;if(typeof n=="number")r=(0>n?lt(0,i+n):n||0)-1;else if(n)return r=j(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function B(e,t,n){return f(e,null==t||n?1:lt(0,t))}function j(e,t,n,r){for(var i=0,o=e?e.length:i,n=n?s(n,r):q,t=n(t);i<o;)r=i+o>>>1,n(e[r])<t?i=r+1:o=r;return i}function F(e,t,n,r){var i=-1
|
||||
,o=e?e.length:0,u=[],a=u;typeof t=="function"&&(r=n,n=t,t=!1),n&&(a=[],n=s(n,r));for(;++i<o;){var r=e[i],f=n?n(r,i,e):r;if(t?!i||a[a.length-1]!==f:0>H(a,f))n&&a.push(f),u.push(r)}return u}function I(e,t){return wt||st&&2<arguments.length?st.call.apply(st,arguments):i(e,t,f(arguments,2))}function q(e){return e}function R(e){C(d(e),function(t){var r=n[t]=e[t];n.prototype[t]=function(){var e=[this.__wrapped__];return rt.apply(e,arguments),e=r.apply(n,e),this.__chain__&&(e=new n(e),e.__chain__=!0),e}
|
||||
})}var U=typeof exports=="object"&&exports,z=typeof global=="object"&&global;z.global===z&&(e=z);var W=[],z=new function(){},X=0,V=z,$=e._,J=/&(?:amp|lt|gt|quot|#x27);/g,K=RegExp("^"+(z.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Q=/($^)/,G=/[&<>"']/g,Y=/['\n\r\t\u2028\u2029\\]/g,Z=Math.ceil,et=W.concat,tt=Math.floor,nt=z.hasOwnProperty,rt=W.push,it=z.toString,st=K.test(st=f.bind)&&st,ot=K.test(ot=Array.isArray)&&ot,ut=e.isFinite,at=e.isNaN,ft=
|
||||
K.test(ft=Object.keys)&&ft,lt=Math.max,ct=Math.min,ht=Math.random,pt="[object Array]",dt="[object Boolean]",vt="[object Date]",mt="[object Number]",gt="[object Object]",yt="[object RegExp]",bt="[object String]",z=!!e.attachEvent,z=st&&!/\n|true/.test(st+z),wt=st&&!z,Et=(Et={0:1,length:1},W.splice.call(Et,0,1),Et[0]),St=arguments.constructor==Object,xt={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,"undefined":!1},Tt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029"
|
||||
:"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var Nt=function(e,t,n){if(!e)return e;var t=t&&typeof n=="undefined"?t:s(t,n),r=e.length,n=-1;if(typeof r=="number"){for(;++n<r;)if(t(e[n],n,e)===V)return e}else for(n in e)if(nt.call(e,n)&&t(e[n],n,e)===V)return e};n.isArguments=function(e){return"[object Arguments]"==it.call(e)},n.isArguments(arguments)||(n.isArguments=function(e){return e?nt.call(e,"callee"):!1});var Ct=
|
||||
function(e,t){var n;if(!e)return e;t||(t=q);for(n in e)if(t(e[n],n,e)===V)break;return e},kt=function(e,t){var n;if(!e)return e;t||(t=q);for(n in e)if(nt.call(e,n)&&t(e[n],n,e)===V)break;return e},Lt={"&":"&","<":"<",">":">",'"':""","'":"'"},At=v(Lt),Ot=ot||function(e){return St&&e instanceof Array||it.call(e)==pt};g(/x/)&&(g=function(e){return e instanceof Function||"[object Function]"==it.call(e)});var Mt=ft?function(e){return y(e)?ft(e):[]}:h;n.after=function(e,t){return 1>
|
||||
e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.bind=I,n.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=d(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=I(e[i],e)}return e},n.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},n.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},n.countBy=function(e,t,n){var r={},t=s(t,n);return C(e,function(e,n,i){n=t(e,n,i),nt
|
||||
.call(r,n)?r[n]++:r[n]=1}),r},n.debounce=function(e,t,n){function r(){u=null,n||(s=e.apply(o,i))}var i,s,o,u;return function(){var a=n&&!u;return i=arguments,o=this,clearTimeout(u),u=setTimeout(r,t),a&&(s=e.apply(o,i)),s}},n.defaults=p,n.defer=function(e){var n=f(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},n.delay=function(e,n){var r=f(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},n.difference=function(e){for(var t=-1,n=e.length,r=et.apply(W,arguments),i=[];++t<n;){var s=
|
||||
e[t];0>H(r,s,n)&&i.push(s)}return i},n.filter=T,n.flatten=P,n.forEach=C,n.functions=d,n.groupBy=function(e,t,n){var r={},t=s(t,n);return C(e,function(e,n,i){n=t(e,n,i),(nt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},n.initial=function(e,t,n){if(!e)return[];var r=e.length;return f(e,0,ct(lt(0,r-(null==t||n?1:t||0)),r))},n.intersection=function(e){var t=arguments,n=t.length,r=-1,i=e?e.length:0,s=[];e:for(;++r<i;){var o=e[r];if(0>H(s,o)){for(var u=n;--u;)if(0>H(t[u],o))continue e;s.push(o)}}return s},n.invert=
|
||||
v,n.invoke=function(e,t){var n=f(arguments,2),r=typeof t=="function",i=[];return C(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.keys=Mt,n.map=k,n.max=L,n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return nt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.min=function(e,t,n){var r=Infinity,i=-1,o=e?e.length:0,u=r;if(t||!Ot(e))t=s(t,n),Nt(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,u=e)});else for(;++i<o;)e[i]<u&&(u=e[i]);return u},n.object=function(
|
||||
e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},n.omit=function(e){var t=et.apply(W,arguments),n={};return Ct(e,function(e,r){0>H(t,r,1)&&(n[r]=e)}),n},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.pairs=function(e){var t=[];return kt(e,function(e,n){t.push([n,e])}),t},n.pick=function(e){for(var t=0,n=et.apply(W,arguments),r=n.length,i={};++t<r;){var s=n[t];s in e&&(i[s]=e[s])}return i},n.pluck=
|
||||
A,n.range=function(e,t,n){e=+e||0,n=+n||1,null==t&&(t=e,e=0);for(var r=-1,t=lt(0,Z((t-e)/n)),i=Array(t);++r<t;)i[r]=e,e+=n;return i},n.reject=function(e,t,n){return t=s(t,n),T(e,function(e,n,r){return!t(e,n,r)})},n.rest=B,n.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return C(e,function(e){var r=tt(ht()*(++t+1));n[t]=n[r],n[r]=e}),n},n.sortBy=function(e,t,n){var i=[],t=s(t,n);C(e,function(e,n,r){i.push({a:t(e,n,r),b:n,c:e})}),e=i.length;for(i.sort(r);e--;)i[e]=i[e].c;return i},n.tap=function(
|
||||
e,t){return t(e),e},n.throttle=function(e,t){function n(){u=new Date,o=null,i=e.apply(s,r)}var r,i,s,o,u=0;return function(){var a=new Date,f=t-(a-u);return r=arguments,s=this,0>=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout(n,f)),i}},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},n.toArray=function(e){return typeof (e?e.length:0)=="number"?f(e):E(e)},n.union=function(){return F(et.apply(W,arguments))},n.uniq=F,n.values=E,n.where=function(
|
||||
e,t){var n=Mt(t);return T(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},n.without=function(e){for(var t=-1,n=e.length,r=[];++t<n;){var i=e[t];0>H(arguments,i,1)&&r.push(i)}return r},n.wrap=function(e,t){return function(){var n=[e];return rt.apply(n,arguments),t.apply(this,n)}},n.zip=function(e){for(var t=-1,n=e?L(A(arguments,"length")):0,r=Array(n);++t<n;)r[t]=A(arguments,t);return r},n.collect=k,n.drop=B,n.each=C,n.extend=c,n.methods=d,n.select=T,n.tail=
|
||||
B,n.unique=F,n.clone=function(e){return e&&xt[typeof e]?Ot(e)?f(e):c({},e):e},n.contains=S,n.escape=function(e){return null==e?"":(e+"").replace(G,u)},n.every=x,n.find=N,n.has=function(e,t){return e?nt.call(e,t):!1},n.identity=q,n.indexOf=H,n.isArray=Ot,n.isBoolean=function(e){return!0===e||!1===e||it.call(e)==dt},n.isDate=function(e){return e instanceof Date||it.call(e)==vt},n.isElement=function(e){return e?1===e.nodeType:!1},n.isEmpty=function(e){if(!e)return!0;if(Ot(e)||w(e))return!e.length;for(
|
||||
var t in e)if(nt.call(e,t))return!1;return!0},n.isEqual=m,n.isFinite=function(e){return ut(e)&&!at(parseFloat(e))},n.isFunction=g,n.isNaN=function(e){return b(e)&&e!=+e},n.isNull=function(e){return null===e},n.isNumber=b,n.isObject=y,n.isRegExp=function(e){return e instanceof RegExp||it.call(e)==yt},n.isString=w,n.isUndefined=function(e){return typeof e=="undefined"},n.lastIndexOf=function(e,t,n){var r=e?e.length:0;for(typeof n=="number"&&(r=(0>n?lt(0,r+n):ct(n,r-1))+1);r--;)if(e[r]===t)return r;
|
||||
return-1},n.mixin=R,n.noConflict=function(){return e._=$,this},n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+tt(ht()*((+t||0)-e+1))},n.reduce=O,n.reduceRight=M,n.result=function(e,t){var n=e?e[t]:null;return g(n)?e[t]():n},n.size=function(e){var t=e?e.length:0;return typeof t=="number"?t:Mt(e).length},n.some=_,n.sortedIndex=j,n.template=function(e,t,r){e||(e="");var r=p({},r,n.templateSettings),i=0,s="__p+='",u=r.variable;e.replace(RegExp((r.escape||Q).source+"|"+
|
||||
(r.interpolate||Q).source+"|"+(r.evaluate||Q).source+"|$","g"),function(t,n,r,u,a){s+=e.slice(i,a).replace(Y,o),s+=n?"'+_['escape']("+n+")+'":u?"';"+u+";__p+='":r?"'+((__t=("+r+"))==null?'':__t)+'":"",i=a+t.length}),s+="';\n",u||(u="obj",s="with("+u+"||{}){"+s+"}"),s="function("+u+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+s+"return __p}";try{var a=Function("_","return "+s)(n)}catch(f){throw f.source=s,f}return t?a(t):(a.source=s,a)},n.unescape=function(
|
||||
e){return null==e?"":(e+"").replace(J,l)},n.uniqueId=function(e){var t=++X+"";return e?e+t:t},n.all=x,n.any=_,n.detect=N,n.foldl=O,n.foldr=M,n.include=S,n.inject=O,n.first=D,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:f(e,lt(0,r-t))}},n.take=D,n.head=D,n.chain=function(e){return e=new n(e),e.__chain__=!0,e},n.VERSION="1.0.0-rc.3",R(n),n.prototype.chain=function(){return this.__chain__=!0,this},n.prototype.value=function(){return this.__wrapped__},Nt("pop push reverse shift sort splice unshift"
|
||||
.split(" "),function(e){var t=W[e];n.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Et&&e.length===0&&delete e[0],this}}),Nt(["concat","join","slice"],function(e){var t=W[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new n(e),e.__chain__=!0),e}}),U?typeof module=="object"&&module&&module.exports==U?(module.exports=n)._=n:U._=n:e._=n})(this);
|
||||
61
package.json
61
package.json
@@ -1,53 +1,20 @@
|
||||
{
|
||||
"name": "lodash",
|
||||
"version": "1.0.0-rc.3",
|
||||
"description": "An alternative to Underscore.js, delivering consistency, customization, performance, and extra features.",
|
||||
"homepage": "http://lodash.com",
|
||||
"main": "./lodash",
|
||||
"keywords": [
|
||||
"browser",
|
||||
"client",
|
||||
"functional",
|
||||
"performance",
|
||||
"server",
|
||||
"speed",
|
||||
"util"
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://lodash.com/license"
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"name": "John-David Dalton",
|
||||
"email": "john.david.dalton@gmail.com",
|
||||
"web": "http://allyoucanleet.com/"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/bestiejs/lodash/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bestiejs/lodash.git"
|
||||
},
|
||||
"bin": {
|
||||
"lodash": "./build.js"
|
||||
},
|
||||
"directories": {
|
||||
"doc": "./doc",
|
||||
"test": "./test"
|
||||
},
|
||||
"engines": [
|
||||
"node",
|
||||
"rhino"
|
||||
"version": "1.0.2",
|
||||
"description": "A utility library delivering consistency, customization, performance, and extras.",
|
||||
"homepage": "https://lodash.com/",
|
||||
"license": "MIT",
|
||||
"main": "./dist/lodash.js",
|
||||
"keywords": ["browser", "client", "functional", "performance", "server", "speed", "util"],
|
||||
"author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
|
||||
"contributors": [
|
||||
"John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
|
||||
"Blaine Bublitz <blaine@iceddev.com> (http://www.iceddev.com/)",
|
||||
"Kit Cambridge <github@kitcambridge.be> (http://kitcambridge.be/)",
|
||||
"Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"
|
||||
],
|
||||
"repository": "lodash/lodash",
|
||||
"jam": {
|
||||
"main": "./lodash.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build",
|
||||
"test": "node test/test && node test/test-build",
|
||||
"install": "node build/post-install"
|
||||
"main": "./dist/lodash.compat.js"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,19 +34,21 @@
|
||||
// expose Lo-Dash build file path
|
||||
ui.buildPath = (function() {
|
||||
switch (build) {
|
||||
case 'lodash-dev': return 'lodash.js';
|
||||
case 'lodash-underscore': return 'lodash.underscore.min.js';
|
||||
case 'lodash-dev': return 'dist/lodash.compat.js';
|
||||
case 'lodash-modern': return 'dist/lodash.min.js';
|
||||
case 'lodash-underscore': return 'dist/lodash.underscore.min.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
}
|
||||
return 'lodash.min.js';
|
||||
return 'dist/lodash.compat.min.js';
|
||||
}());
|
||||
|
||||
// expose other library file path
|
||||
ui.otherPath = (function() {
|
||||
switch (other) {
|
||||
case 'lodash-dev': return 'lodash.js';
|
||||
case 'lodash-prod': return 'lodash.min.js';
|
||||
case 'lodash-underscore': return 'lodash.underscore.min.js';
|
||||
case 'lodash-dev': return 'dist/lodash.compat.js';
|
||||
case 'lodash-prod': return 'dist/lodash.compat.min.js';
|
||||
case 'lodash-modern': return 'dist/lodash.min.js';
|
||||
case 'lodash-underscore': return 'dist/lodash.underscore.min.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
case 'underscore-dev': return 'vendor/underscore/underscore.js';
|
||||
}
|
||||
@@ -76,6 +78,7 @@
|
||||
'<select id="perf-build">' +
|
||||
'<option value="lodash-dev">Lo-Dash</option>' +
|
||||
'<option value="lodash-prod">Lo-Dash (minified)</option>' +
|
||||
'<option value="lodash-modern">Lo-Dash (modern)</option>' +
|
||||
'<option value="lodash-underscore">Lo-Dash (underscore)</option>' +
|
||||
'<option value="lodash-custom">Lo-Dash (custom)</option>' +
|
||||
'</select>';
|
||||
@@ -89,6 +92,7 @@
|
||||
'<option value="underscore-prod">Underscore (minified)</option>' +
|
||||
'<option value="lodash-dev">Lo-Dash</option>' +
|
||||
'<option value="lodash-prod">Lo-Dash (minified)</option>' +
|
||||
'<option value="lodash-modern">Lo-Dash (modern)</option>' +
|
||||
'<option value="lodash-underscore">Lo-Dash (underscore)</option>' +
|
||||
'<option value="lodash-custom">Lo-Dash (custom)</option>' +
|
||||
'</select>';
|
||||
@@ -102,20 +106,22 @@
|
||||
|
||||
buildList.selectedIndex = (function() {
|
||||
switch (build) {
|
||||
case 'lodash-dev': return 0;
|
||||
case 'lodash-underscore': return 2;
|
||||
case 'lodash-custom': return 3;
|
||||
case 'lodash-dev': return 0;
|
||||
case 'lodash-modern': return 2;
|
||||
case 'lodash-underscore': return 3;
|
||||
case 'lodash-custom': return 4;
|
||||
}
|
||||
return 1;
|
||||
}());
|
||||
|
||||
otherList.selectedIndex = (function() {
|
||||
switch (other) {
|
||||
case 'underscore-dev': return 0;
|
||||
case 'lodash-dev': return 2;
|
||||
case 'lodash-prod': return 3;
|
||||
case 'lodash-underscore': return 4;
|
||||
case 'lodash-custom': return 5;
|
||||
case 'underscore-dev': return 0;
|
||||
case 'lodash-dev': return 2;
|
||||
case 'lodash-prod': return 3;
|
||||
case 'lodash-modern': return 4;
|
||||
case 'lodash-underscore': return 5;
|
||||
case 'lodash-custom': return 6;
|
||||
}
|
||||
return 1;
|
||||
}());
|
||||
|
||||
228
perf/perf.js
228
perf/perf.js
@@ -1,8 +1,28 @@
|
||||
(function(window) {
|
||||
|
||||
/** Use a single load function */
|
||||
/** Use a single "load" function */
|
||||
var load = typeof require == 'function' ? require : window.load;
|
||||
|
||||
/** The file path of the Lo-Dash file to test */
|
||||
var filePath = (function() {
|
||||
var min = 0;
|
||||
var result = window.phantom
|
||||
? phantom.args
|
||||
: (window.system
|
||||
? (min = 1, system.args)
|
||||
: (window.process ? (min = 2, process.argv) : (window.arguments || []))
|
||||
);
|
||||
|
||||
var last = result[result.length - 1];
|
||||
result = (result.length > min && last != 'test.js') ? last : '../lodash.js';
|
||||
|
||||
try {
|
||||
result = require('fs').realpathSync(result);
|
||||
} catch(e) { }
|
||||
|
||||
return result;
|
||||
}());
|
||||
|
||||
/** Load Benchmark.js */
|
||||
var Benchmark =
|
||||
window.Benchmark || (
|
||||
@@ -13,7 +33,7 @@
|
||||
/** Load Lo-Dash */
|
||||
var lodash =
|
||||
window.lodash || (
|
||||
lodash = load('../lodash.js') || window._,
|
||||
lodash = load(filePath) || window._,
|
||||
lodash = lodash._ || lodash,
|
||||
lodash.noConflict()
|
||||
);
|
||||
@@ -35,22 +55,27 @@
|
||||
var suites = [];
|
||||
|
||||
/** The `ui` object */
|
||||
var ui = window.ui || {};
|
||||
var ui = window.ui || {
|
||||
'buildPath': basename(filePath, '.js'),
|
||||
'otherPath': 'underscore'
|
||||
};
|
||||
|
||||
/** The Lo-Dash build basename */
|
||||
var buildName = basename(ui.buildPath || 'lodash', '.js');
|
||||
var buildName = basename(ui.buildPath, '.js');
|
||||
|
||||
/** The other library basename */
|
||||
var otherName = basename(ui.otherPath || 'underscore', '.js');
|
||||
|
||||
/** Add `console.log()` support for Narwhal and RingoJS */
|
||||
window.console || (window.console = { 'log': window.print });
|
||||
var otherName = basename(ui.otherPath, '.js');
|
||||
|
||||
/** Expose functions to the global object */
|
||||
window._ = _;
|
||||
window.Benchmark = Benchmark;
|
||||
window.lodash = lodash;
|
||||
|
||||
/** Add `console.log()` support for Narwhal and RingoJS */
|
||||
if (!window.console && window.print) {
|
||||
window.console = { 'log': window.print };
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -78,7 +103,8 @@
|
||||
* @returns {Number} Returns the adjusted Hz.
|
||||
*/
|
||||
function getHz(bench) {
|
||||
return 1 / (bench.stats.mean + bench.stats.moe);
|
||||
var result = 1 / (bench.stats.mean + bench.stats.moe);
|
||||
return isFinite(result) ? result : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,7 +213,7 @@
|
||||
numbers = Array(limit),\
|
||||
fourNumbers = [5, 25, 10, 30],\
|
||||
nestedNumbers = [1, [2], [3, [[4]]]],\
|
||||
twoNumbers = [12, 21];\
|
||||
twoNumbers = [12, 23];\
|
||||
\
|
||||
for (index = 0; index < limit; index++) {\
|
||||
numbers[index] = index;\
|
||||
@@ -204,11 +230,9 @@
|
||||
};\
|
||||
\
|
||||
var lodashBoundNormal = lodash.bind(func, contextObject),\
|
||||
lodashBoundCtor = lodash.bind(ctor, contextObject),\
|
||||
lodashBoundPartial = lodash.bind(func, contextObject, "hi");\
|
||||
\
|
||||
var _boundNormal = _.bind(func, contextObject),\
|
||||
_boundCtor = _.bind(ctor, contextObject),\
|
||||
_boundPartial = _.bind(func, contextObject, "hi");\
|
||||
}\
|
||||
\
|
||||
@@ -294,7 +318,13 @@
|
||||
var object2 = {},\
|
||||
objects2 = Array(limit),\
|
||||
numbers2 = Array(limit),\
|
||||
nestedNumbers2 = [1, [2], [3, [[4]]]];\
|
||||
nestedNumbers2 = [1, [2], [3, [[4]]]],\
|
||||
nestedNumbers3 = [1, [2], [5, [[6]]]],\
|
||||
simpleObject = { "a": 1 },\
|
||||
simpleObject2 = { "a": 2 },\
|
||||
simpleObjects = [simpleObject],\
|
||||
simpleObjects2 = [simpleObject2],\
|
||||
twoNumbers2 = [18, 27];\
|
||||
\
|
||||
for (index = 0; index < limit; index++) {\
|
||||
object2["key" + index] = index;\
|
||||
@@ -383,33 +413,14 @@
|
||||
"list": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]\
|
||||
};\
|
||||
\
|
||||
var tplBase =\
|
||||
var tpl =\
|
||||
"<div>" +\
|
||||
"<h1 class=\'header1\'><%= header1 %></h1>" +\
|
||||
"<h2 class=\'header2\'><%= header2 %></h2>" +\
|
||||
"<h3 class=\'header3\'><%= header3 %></h3>" +\
|
||||
"<h4 class=\'header4\'><%= header4 %></h4>" +\
|
||||
"<h5 class=\'header5\'><%= header5 %></h5>" +\
|
||||
"<h6 class=\'header6\'><%= header6 %></h6>";\
|
||||
\
|
||||
var tpl =\
|
||||
tplBase +\
|
||||
"<ul class=\'list\'>" +\
|
||||
"<li class=\'item\'><%= list[0] %></li>" +\
|
||||
"<li class=\'item\'><%= list[1] %></li>" +\
|
||||
"<li class=\'item\'><%= list[2] %></li>" +\
|
||||
"<li class=\'item\'><%= list[3] %></li>" +\
|
||||
"<li class=\'item\'><%= list[4] %></li>" +\
|
||||
"<li class=\'item\'><%= list[5] %></li>" +\
|
||||
"<li class=\'item\'><%= list[6] %></li>" +\
|
||||
"<li class=\'item\'><%= list[7] %></li>" +\
|
||||
"<li class=\'item\'><%= list[8] %></li>" +\
|
||||
"<li class=\'item\'><%= list[9] %></li>" +\
|
||||
"</ul>" +\
|
||||
"</div>";\
|
||||
\
|
||||
var tplWithEvaluate =\
|
||||
tplBase +\
|
||||
"<h6 class=\'header6\'><%= header6 %></h6>" +\
|
||||
"<ul class=\'list\'>" +\
|
||||
"<% for (var index = 0, length = list.length; index < length; index++) { %>" +\
|
||||
"<li class=\'item\'><%= list[index] %></li>" +\
|
||||
@@ -417,33 +428,14 @@
|
||||
"</ul>" +\
|
||||
"</div>";\
|
||||
\
|
||||
var tplBaseVerbose =\
|
||||
var tplVerbose =\
|
||||
"<div>" +\
|
||||
"<h1 class=\'header1\'><%= data.header1 %></h1>" +\
|
||||
"<h2 class=\'header2\'><%= data.header2 %></h2>" +\
|
||||
"<h3 class=\'header3\'><%= data.header3 %></h3>" +\
|
||||
"<h4 class=\'header4\'><%= data.header4 %></h4>" +\
|
||||
"<h5 class=\'header5\'><%= data.header5 %></h5>" +\
|
||||
"<h6 class=\'header6\'><%= data.header6 %></h6>";\
|
||||
\
|
||||
var tplVerbose =\
|
||||
tplBaseVerbose +\
|
||||
"<ul class=\'list\'>" +\
|
||||
"<li class=\'item\'><%= data.list[0] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[1] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[2] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[3] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[4] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[5] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[6] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[7] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[8] %></li>" +\
|
||||
"<li class=\'item\'><%= data.list[9] %></li>" +\
|
||||
"</ul>" +\
|
||||
"</div>";\
|
||||
\
|
||||
var tplVerboseWithEvaluate =\
|
||||
tplBaseVerbose +\
|
||||
"<h6 class=\'header6\'><%= data.header6 %></h6>" +\
|
||||
"<ul class=\'list\'>" +\
|
||||
"<% for (var index = 0, length = data.list.length; index < length; index++) { %>" +\
|
||||
"<li class=\'item\'><%= data.list[index] %></li>" +\
|
||||
@@ -454,14 +446,10 @@
|
||||
var settingsObject = { "variable": "data" };\
|
||||
\
|
||||
var lodashTpl = lodash.template(tpl),\
|
||||
lodashTplWithEvaluate = lodash.template(tplWithEvaluate),\
|
||||
lodashTplVerbose = lodash.template(tplVerbose, null, settingsObject),\
|
||||
lodashTplVerboseWithEvaluate = lodash.template(tplVerboseWithEvaluate, null, settingsObject);\
|
||||
lodashTplVerbose = lodash.template(tplVerbose, null, settingsObject);\
|
||||
\
|
||||
var _tpl = _.template(tpl),\
|
||||
_tplWithEvaluate = _.template(tplWithEvaluate),\
|
||||
_tplVerbose = _.template(tplVerbose, null, settingsObject),\
|
||||
_tplVerboseWithEvaluate = _.template(tplVerboseWithEvaluate, null, settingsObject);\
|
||||
_tplVerbose = _.template(tplVerbose, null, settingsObject);\
|
||||
}'
|
||||
});
|
||||
|
||||
@@ -527,18 +515,6 @@
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('bound and called in a `new` expression, i.e. `new bound` (edge case)')
|
||||
.add(buildName, {
|
||||
'fn': 'new lodashBoundCtor()',
|
||||
'teardown': 'function bind(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': 'new _boundCtor()',
|
||||
'teardown': 'function bind(){}'
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
@@ -863,6 +839,16 @@
|
||||
)
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.find` with `properties`')
|
||||
.add(buildName, '\
|
||||
lodash.find(objects, { "num": 9 });'
|
||||
)
|
||||
.add(otherName, '\
|
||||
_.findWhere(objects, { "num": 9 });'
|
||||
)
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
@@ -1040,11 +1026,15 @@
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.isEqual` comparing arrays')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.isEqual(numbers, numbers2)',
|
||||
'fn': '\
|
||||
lodash.isEqual(numbers, numbers2);\
|
||||
lodash.isEqual(twoNumbers, twoNumbers2);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_.isEqual(numbers, numbers2)',
|
||||
'fn': '\
|
||||
_.isEqual(numbers, numbers2);\
|
||||
_.isEqual(twoNumbers, twoNumbers2);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
);
|
||||
@@ -1052,11 +1042,15 @@
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.isEqual` comparing nested arrays')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.isEqual(nestedNumbers, nestedNumbers2)',
|
||||
'fn': '\
|
||||
lodash.isEqual(nestedNumbers, nestedNumbers2);\
|
||||
lodash.isEqual(nestedNumbers2, nestedNumbers3);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_.isEqual(nestedNumbers, nestedNumbers2)',
|
||||
'fn': '\
|
||||
_.isEqual(nestedNumbers, nestedNumbers2);\
|
||||
_.isEqual(nestedNumbers2, nestedNumbers3);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
);
|
||||
@@ -1064,11 +1058,15 @@
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.isEqual` comparing arrays of objects')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.isEqual(objects, objects2)',
|
||||
'fn': '\
|
||||
lodash.isEqual(objects, objects2);\
|
||||
lodash.isEqual(simpleObjects, simpleObjects2);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_.isEqual(objects, objects2)',
|
||||
'fn': '\
|
||||
_.isEqual(objects, objects2);\
|
||||
_.isEqual(simpleObjects, simpleObjects2);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
);
|
||||
@@ -1076,11 +1074,15 @@
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.isEqual` comparing objects')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.isEqual(object, object2)',
|
||||
'fn': '\
|
||||
lodash.isEqual(object, object2);\
|
||||
lodash.isEqual(simpleObject, simpleObject2);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_.isEqual(object, object2)',
|
||||
'fn': '\
|
||||
_.isEqual(object, object2);\
|
||||
_.isEqual(simpleObject, simpleObject2);',
|
||||
'teardown': 'function isEqual(){}'
|
||||
})
|
||||
);
|
||||
@@ -1419,6 +1421,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] == 19;\
|
||||
}, object)'
|
||||
)
|
||||
.add(otherName, '\
|
||||
_.some(objects, function(value, index) {\
|
||||
return this["key" + index] == 19;\
|
||||
}, object)'
|
||||
)
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.some` iterating an object')
|
||||
.add(buildName, '\
|
||||
@@ -1500,7 +1516,7 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.template` without "evaluate" delimiters (slow path)')
|
||||
Benchmark.Suite('`_.template` (slow path)')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.template(tpl, tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
@@ -1512,19 +1528,7 @@
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.template` with "evaluate" delimiters (slow path)')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.template(tplWithEvaluate, tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_.template(tplWithEvaluate, tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('compiled template without "evaluate" delimiters')
|
||||
Benchmark.Suite('compiled template')
|
||||
.add(buildName, {
|
||||
'fn': 'lodashTpl(tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
@@ -1536,19 +1540,7 @@
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('compiled template with "evaluate" delimiters')
|
||||
.add(buildName, {
|
||||
'fn': 'lodashTplWithEvaluate(tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_tplWithEvaluate(tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('compiled template without a with-statement or "evaluate" delimiters')
|
||||
Benchmark.Suite('compiled template without a with-statement')
|
||||
.add(buildName, {
|
||||
'fn': 'lodashTplVerbose(tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
@@ -1559,18 +1551,6 @@
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('compiled template without a with-statement using "evaluate" delimiters')
|
||||
.add(buildName, {
|
||||
'fn': 'lodashTplVerboseWithEvaluate(tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_tplVerboseWithEvaluate(tplData)',
|
||||
'teardown': 'function template(){}'
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
@@ -1718,13 +1698,13 @@
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('`_.without` iterating an array of 20 elements')
|
||||
Benchmark.Suite('`_.without` iterating an array of 30 elements')
|
||||
.add(buildName, {
|
||||
'fn': 'lodash.without.apply(lodash, [twentyValues].concat(twentyValues2));',
|
||||
'fn': 'lodash.without.apply(lodash, [thirtyValues].concat(thirtyValues2));',
|
||||
'teardown': 'function multiArrays(){}'
|
||||
})
|
||||
.add(otherName, {
|
||||
'fn': '_.without.apply(_, [twentyValues].concat(twentyValues2));',
|
||||
'fn': '_.without.apply(_, [thirtyValues].concat(thirtyValues2));',
|
||||
'teardown': 'function multiArrays(){}'
|
||||
})
|
||||
);
|
||||
@@ -1736,7 +1716,7 @@
|
||||
}
|
||||
|
||||
// in the browser, expose `run` to be called later
|
||||
if (window.document) {
|
||||
if (window.document && !window.phantom) {
|
||||
window.run = run;
|
||||
} else {
|
||||
run();
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
cd "$(dirname "$0")"
|
||||
for cmd in node narwhal ringo rhino; do
|
||||
echo ""
|
||||
echo "Running performance suite in $cmd..."
|
||||
$cmd perf.js
|
||||
|
||||
echo "Running performance suite in node..."
|
||||
node perf.js ../dist/lodash.js && node perf.js ../dist/lodash.min.js
|
||||
|
||||
for cmd in rhino narwhal ringo phantomjs; do
|
||||
echo ""
|
||||
echo "Running performance suite in $cmd..."
|
||||
$cmd perf.js ../dist/lodash.compat.js && $cmd perf.js ../dist/lodash.compat.min.js
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Running performance suite in a browser..."
|
||||
open index.html
|
||||
open index.html
|
||||
|
||||
@@ -21,13 +21,7 @@
|
||||
<script src="../vendor/json3/lib/json3.js"></script>
|
||||
<script src="../vendor/jquery/jquery.js"></script>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script>
|
||||
// avoid syntax errors for `QUnit.throws` in older Firefoxes
|
||||
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
|
||||
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
|
||||
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
|
||||
);
|
||||
</script>
|
||||
<script src="../vendor/qunit/qunit/qunit.js"></script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script src="../lodash.js"></script>
|
||||
<script>
|
||||
@@ -36,7 +30,8 @@
|
||||
</script>
|
||||
<script>
|
||||
_.mixin({
|
||||
'debounce': lodash.debounce
|
||||
'debounce': lodash.debounce,
|
||||
'defer': lodash.defer
|
||||
});
|
||||
if (!_.chain) {
|
||||
_.mixin({
|
||||
|
||||
@@ -8,13 +8,7 @@
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script>
|
||||
// avoid syntax errors for `QUnit.throws` in older Firefoxes
|
||||
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
|
||||
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
|
||||
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
|
||||
);
|
||||
</script>
|
||||
<script src="../vendor/qunit/qunit/qunit.js"></script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script>
|
||||
// set a bad shim
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
cd "$(dirname "$0")"
|
||||
for cmd in rhino ringo narwhal node; do
|
||||
echo ""
|
||||
|
||||
for cmd in rhino narwhal ringo phantomjs; do
|
||||
echo "Testing in $cmd..."
|
||||
$cmd test.js
|
||||
$cmd test.js ../dist/lodash.compat.js && $cmd test.js ../dist/lodash.compat.min.js
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Testing in node..."
|
||||
node test.js ../dist/lodash.js && node test.js ../dist/lodash.min.js
|
||||
|
||||
echo ""
|
||||
echo "Testing build..."
|
||||
node test-build.js
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<ul>
|
||||
<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>
|
||||
<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>
|
||||
</ul>
|
||||
@@ -11,8 +11,25 @@
|
||||
_ = require('../lodash.js');
|
||||
|
||||
/** The unit testing framework */
|
||||
var QUnit = global.QUnit = require('../vendor/qunit/qunit/qunit.js');
|
||||
require('../vendor/qunit-clib/qunit-clib.js');
|
||||
var QUnit = (
|
||||
global.addEventListener || (global.addEventListener = Function.prototype),
|
||||
global.QUnit = require('../vendor/qunit/qunit/qunit.js'),
|
||||
require('../vendor/qunit-clib/qunit-clib.js'),
|
||||
global.addEventListener === Function.prototype && delete global.addEventListener,
|
||||
global.QUnit
|
||||
);
|
||||
|
||||
/** The time limit for the tests to run (milliseconds) */
|
||||
var timeLimit = process.argv.reduce(function(result, value, index) {
|
||||
if (/--time-limit/.test(value)) {
|
||||
return parseInt(process.argv[index + 1].replace(/(\d+h)?(\d+m)?(\d+s)?/, function(match, h, m, s) {
|
||||
return ((parseInt(h) || 0) * 3600000) +
|
||||
((parseInt(m) || 0) * 60000) +
|
||||
((parseInt(s) || 0) * 1000);
|
||||
})) || result;
|
||||
}
|
||||
return result;
|
||||
}, 0);
|
||||
|
||||
/** Used to associate aliases with their real names */
|
||||
var aliasToRealMap = {
|
||||
@@ -56,7 +73,8 @@
|
||||
/** List of all Lo-Dash methods */
|
||||
var allMethods = _.functions(_)
|
||||
.filter(function(methodName) { return !/^_/.test(methodName); })
|
||||
.concat('chain');
|
||||
.concat('chain')
|
||||
.sort();
|
||||
|
||||
/** List of "Arrays" category methods */
|
||||
var arraysMethods = [
|
||||
@@ -95,6 +113,7 @@
|
||||
var collectionsMethods = [
|
||||
'all',
|
||||
'any',
|
||||
'at',
|
||||
'collect',
|
||||
'contains',
|
||||
'countBy',
|
||||
@@ -139,6 +158,7 @@
|
||||
'memoize',
|
||||
'once',
|
||||
'partial',
|
||||
'partialRight',
|
||||
'throttle',
|
||||
'wrap'
|
||||
];
|
||||
@@ -249,13 +269,14 @@
|
||||
|
||||
/** List of methods used by Underscore */
|
||||
var underscoreMethods = _.without.apply(_, [allMethods].concat([
|
||||
'at',
|
||||
'bindKey',
|
||||
'cloneDeep',
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'isPlainObject',
|
||||
'merge',
|
||||
'partial'
|
||||
'partialRight'
|
||||
]));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -349,6 +370,7 @@
|
||||
object = { 'a': 1, 'b': 2, 'c': 3 },
|
||||
noop = function() {},
|
||||
string = 'abc',
|
||||
template = '<%= a %>',
|
||||
func = lodash[methodName];
|
||||
|
||||
try {
|
||||
@@ -386,6 +408,10 @@
|
||||
func(array);
|
||||
func(object);
|
||||
}
|
||||
else if (methodName == 'at') {
|
||||
func(array, 0, 2);
|
||||
func(object, 'a', 'c');
|
||||
}
|
||||
else if (methodName == 'invoke') {
|
||||
func(array, 'slice');
|
||||
func(object, 'toFixed');
|
||||
@@ -406,7 +432,7 @@
|
||||
func({ 'noop': noop });
|
||||
} else if (methodName == 'bindKey') {
|
||||
func(lodash, 'identity', array, string);
|
||||
} else if (/^(?:bind|partial)$/.test(methodName)) {
|
||||
} else if (/^(?:bind|partial(?:Right)?)$/.test(methodName)) {
|
||||
func(noop, object, array, string);
|
||||
} else if (/^(?:compose|memoize|wrap)$/.test(methodName)) {
|
||||
func(noop, noop);
|
||||
@@ -436,6 +462,9 @@
|
||||
else if (utilityMethods.indexOf(methodName) > -1) {
|
||||
if (methodName == 'result') {
|
||||
func(object, 'b');
|
||||
} else if (methodName == 'template') {
|
||||
func(template, object);
|
||||
func(template, null, { 'imports': object })(object);
|
||||
} else if (methodName == 'times') {
|
||||
func(2, noop, object);
|
||||
} else {
|
||||
@@ -458,12 +487,12 @@
|
||||
var start = _.once(QUnit.start);
|
||||
|
||||
asyncTest('`lodash`', function() {
|
||||
build(['-s'], function(source, filePath) {
|
||||
build(['-s'], function(data) {
|
||||
// used by r.js build optimizer
|
||||
var defineHasRegExp = /typeof\s+define\s*==(=)?\s*['"]function['"]\s*&&\s*typeof\s+define\.amd\s*==(=)?\s*['"]object['"]\s*&&\s*define\.amd/g,
|
||||
basename = path.basename(filePath, '.js');
|
||||
basename = path.basename(data.outputPath, '.js');
|
||||
|
||||
ok(!!defineHasRegExp.exec(source), basename);
|
||||
ok(!!defineHasRegExp.exec(data.source), basename);
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -479,22 +508,22 @@
|
||||
asyncTest('`lodash template=*.jst`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'template=' + templatePath + '/*.jst'], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', 'template=' + templatePath + '/*.jst'], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
var data = {
|
||||
var object = {
|
||||
'a': { 'people': ['moe', 'larry', 'curly'] },
|
||||
'b': { 'epithet': 'stooge' },
|
||||
'c': { 'name': 'ES6' }
|
||||
};
|
||||
|
||||
context._ = _;
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
|
||||
equal(_.templates.a(data.a).replace(/[\r\n]+/g, ''), '<ul><li>moe</li><li>larry</li><li>curly</li></ul>', basename);
|
||||
equal(_.templates.b(data.b), 'Hello stooge.', basename);
|
||||
equal(_.templates.c(data.c), 'Hello ES6!', basename);
|
||||
equal(_.templates.a(object.a).replace(/[\r\n]+/g, ''), '<ul><li>moe</li><li>larry</li><li>curly</li></ul>', basename);
|
||||
equal(_.templates.b(object.b), 'Hello stooge.', basename);
|
||||
equal(_.templates.c(object.c), 'Hello ES6!', basename);
|
||||
delete _.templates;
|
||||
start();
|
||||
});
|
||||
@@ -506,12 +535,14 @@
|
||||
];
|
||||
|
||||
commands.forEach(function(command) {
|
||||
asyncTest('`lodash template=*.jst` exports=amd' + (command ? ' ' + command : ''), function() {
|
||||
var expectedId = /underscore/.test(command) ? 'underscore' : 'lodash';
|
||||
|
||||
asyncTest('`lodash template=*.jst exports=amd' + (command ? ' ' + command : '') + '`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'template=' + templatePath + '/*.jst', 'exports=amd'].concat(command || []), function(source, filePath) {
|
||||
build(['-s', 'template=' + templatePath + '/*.jst', 'exports=amd'].concat(command || []), function(data) {
|
||||
var moduleId,
|
||||
basename = path.basename(filePath, '.js'),
|
||||
basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
context.define = function(requires, factory) {
|
||||
@@ -520,24 +551,26 @@
|
||||
};
|
||||
|
||||
context.define.amd = {};
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
|
||||
equal(moduleId, (command ? 'underscore' : 'lodash'), basename);
|
||||
equal(moduleId, expectedId, basename);
|
||||
ok('a' in _.templates && 'b' in _.templates, basename);
|
||||
equal(_.templates.a({ 'people': ['moe', 'larry'] }), '<ul>\n<li>moe</li><li>larry</li>\n</ul>', basename);
|
||||
|
||||
delete _.templates;
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('`lodash settings=...`' + (command ? ' ' + command : ''), function() {
|
||||
asyncTest('`lodash settings=...' + (command ? ' ' + command : '') + '`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'template=' + templatePath + '/*.tpl', 'settings={interpolate:/\\{\\{([\\s\\S]+?)\\}\\}/}'].concat(command || []), function(source, filePath) {
|
||||
build(['-s', 'template=' + templatePath + '/*.tpl', 'settings={interpolate:/{{([\\s\\S]+?)}}/}'].concat(command || []), function(data) {
|
||||
var moduleId,
|
||||
basename = path.basename(filePath, '.js'),
|
||||
basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
var data = {
|
||||
var object = {
|
||||
'd': { 'name': 'Mustache' }
|
||||
};
|
||||
|
||||
@@ -547,10 +580,10 @@
|
||||
};
|
||||
|
||||
context.define.amd = {};
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
|
||||
equal(moduleId, (command ? 'underscore' : 'lodash'), basename);
|
||||
equal(_.templates.d(data.d), 'Hello Mustache!', basename);
|
||||
equal(moduleId, expectedId, basename);
|
||||
equal(_.templates.d(object.d), 'Hello Mustache!', basename);
|
||||
delete _.templates;
|
||||
start();
|
||||
});
|
||||
@@ -563,23 +596,23 @@
|
||||
QUnit.module('independent builds');
|
||||
|
||||
(function() {
|
||||
var reComment = /\/\*![\s\S]+?\*\//,
|
||||
reCustom = /Custom Build/;
|
||||
var reCustom = /Custom Build/,
|
||||
reLicense = /^\/\**\s+\* @license[\s\S]+?\*\/\n/;
|
||||
|
||||
asyncTest('debug only', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
build(['-d', '-s'], function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'lodash');
|
||||
build(['-d', '-s'], function(data) {
|
||||
equal(path.basename(data.outputPath, '.js'), 'lodash');
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('debug custom', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
build(['-d', '-s', 'backbone'], function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'lodash.custom');
|
||||
build(['-d', '-s', 'backbone'], function(data) {
|
||||
equal(path.basename(data.outputPath, '.js'), 'lodash.custom');
|
||||
|
||||
var comment = source.match(reComment);
|
||||
var comment = data.source.match(reLicense);
|
||||
ok(reCustom.test(comment));
|
||||
start();
|
||||
});
|
||||
@@ -587,18 +620,18 @@
|
||||
|
||||
asyncTest('minified only', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
build(['-m', '-s'], function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'lodash.min');
|
||||
build(['-m', '-s'], function(data) {
|
||||
equal(path.basename(data.outputPath, '.js'), 'lodash.min');
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('minified custom', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
build(['-m', '-s', 'backbone'], function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'lodash.custom.min');
|
||||
build(['-m', '-s', 'backbone'], function(data) {
|
||||
equal(path.basename(data.outputPath, '.js'), 'lodash.custom.min');
|
||||
|
||||
var comment = source.match(reComment);
|
||||
var comment = data.source.match(reLicense);
|
||||
ok(reCustom.test(comment));
|
||||
start();
|
||||
});
|
||||
@@ -607,15 +640,65 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('source maps');
|
||||
|
||||
(function() {
|
||||
var mapCommands = [
|
||||
'-p',
|
||||
'-p custom.map',
|
||||
'--source-map',
|
||||
'--source-map custom.map'
|
||||
];
|
||||
|
||||
var outputCommands = [
|
||||
'',
|
||||
'-o foo.js',
|
||||
'-m -o bar.js'
|
||||
];
|
||||
|
||||
mapCommands.forEach(function(mapCommand) {
|
||||
outputCommands.forEach(function(outputCommand) {
|
||||
asyncTest('`lodash ' + mapCommand + (outputCommand ? ' ' + outputCommand : '') + '`', function() {
|
||||
var callback = _.once(function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
comment = (/(\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)$/.exec(data.source) || [])[0],
|
||||
sources = /foo.js/.test(outputCommand) ? ['foo.js'] : ['lodash' + (outputCommand.length ? '' : '.custom') + '.js'],
|
||||
sourceMap = JSON.parse(data.sourceMap),
|
||||
sourceMapURL = (/\w+(?=\.map$)/.exec(mapCommand) || [basename])[0];
|
||||
|
||||
ok(RegExp('/\\*\\n//@ sourceMappingURL=' + sourceMapURL + '.map\\n\\*/').test(comment), basename);
|
||||
equal(sourceMap.file, basename + '.js', basename);
|
||||
deepEqual(sourceMap.sources, sources, basename);
|
||||
|
||||
QUnit.start();
|
||||
});
|
||||
|
||||
outputCommand = outputCommand ? outputCommand.split(' ') : [];
|
||||
if (outputCommand.indexOf('-m') < 0) {
|
||||
callback = _.after(2, callback);
|
||||
}
|
||||
build(['-s'].concat(mapCommand.split(' '), outputCommand), callback);
|
||||
});
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('strict modifier');
|
||||
|
||||
(function() {
|
||||
var object = Object.freeze({
|
||||
'a': _.identity,
|
||||
'b': null
|
||||
'b': undefined
|
||||
});
|
||||
|
||||
['non-strict', 'strict'].forEach(function(strictMode, index) {
|
||||
var modes = [
|
||||
'non-strict',
|
||||
'strict'
|
||||
];
|
||||
|
||||
modes.forEach(function(strictMode, index) {
|
||||
asyncTest(strictMode + ' should ' + (index ? 'error': 'silently fail') + ' attempting to overwrite read-only properties', function() {
|
||||
var commands = ['-s', 'include=bindAll,defaults,extend'],
|
||||
start = _.after(2, _.once(QUnit.start));
|
||||
@@ -623,11 +706,11 @@
|
||||
if (index) {
|
||||
commands.push('strict');
|
||||
}
|
||||
build(commands, function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(commands, function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
var actual = _.every([
|
||||
@@ -665,11 +748,11 @@
|
||||
asyncTest('`lodash ' + command +'`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', command], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', command], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
ok(lodash.chain(1) instanceof lodash, '_.chain: ' + basename);
|
||||
@@ -703,29 +786,49 @@
|
||||
asyncTest('modified methods should work correctly', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'underscore'], function(source, filePath) {
|
||||
build(['-s', 'underscore'], function(data) {
|
||||
var last,
|
||||
array = [{ 'a': 1, 'b': 2 }, { 'a': 2, 'b': 2 }],
|
||||
basename = path.basename(filePath, '.js'),
|
||||
basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
var object = { 'fn': lodash.bind(function(foo) { return foo + this.bar; }, { 'bar': 1 }, 1) };
|
||||
var object = {
|
||||
'fn': lodash.bind(function(foo) {
|
||||
return foo + this.bar;
|
||||
}, { 'bar': 1 }, 1)
|
||||
};
|
||||
|
||||
equal(object.fn(), 2, '_.bind: ' + basename);
|
||||
|
||||
strictEqual(lodash.clone(array, true)[0], array[0], '_.clone should be shallow: ' + basename);
|
||||
ok(lodash.contains({ 'a': 1, 'b': 2 }, 1), '_.contains should work with objects: ' + basename);
|
||||
ok(lodash.contains([1, 2, 3], 1, 2), '_.contains should ignore `fromIndex`: ' + basename);
|
||||
ok(!lodash.every([true, false, true]), '_.every: ' + basename);
|
||||
var actual = lodash.clone('a', function() {
|
||||
return this.a;
|
||||
}, { 'a': 'A' });
|
||||
|
||||
equal(actual, 'a', '_.clone should ignore `callback` and `thisArg`: ' + basename);
|
||||
strictEqual(lodash.clone(array, true)[0], array[0], '_.clone should ignore `deep`: ' + basename);
|
||||
|
||||
strictEqual(lodash.contains({ 'a': 1, 'b': 2 }, 1), true, '_.contains should work with objects: ' + basename);
|
||||
strictEqual(lodash.contains([1, 2, 3], 1, 2), true, '_.contains should ignore `fromIndex`: ' + basename);
|
||||
strictEqual(lodash.every([true, false, true]), false, '_.every: ' + basename);
|
||||
|
||||
function Foo() {}
|
||||
Foo.prototype = { 'a': 1 };
|
||||
|
||||
actual = lodash.defaults({ 'a': null }, { 'a': 1 });
|
||||
strictEqual(actual.a, 1, '_.defaults should overwrite `null` values: ' + basename);
|
||||
|
||||
deepEqual(lodash.defaults({}, new Foo), Foo.prototype, '_.defaults should assign inherited `source` properties: ' + basename);
|
||||
deepEqual(lodash.extend({}, new Foo), Foo.prototype, '_.extend should assign inherited `source` properties: ' + basename);
|
||||
|
||||
actual = lodash.extend({}, { 'a': 0 }, function(a, b) {
|
||||
return this[b];
|
||||
}, [2]);
|
||||
|
||||
strictEqual(actual.a, 0, '_.extend should ignore `callback` and `thisArg`: ' + basename);
|
||||
|
||||
actual = lodash.find(array, function(value) {
|
||||
return 'a' in value;
|
||||
});
|
||||
@@ -746,20 +849,38 @@
|
||||
object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
equal(lodash.isEqual(object, { 'a': 1, 'b': 0, 'c': 3 }), false, '_.isEqual: ' + basename);
|
||||
|
||||
actual = lodash.isEqual('a', 'b', function(a, b) {
|
||||
return this[a] == this[b];
|
||||
}, { 'a': 1, 'b': 1 });
|
||||
|
||||
strictEqual(actual, false, '_.isEqual should ignore `callback` and `thisArg`: ' + basename);
|
||||
|
||||
equal(lodash.max('abc'), -Infinity, '_.max should return `-Infinity` for strings: ' + basename);
|
||||
equal(lodash.min('abc'), Infinity, '_.min should return `Infinity` for strings: ' + basename);
|
||||
|
||||
// avoid issues comparing objects with `deepEqual`
|
||||
object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
var actual = lodash.omit(object, function(value) { return value == 3; });
|
||||
actual = lodash.omit(object, function(value) { return value == 3; });
|
||||
deepEqual(_.keys(actual).sort(), ['a', 'b', 'c'], '_.omit should not accept a `callback`: ' + basename);
|
||||
|
||||
actual = lodash.pick(object, function(value) { return value != 3; });
|
||||
deepEqual(_.keys(actual), [], '_.pick should not accept a `callback`: ' + basename);
|
||||
|
||||
ok(lodash.some([false, true, false]), '_.some: ' + basename);
|
||||
strictEqual(lodash.result(), null, '_.result should return `null` for falsey `object` arguments: ' + basename);
|
||||
strictEqual(lodash.some([false, true, false]), true, '_.some: ' + basename);
|
||||
equal(lodash.template('${a}', object), '${a}', '_.template should ignore ES6 delimiters: ' + basename);
|
||||
equal(lodash.uniqueId(0), '1', '_.uniqueId should ignore a prefix of `0`: ' + basename);
|
||||
equal('imports' in lodash.templateSettings, false, '_.templateSettings should not have an "imports" property: ' + basename);
|
||||
strictEqual(lodash.uniqueId(0), '1', '_.uniqueId should ignore a prefix of `0`: ' + basename);
|
||||
|
||||
var collection = [{ 'a': { 'b': 1, 'c': 2 } }];
|
||||
deepEqual(lodash.where(collection, { 'a': { 'b': 1 } }), [], '_.where performs shallow comparisons: ' + basename);
|
||||
|
||||
collection = [{ 'a': 1 }, { 'a': 1 }];
|
||||
deepEqual(lodash.where(collection, { 'a': 1 }, true), collection[0], '_.where supports a `first` argument: ' + basename);
|
||||
deepEqual(lodash.where(collection, {}, true), null, '_.where should return `null` when passed `first` and falsey `properties`: ' + basename);
|
||||
|
||||
deepEqual(lodash.findWhere(collection, { 'a': 1 }), collection[0], '_.findWhere: ' + basename);
|
||||
strictEqual(lodash.findWhere(collection, {}), null, '_.findWhere should return `null` for falsey `properties`: ' + basename);
|
||||
|
||||
start();
|
||||
});
|
||||
@@ -768,21 +889,22 @@
|
||||
asyncTest('should not have any Lo-Dash-only methods', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'underscore'], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', 'underscore'], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
_.each([
|
||||
'assign',
|
||||
'at',
|
||||
'bindKey',
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'isPlainObject',
|
||||
'merge',
|
||||
'partial'
|
||||
'partialRight'
|
||||
], function(methodName) {
|
||||
equal(lodash[methodName], undefined, '_.' + methodName + ' should not exist: ' + basename);
|
||||
});
|
||||
@@ -791,14 +913,31 @@
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('`lodash underscore include=findWhere`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'underscore', 'include=findWhere'], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
var collection = [{ 'a': 1 }, { 'a': 1 }];
|
||||
deepEqual(lodash.findWhere(collection, { 'a': 1 }), collection[0], '_.findWhere: ' + basename);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('`lodash underscore include=partial`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'underscore', 'include=partial'], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', 'underscore', 'include=partial'], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
equal(lodash.partial(_.identity, 2)(), 2, '_.partial: ' + basename);
|
||||
@@ -809,17 +948,17 @@
|
||||
asyncTest('`lodash underscore plus=clone`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'underscore', 'plus=clone'], function(source, filePath) {
|
||||
build(['-s', 'underscore', 'plus=clone'], function(data) {
|
||||
var array = [{ 'value': 1 }],
|
||||
basename = path.basename(filePath, '.js'),
|
||||
basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._,
|
||||
clone = lodash.clone(array, true);
|
||||
|
||||
deepEqual(array, clone, basename);
|
||||
notEqual(array, clone, basename);
|
||||
ok(_.isEqual(array, clone), basename);
|
||||
notEqual(array[0], clone[0], basename);
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -842,10 +981,11 @@
|
||||
asyncTest('`lodash ' + command +'`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', command], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', command], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext(),
|
||||
pass = false;
|
||||
pass = false,
|
||||
source = data.source;
|
||||
|
||||
switch(index) {
|
||||
case 0:
|
||||
@@ -902,8 +1042,8 @@
|
||||
asyncTest('`lodash ' + command +'`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'exports=none', command], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', 'exports=none', command], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
context.define = function(func) {
|
||||
@@ -911,7 +1051,7 @@
|
||||
};
|
||||
|
||||
try {
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
@@ -936,10 +1076,11 @@
|
||||
|
||||
commands.forEach(function(command, index) {
|
||||
asyncTest('`lodash ' + command +'`', function() {
|
||||
var start = _.once(QUnit.start);
|
||||
var counter = -1,
|
||||
start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s'].concat(command.split(' ')), function(source, filePath) {
|
||||
equal(path.basename(filePath, '.js'), 'a', command);
|
||||
build(['-s'].concat(command.split(' ')), function(data) {
|
||||
equal(path.basename(data.outputPath, '.js'), (++counter ? 'a.min' : 'a'), command);
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -953,7 +1094,8 @@
|
||||
(function() {
|
||||
var commands = [
|
||||
'-c',
|
||||
'--stdout'
|
||||
'-c -d',
|
||||
'--stdout',
|
||||
];
|
||||
|
||||
commands.forEach(function(command, index) {
|
||||
@@ -966,9 +1108,9 @@
|
||||
written = string;
|
||||
};
|
||||
|
||||
build([command, 'exports=', 'include='], function(source) {
|
||||
build(['exports=', 'include='].concat(command.split(' ')), function(data) {
|
||||
process.stdout.write = write;
|
||||
equal(written, source);
|
||||
equal(written, data.source);
|
||||
equal(arguments.length, 1);
|
||||
start();
|
||||
});
|
||||
@@ -978,47 +1120,18 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('minify underscore');
|
||||
|
||||
(function() {
|
||||
asyncTest('`node minify underscore.js`', function() {
|
||||
var source = fs.readFileSync(path.join(__dirname, '..', 'vendor', 'underscore', 'underscore.js'), 'utf8'),
|
||||
start = _.once(QUnit.start);
|
||||
|
||||
minify(source, {
|
||||
'isSilent': true,
|
||||
'workingName': 'underscore.min',
|
||||
'onComplete': function(result) {
|
||||
var context = createContext();
|
||||
|
||||
try {
|
||||
vm.runInContext(result, context);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
var underscore = context._ || {};
|
||||
ok(_.isString(underscore.VERSION));
|
||||
ok(!/Lo-Dash/.test(result) && result.match(/\n/g).length < source.match(/\n/g).length);
|
||||
start();
|
||||
}
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('mobile build');
|
||||
|
||||
(function() {
|
||||
asyncTest('`lodash mobile`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
build(['-s', 'mobile'], function(source, filePath) {
|
||||
var basename = path.basename(filePath, '.js'),
|
||||
build(['-s', 'mobile'], function(data) {
|
||||
var basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext();
|
||||
|
||||
try {
|
||||
vm.runInContext(source, context);
|
||||
vm.runInContext(data.source, context);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
@@ -1036,13 +1149,31 @@
|
||||
|
||||
deepEqual(lodash.merge(object1, object2), object3, basename);
|
||||
deepEqual(lodash.sortBy([3, 2, 1], _.identity), array, basename);
|
||||
ok(lodash.isEqual(circular1, circular2), basename);
|
||||
strictEqual(lodash.isEqual(circular1, circular2), true, basename);
|
||||
|
||||
var actual = lodash.clone(circular1, true);
|
||||
var actual = lodash.cloneDeep(circular1);
|
||||
ok(actual != circular1 && actual.b == actual, basename);
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('`lodash csp`', function() {
|
||||
var sources = [];
|
||||
|
||||
var check = _.after(2, _.once(function() {
|
||||
equal(sources[0], sources[1]);
|
||||
QUnit.start();
|
||||
}));
|
||||
|
||||
var callback = function(data) {
|
||||
// remove copyright header and append source
|
||||
sources.push(data.source.replace(/^\/\**[\s\S]+?\*\/\n/, ''));
|
||||
check();
|
||||
};
|
||||
|
||||
build(['-s', '-d', 'csp'], callback);
|
||||
build(['-s', '-d', 'mobile'], callback);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1055,6 +1186,7 @@
|
||||
'csp',
|
||||
'legacy',
|
||||
'mobile',
|
||||
'modern',
|
||||
'strict',
|
||||
'underscore',
|
||||
'category=arrays',
|
||||
@@ -1067,8 +1199,9 @@
|
||||
'include=each,filter,map',
|
||||
'include=once plus=bind,Chaining',
|
||||
'category=collections,functions',
|
||||
'underscore backbone',
|
||||
'backbone legacy category=utilities minus=first,last',
|
||||
'legacy include=defer',
|
||||
'legacy underscore',
|
||||
'underscore include=debounce,throttle plus=after minus=throttle',
|
||||
'underscore mobile strict category=functions exports=amd,global plus=pick,uniq',
|
||||
]
|
||||
@@ -1078,81 +1211,114 @@
|
||||
})
|
||||
);
|
||||
|
||||
commands.forEach(function(command) {
|
||||
asyncTest('`lodash ' + command +'`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
commands.forEach(function(origCommand) {
|
||||
_.times(4, function(index) {
|
||||
var command = origCommand;
|
||||
|
||||
build(['--silent'].concat(command.split(' ')), function(source, filePath) {
|
||||
var methodNames,
|
||||
basename = path.basename(filePath, '.js'),
|
||||
context = createContext(),
|
||||
isUnderscore = /underscore/.test(command),
|
||||
exposeAssign = !isUnderscore;
|
||||
if (index == 1) {
|
||||
if (/legacy|mobile/.test(command)) {
|
||||
return;
|
||||
}
|
||||
command = 'mobile ' + command;
|
||||
}
|
||||
if (index == 2) {
|
||||
if (/legacy|modern/.test(command)) {
|
||||
return;
|
||||
}
|
||||
command = 'modern ' + command;
|
||||
}
|
||||
if (index == 3) {
|
||||
if (/category|legacy|underscore/.test(command)) {
|
||||
return;
|
||||
}
|
||||
command = 'underscore ' + command;
|
||||
}
|
||||
asyncTest('`lodash ' + command +'`', function() {
|
||||
var start = _.after(2, _.once(QUnit.start));
|
||||
|
||||
try {
|
||||
vm.runInContext(source, context);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
// add method names explicitly
|
||||
if (/include/.test(command)) {
|
||||
methodNames = command.match(/include=(\S*)/)[1].split(/, */);
|
||||
}
|
||||
// add method names required by Backbone and Underscore builds
|
||||
if (/backbone/.test(command) && !methodNames) {
|
||||
methodNames = backboneDependencies.slice();
|
||||
}
|
||||
if (isUnderscore) {
|
||||
if (methodNames) {
|
||||
exposeAssign = methodNames.indexOf('assign') > -1;
|
||||
} else {
|
||||
methodNames = underscoreMethods.slice();
|
||||
build(['--silent'].concat(command.split(' ')), function(data) {
|
||||
var methodNames,
|
||||
basename = path.basename(data.outputPath, '.js'),
|
||||
context = createContext(),
|
||||
isUnderscore = /backbone|underscore/.test(command),
|
||||
exposeAssign = !isUnderscore;
|
||||
|
||||
try {
|
||||
vm.runInContext(data.source, context);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
// add method names explicitly
|
||||
if (/include/.test(command)) {
|
||||
methodNames = command.match(/include=(\S*)/)[1].split(/, */);
|
||||
}
|
||||
// add method names required by Backbone and Underscore builds
|
||||
if (/backbone/.test(command) && !methodNames) {
|
||||
methodNames = backboneDependencies.slice();
|
||||
}
|
||||
if (isUnderscore) {
|
||||
if (methodNames) {
|
||||
exposeAssign = methodNames.indexOf('assign') > -1;
|
||||
} else {
|
||||
methodNames = underscoreMethods.slice();
|
||||
}
|
||||
}
|
||||
// add method names explicitly by category
|
||||
if (/category/.test(command)) {
|
||||
// resolve method names belonging to each category (case-insensitive)
|
||||
methodNames = command.match(/category=(\S*)/)[1].split(/, */).reduce(function(result, category) {
|
||||
var capitalized = category[0].toUpperCase() + category.toLowerCase().slice(1);
|
||||
return result.concat(getMethodsByCategory(capitalized));
|
||||
}, methodNames || []);
|
||||
}
|
||||
// init `methodNames` if it hasn't been inited
|
||||
if (!methodNames) {
|
||||
methodNames = allMethods.slice();
|
||||
}
|
||||
if (/plus/.test(command)) {
|
||||
methodNames = methodNames.concat(command.match(/plus=(\S*)/)[1].split(/, */));
|
||||
}
|
||||
if (/minus/.test(command)) {
|
||||
methodNames = _.without.apply(_, [methodNames]
|
||||
.concat(expandMethodNames(command.match(/minus=(\S*)/)[1].split(/, */))));
|
||||
}
|
||||
if (/exclude/.test(command)) {
|
||||
methodNames = _.without.apply(_, [methodNames]
|
||||
.concat(expandMethodNames(command.match(/exclude=(\S*)/)[1].split(/, */))));
|
||||
}
|
||||
}
|
||||
// add method names explicitly by category
|
||||
if (/category/.test(command)) {
|
||||
// resolve method names belonging to each category (case-insensitive)
|
||||
methodNames = command.match(/category=(\S*)/)[1].split(/, */).reduce(function(result, category) {
|
||||
var capitalized = category[0].toUpperCase() + category.toLowerCase().slice(1);
|
||||
return result.concat(getMethodsByCategory(capitalized));
|
||||
}, methodNames || []);
|
||||
}
|
||||
// init `methodNames` if it hasn't been inited
|
||||
if (!methodNames) {
|
||||
methodNames = allMethods.slice();
|
||||
}
|
||||
if (/plus/.test(command)) {
|
||||
methodNames = methodNames.concat(command.match(/plus=(\S*)/)[1].split(/, */));
|
||||
}
|
||||
if (/minus/.test(command)) {
|
||||
methodNames = _.without.apply(_, [methodNames]
|
||||
.concat(expandMethodNames(command.match(/minus=(\S*)/)[1].split(/, */))));
|
||||
}
|
||||
if (/exclude/.test(command)) {
|
||||
methodNames = _.without.apply(_, [methodNames]
|
||||
.concat(expandMethodNames(command.match(/exclude=(\S*)/)[1].split(/, */))));
|
||||
}
|
||||
|
||||
// expand aliases and categories to real method names
|
||||
methodNames = expandMethodNames(methodNames).reduce(function(result, methodName) {
|
||||
return result.concat(methodName, getMethodsByCategory(methodName));
|
||||
}, []);
|
||||
// expand aliases and categories to real method names
|
||||
methodNames = expandMethodNames(methodNames).reduce(function(result, methodName) {
|
||||
return result.concat(methodName, getMethodsByCategory(methodName));
|
||||
}, []);
|
||||
|
||||
// remove nonexistent and duplicate method names
|
||||
methodNames = _.uniq(_.intersection(allMethods, expandMethodNames(methodNames)));
|
||||
// remove nonexistent and duplicate method names
|
||||
methodNames = _.uniq(_.intersection(allMethods, expandMethodNames(methodNames)));
|
||||
|
||||
if (!exposeAssign) {
|
||||
methodNames = _.without(methodNames, 'assign');
|
||||
}
|
||||
var lodash = context._ || {};
|
||||
methodNames.forEach(function(methodName) {
|
||||
testMethod(lodash, methodName, basename);
|
||||
if (!exposeAssign) {
|
||||
methodNames = _.without(methodNames, 'assign');
|
||||
}
|
||||
var lodash = context._ || {};
|
||||
methodNames.forEach(function(methodName) {
|
||||
testMethod(lodash, methodName, basename);
|
||||
});
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
if (timeLimit > 0) {
|
||||
setTimeout(function() {
|
||||
process.exit(QUnit.config.stats.bad ? 1 : 0);
|
||||
}, timeLimit);
|
||||
}
|
||||
// explicitly call `QUnit.start()` for Narwhal, Node.js, Rhino, and RingoJS
|
||||
if (!global.document) {
|
||||
QUnit.start();
|
||||
}
|
||||
}());
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
// expose Lo-Dash build file path
|
||||
ui.buildPath = (function() {
|
||||
switch (build) {
|
||||
case 'lodash-prod': return 'lodash.min.js';
|
||||
case 'lodash-underscore': return 'lodash.underscore.min.js';
|
||||
case 'lodash-prod': return 'dist/lodash.compat.min.js';
|
||||
case 'lodash-underscore': return 'dist/lodash.underscore.min.js';
|
||||
case 'lodash-modern': return 'dist/lodash.min.js';
|
||||
case 'lodash-modern-debug': return 'dist/lodash.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
case 'lodash-custom-debug': return 'lodash.custom.js';
|
||||
}
|
||||
@@ -58,8 +60,10 @@
|
||||
switch (build) {
|
||||
case 'lodash-prod': return 1;
|
||||
case 'lodash-underscore': return 2;
|
||||
case 'lodash-custom': return 3;
|
||||
case 'lodash-custom-debug': return 4;
|
||||
case 'lodash-modern': return 3;
|
||||
case 'lodash-modern-debug': return 4;
|
||||
case 'lodash-custom': return 5;
|
||||
case 'lodash-custom-debug': return 6;
|
||||
}
|
||||
return 0;
|
||||
}());
|
||||
@@ -86,6 +90,8 @@
|
||||
'<option value="lodash-dev">Developement</option>' +
|
||||
'<option value="lodash-prod">Production</option>' +
|
||||
'<option value="lodash-underscore">Underscore</option>' +
|
||||
'<option value="lodash-modern">Modern</option>' +
|
||||
'<option value="lodash-modern-debug">Modern (debug)</option>' +
|
||||
'<option value="lodash-custom">Custom</option>' +
|
||||
'<option value="lodash-custom-debug">Custom (debug)</option>' +
|
||||
'</select>';
|
||||
|
||||
1134
test/test.js
1134
test/test.js
File diff suppressed because it is too large
Load Diff
@@ -21,13 +21,7 @@
|
||||
</div>
|
||||
<script src="../vendor/jquery/jquery.js"></script>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script>
|
||||
// avoid syntax errors for `QUnit.throws` in older Firefoxes
|
||||
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
|
||||
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
|
||||
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
|
||||
);
|
||||
</script>
|
||||
<script src="../vendor/qunit/qunit/qunit.js"></script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script>
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
@@ -62,6 +56,10 @@
|
||||
|
||||
_.mixin(_);
|
||||
|
||||
_.mixin({
|
||||
'findWhere': _.find
|
||||
});
|
||||
|
||||
_.chain = function(value) {
|
||||
value = new _(value);
|
||||
value.__chain__ = true;
|
||||
|
||||
497
vendor/backbone/backbone.js
vendored
497
vendor/backbone/backbone.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Backbone.js 0.9.9
|
||||
// Backbone.js 0.9.10
|
||||
|
||||
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Backbone may be freely distributed under the MIT license.
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
// Current version of the library. Keep in sync with `package.json`.
|
||||
Backbone.VERSION = '0.9.9';
|
||||
Backbone.VERSION = '0.9.10';
|
||||
|
||||
// Require Underscore, if we're on the server, and it's not already present.
|
||||
var _ = root._;
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
// Optimized internal dispatch function for triggering events. Tries to
|
||||
// keep the usual cases speedy (most Backbone events have 3 arguments).
|
||||
var triggerEvents = function(obj, events, args) {
|
||||
var triggerEvents = function(events, args) {
|
||||
var ev, i = -1, l = events.length;
|
||||
switch (args.length) {
|
||||
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx);
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
// Remove one or many callbacks. If `context` is null, removes all
|
||||
// callbacks with that function. If `callback` is null, removes all
|
||||
// callbacks for the event. If `events` is null, removes all bound
|
||||
// callbacks for the event. If `name` is null, removes all bound
|
||||
// callbacks for all events.
|
||||
off: function(name, callback, context) {
|
||||
var list, ev, events, names, i, l, j, k;
|
||||
@@ -160,7 +160,8 @@
|
||||
if (callback || context) {
|
||||
for (j = 0, k = list.length; j < k; j++) {
|
||||
ev = list[j];
|
||||
if ((callback && callback !== (ev.callback._callback || ev.callback)) ||
|
||||
if ((callback && callback !== ev.callback &&
|
||||
callback !== ev.callback._callback) ||
|
||||
(context && context !== ev.context)) {
|
||||
events.push(ev);
|
||||
}
|
||||
@@ -183,32 +184,33 @@
|
||||
if (!eventsApi(this, 'trigger', name, args)) return this;
|
||||
var events = this._events[name];
|
||||
var allEvents = this._events.all;
|
||||
if (events) triggerEvents(this, events, args);
|
||||
if (allEvents) triggerEvents(this, allEvents, arguments);
|
||||
if (events) triggerEvents(events, args);
|
||||
if (allEvents) triggerEvents(allEvents, arguments);
|
||||
return this;
|
||||
},
|
||||
|
||||
// An inversion-of-control version of `on`. Tell *this* object to listen to
|
||||
// an event in another object ... keeping track of what it's listening to.
|
||||
listenTo: function(object, events, callback) {
|
||||
listenTo: function(obj, name, callback) {
|
||||
var listeners = this._listeners || (this._listeners = {});
|
||||
var id = object._listenerId || (object._listenerId = _.uniqueId('l'));
|
||||
listeners[id] = object;
|
||||
object.on(events, callback || this, this);
|
||||
var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
|
||||
listeners[id] = obj;
|
||||
obj.on(name, typeof name === 'object' ? this : callback, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
// Tell this object to stop listening to either specific events ... or
|
||||
// to every object it's currently listening to.
|
||||
stopListening: function(object, events, callback) {
|
||||
stopListening: function(obj, name, callback) {
|
||||
var listeners = this._listeners;
|
||||
if (!listeners) return;
|
||||
if (object) {
|
||||
object.off(events, callback, this);
|
||||
if (!events && !callback) delete listeners[object._listenerId];
|
||||
if (obj) {
|
||||
obj.off(name, typeof name === 'object' ? this : callback, this);
|
||||
if (!name && !callback) delete listeners[obj._listenerId];
|
||||
} else {
|
||||
if (typeof name === 'object') callback = this;
|
||||
for (var id in listeners) {
|
||||
listeners[id].off(null, null, this);
|
||||
listeners[id].off(name, callback, this);
|
||||
}
|
||||
this._listeners = {};
|
||||
}
|
||||
@@ -233,15 +235,14 @@
|
||||
var defaults;
|
||||
var attrs = attributes || {};
|
||||
this.cid = _.uniqueId('c');
|
||||
this.changed = {};
|
||||
this.attributes = {};
|
||||
this._changes = [];
|
||||
if (options && options.collection) this.collection = options.collection;
|
||||
if (options && options.parse) attrs = this.parse(attrs);
|
||||
if (defaults = _.result(this, 'defaults')) _.defaults(attrs, defaults);
|
||||
this.set(attrs, {silent: true});
|
||||
this._currentAttributes = _.clone(this.attributes);
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
if (options && options.parse) attrs = this.parse(attrs, options) || {};
|
||||
if (defaults = _.result(this, 'defaults')) {
|
||||
attrs = _.defaults({}, attrs, defaults);
|
||||
}
|
||||
this.set(attrs, options);
|
||||
this.changed = {};
|
||||
this.initialize.apply(this, arguments);
|
||||
};
|
||||
|
||||
@@ -285,47 +286,72 @@
|
||||
return this.get(attr) != null;
|
||||
},
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// Set a hash of model attributes on the object, firing `"change"` unless
|
||||
// you choose to silence it.
|
||||
set: function(key, val, options) {
|
||||
var attr, attrs;
|
||||
var attr, attrs, unset, changes, silent, changing, prev, current;
|
||||
if (key == null) return this;
|
||||
|
||||
// Handle both `"key", value` and `{key: value}` -style arguments.
|
||||
if (_.isObject(key)) {
|
||||
if (typeof key === 'object') {
|
||||
attrs = key;
|
||||
options = val;
|
||||
} else {
|
||||
(attrs = {})[key] = val;
|
||||
}
|
||||
|
||||
// Extract attributes and options.
|
||||
var silent = options && options.silent;
|
||||
var unset = options && options.unset;
|
||||
options || (options = {});
|
||||
|
||||
// Run validation.
|
||||
if (!this._validate(attrs, options)) return false;
|
||||
|
||||
// Extract attributes and options.
|
||||
unset = options.unset;
|
||||
silent = options.silent;
|
||||
changes = [];
|
||||
changing = this._changing;
|
||||
this._changing = true;
|
||||
|
||||
if (!changing) {
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
this.changed = {};
|
||||
}
|
||||
current = this.attributes, prev = this._previousAttributes;
|
||||
|
||||
// Check for changes of `id`.
|
||||
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
|
||||
|
||||
var now = this.attributes;
|
||||
|
||||
// For each `set` attribute...
|
||||
// For each `set` attribute, update or delete the current value.
|
||||
for (attr in attrs) {
|
||||
val = attrs[attr];
|
||||
|
||||
// Update or delete the current value, and track the change.
|
||||
unset ? delete now[attr] : now[attr] = val;
|
||||
this._changes.push(attr, val);
|
||||
if (!_.isEqual(current[attr], val)) changes.push(attr);
|
||||
if (!_.isEqual(prev[attr], val)) {
|
||||
this.changed[attr] = val;
|
||||
} else {
|
||||
delete this.changed[attr];
|
||||
}
|
||||
unset ? delete current[attr] : current[attr] = val;
|
||||
}
|
||||
|
||||
// Signal that the model's state has potentially changed, and we need
|
||||
// to recompute the actual changes.
|
||||
this._hasComputed = false;
|
||||
// Trigger all relevant attribute changes.
|
||||
if (!silent) {
|
||||
if (changes.length) this._pending = true;
|
||||
for (var i = 0, l = changes.length; i < l; i++) {
|
||||
this.trigger('change:' + changes[i], this, current[changes[i]], options);
|
||||
}
|
||||
}
|
||||
|
||||
// Fire the `"change"` events.
|
||||
if (!silent) this.change(options);
|
||||
if (changing) return this;
|
||||
if (!silent) {
|
||||
while (this._pending) {
|
||||
this._pending = false;
|
||||
this.trigger('change', this, options);
|
||||
}
|
||||
}
|
||||
this._pending = false;
|
||||
this._changing = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -343,16 +369,54 @@
|
||||
return this.set(attrs, _.extend({}, options, {unset: true}));
|
||||
},
|
||||
|
||||
// Determine if the model has changed since the last `"change"` event.
|
||||
// If you specify an attribute name, determine if that attribute has changed.
|
||||
hasChanged: function(attr) {
|
||||
if (attr == null) return !_.isEmpty(this.changed);
|
||||
return _.has(this.changed, attr);
|
||||
},
|
||||
|
||||
// Return an object containing all the attributes that have changed, or
|
||||
// false if there are no changed attributes. Useful for determining what
|
||||
// parts of a view need to be updated and/or what attributes need to be
|
||||
// persisted to the server. Unset attributes will be set to undefined.
|
||||
// You can also pass an attributes object to diff against the model,
|
||||
// determining if there *would be* a change.
|
||||
changedAttributes: function(diff) {
|
||||
if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
|
||||
var val, changed = false;
|
||||
var old = this._changing ? this._previousAttributes : this.attributes;
|
||||
for (var attr in diff) {
|
||||
if (_.isEqual(old[attr], (val = diff[attr]))) continue;
|
||||
(changed || (changed = {}))[attr] = val;
|
||||
}
|
||||
return changed;
|
||||
},
|
||||
|
||||
// Get the previous value of an attribute, recorded at the time the last
|
||||
// `"change"` event was fired.
|
||||
previous: function(attr) {
|
||||
if (attr == null || !this._previousAttributes) return null;
|
||||
return this._previousAttributes[attr];
|
||||
},
|
||||
|
||||
// Get all of the attributes of the model at the time of the previous
|
||||
// `"change"` event.
|
||||
previousAttributes: function() {
|
||||
return _.clone(this._previousAttributes);
|
||||
},
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Fetch the model from the server. If the server's representation of the
|
||||
// model differs from its current attributes, they will be overriden,
|
||||
// triggering a `"change"` event.
|
||||
fetch: function(options) {
|
||||
options = options ? _.clone(options) : {};
|
||||
if (options.parse === void 0) options.parse = true;
|
||||
var model = this;
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
if (!model.set(model.parse(resp), options)) return false;
|
||||
options.success = function(model, resp, options) {
|
||||
if (!model.set(model.parse(resp, options), options)) return false;
|
||||
if (success) success(model, resp, options);
|
||||
};
|
||||
return this.sync('read', this, options);
|
||||
@@ -362,55 +426,51 @@
|
||||
// If the server returns an attributes hash that differs, the model's
|
||||
// state will be `set` again.
|
||||
save: function(key, val, options) {
|
||||
var attrs, current, done;
|
||||
var attrs, success, method, xhr, attributes = this.attributes;
|
||||
|
||||
// Handle both `"key", value` and `{key: value}` -style arguments.
|
||||
if (key == null || _.isObject(key)) {
|
||||
if (key == null || typeof key === 'object') {
|
||||
attrs = key;
|
||||
options = val;
|
||||
} else if (key != null) {
|
||||
} else {
|
||||
(attrs = {})[key] = val;
|
||||
}
|
||||
options = options ? _.clone(options) : {};
|
||||
|
||||
// If we're "wait"-ing to set changed attributes, validate early.
|
||||
if (options.wait) {
|
||||
if (attrs && !this._validate(attrs, options)) return false;
|
||||
current = _.clone(this.attributes);
|
||||
}
|
||||
// If we're not waiting and attributes exist, save acts as `set(attr).save(null, opts)`.
|
||||
if (attrs && (!options || !options.wait) && !this.set(attrs, options)) return false;
|
||||
|
||||
// Regular saves `set` attributes before persisting to the server.
|
||||
var silentOptions = _.extend({}, options, {silent: true});
|
||||
if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
|
||||
return false;
|
||||
}
|
||||
options = _.extend({validate: true}, options);
|
||||
|
||||
// Do not persist invalid models.
|
||||
if (!attrs && !this._validate(null, options)) return false;
|
||||
if (!this._validate(attrs, options)) return false;
|
||||
|
||||
// Set temporary attributes if `{wait: true}`.
|
||||
if (attrs && options.wait) {
|
||||
this.attributes = _.extend({}, attributes, attrs);
|
||||
}
|
||||
|
||||
// After a successful server-side save, the client is (optionally)
|
||||
// updated with the server-side state.
|
||||
var model = this;
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
done = true;
|
||||
var serverAttrs = model.parse(resp);
|
||||
if (options.parse === void 0) options.parse = true;
|
||||
success = options.success;
|
||||
options.success = function(model, resp, options) {
|
||||
// Ensure attributes are restored during synchronous saves.
|
||||
model.attributes = attributes;
|
||||
var serverAttrs = model.parse(resp, options);
|
||||
if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
|
||||
if (!model.set(serverAttrs, options)) return false;
|
||||
if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
|
||||
return false;
|
||||
}
|
||||
if (success) success(model, resp, options);
|
||||
};
|
||||
|
||||
// Finish configuring and sending the Ajax request.
|
||||
var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
|
||||
if (method == 'patch') options.attrs = attrs;
|
||||
var xhr = this.sync(method, this, options);
|
||||
method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
|
||||
if (method === 'patch') options.attrs = attrs;
|
||||
xhr = this.sync(method, this, options);
|
||||
|
||||
// When using `wait`, reset attributes to original values unless
|
||||
// `success` has been called already.
|
||||
if (!done && options.wait) {
|
||||
this.clear(silentOptions);
|
||||
this.set(current, silentOptions);
|
||||
}
|
||||
// Restore attributes.
|
||||
if (attrs && options.wait) this.attributes = attributes;
|
||||
|
||||
return xhr;
|
||||
},
|
||||
@@ -427,13 +487,13 @@
|
||||
model.trigger('destroy', model, model.collection, options);
|
||||
};
|
||||
|
||||
options.success = function(resp) {
|
||||
options.success = function(model, resp, options) {
|
||||
if (options.wait || model.isNew()) destroy();
|
||||
if (success) success(model, resp, options);
|
||||
};
|
||||
|
||||
if (this.isNew()) {
|
||||
options.success();
|
||||
options.success(this, null, options);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -453,7 +513,7 @@
|
||||
|
||||
// **parse** converts a response into the hash of attributes to be `set` on
|
||||
// the model. The default implementation is just to pass the response along.
|
||||
parse: function(resp) {
|
||||
parse: function(resp, options) {
|
||||
return resp;
|
||||
},
|
||||
|
||||
@@ -467,115 +527,20 @@
|
||||
return this.id == null;
|
||||
},
|
||||
|
||||
// Call this method to manually fire a `"change"` event for this model and
|
||||
// a `"change:attribute"` event for each changed attribute.
|
||||
// Calling this will cause all objects observing the model to update.
|
||||
change: function(options) {
|
||||
var changing = this._changing;
|
||||
this._changing = true;
|
||||
|
||||
// Generate the changes to be triggered on the model.
|
||||
var triggers = this._computeChanges(true);
|
||||
|
||||
this._pending = !!triggers.length;
|
||||
|
||||
for (var i = triggers.length - 2; i >= 0; i -= 2) {
|
||||
this.trigger('change:' + triggers[i], this, triggers[i + 1], options);
|
||||
}
|
||||
|
||||
if (changing) return this;
|
||||
|
||||
// Trigger a `change` while there have been changes.
|
||||
while (this._pending) {
|
||||
this._pending = false;
|
||||
this.trigger('change', this, options);
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
}
|
||||
|
||||
this._changing = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
// Determine if the model has changed since the last `"change"` event.
|
||||
// If you specify an attribute name, determine if that attribute has changed.
|
||||
hasChanged: function(attr) {
|
||||
if (!this._hasComputed) this._computeChanges();
|
||||
if (attr == null) return !_.isEmpty(this.changed);
|
||||
return _.has(this.changed, attr);
|
||||
},
|
||||
|
||||
// Return an object containing all the attributes that have changed, or
|
||||
// false if there are no changed attributes. Useful for determining what
|
||||
// parts of a view need to be updated and/or what attributes need to be
|
||||
// persisted to the server. Unset attributes will be set to undefined.
|
||||
// You can also pass an attributes object to diff against the model,
|
||||
// determining if there *would be* a change.
|
||||
changedAttributes: function(diff) {
|
||||
if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
|
||||
var val, changed = false, old = this._previousAttributes;
|
||||
for (var attr in diff) {
|
||||
if (_.isEqual(old[attr], (val = diff[attr]))) continue;
|
||||
(changed || (changed = {}))[attr] = val;
|
||||
}
|
||||
return changed;
|
||||
},
|
||||
|
||||
// Looking at the built up list of `set` attribute changes, compute how
|
||||
// many of the attributes have actually changed. If `loud`, return a
|
||||
// boiled-down list of only the real changes.
|
||||
_computeChanges: function(loud) {
|
||||
this.changed = {};
|
||||
var already = {};
|
||||
var triggers = [];
|
||||
var current = this._currentAttributes;
|
||||
var changes = this._changes;
|
||||
|
||||
// Loop through the current queue of potential model changes.
|
||||
for (var i = changes.length - 2; i >= 0; i -= 2) {
|
||||
var key = changes[i], val = changes[i + 1];
|
||||
if (already[key]) continue;
|
||||
already[key] = true;
|
||||
|
||||
// Check if the attribute has been modified since the last change,
|
||||
// and update `this.changed` accordingly. If we're inside of a `change`
|
||||
// call, also add a trigger to the list.
|
||||
if (!_.isEqual(current[key], val)) {
|
||||
this.changed[key] = val;
|
||||
if (!loud) continue;
|
||||
triggers.push(key, val);
|
||||
current[key] = val;
|
||||
}
|
||||
}
|
||||
if (loud) this._changes = [];
|
||||
|
||||
// Signals `this.changed` is current to prevent duplicate calls from `this.hasChanged`.
|
||||
this._hasComputed = true;
|
||||
return triggers;
|
||||
},
|
||||
|
||||
// Get the previous value of an attribute, recorded at the time the last
|
||||
// `"change"` event was fired.
|
||||
previous: function(attr) {
|
||||
if (attr == null || !this._previousAttributes) return null;
|
||||
return this._previousAttributes[attr];
|
||||
},
|
||||
|
||||
// Get all of the attributes of the model at the time of the previous
|
||||
// `"change"` event.
|
||||
previousAttributes: function() {
|
||||
return _.clone(this._previousAttributes);
|
||||
// Check if the model is currently in a valid state.
|
||||
isValid: function(options) {
|
||||
return !this.validate || !this.validate(this.attributes, options);
|
||||
},
|
||||
|
||||
// Run validation against the next complete set of model attributes,
|
||||
// returning `true` if all is well. If a specific `error` callback has
|
||||
// been passed, call that instead of firing the general `"error"` event.
|
||||
// returning `true` if all is well. Otherwise, fire a general
|
||||
// `"error"` event and call the error callback, if specified.
|
||||
_validate: function(attrs, options) {
|
||||
if (!this.validate) return true;
|
||||
if (!options.validate || !this.validate) return true;
|
||||
attrs = _.extend({}, this.attributes, attrs);
|
||||
var error = this.validate(attrs, options);
|
||||
var error = this.validationError = this.validate(attrs, options) || null;
|
||||
if (!error) return true;
|
||||
if (options && options.error) options.error(this, error, options);
|
||||
this.trigger('error', this, error, options);
|
||||
this.trigger('invalid', this, error, options || {});
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -591,6 +556,7 @@
|
||||
options || (options = {});
|
||||
if (options.model) this.model = options.model;
|
||||
if (options.comparator !== void 0) this.comparator = options.comparator;
|
||||
this.models = [];
|
||||
this._reset();
|
||||
this.initialize.apply(this, arguments);
|
||||
if (models) this.reset(models, _.extend({silent: true}, options));
|
||||
@@ -618,74 +584,81 @@
|
||||
return Backbone.sync.apply(this, arguments);
|
||||
},
|
||||
|
||||
// Add a model, or list of models to the set. Pass **silent** to avoid
|
||||
// firing the `add` event for every new model.
|
||||
// Add a model, or list of models to the set.
|
||||
add: function(models, options) {
|
||||
var i, args, length, model, existing, needsSort;
|
||||
var at = options && options.at;
|
||||
var sort = ((options && options.sort) == null ? true : options.sort);
|
||||
models = _.isArray(models) ? models.slice() : [models];
|
||||
options || (options = {});
|
||||
var i, l, model, attrs, existing, doSort, add, at, sort, sortAttr;
|
||||
add = [];
|
||||
at = options.at;
|
||||
sort = this.comparator && (at == null) && options.sort != false;
|
||||
sortAttr = _.isString(this.comparator) ? this.comparator : null;
|
||||
|
||||
// Turn bare objects into model references, and prevent invalid models
|
||||
// from being added.
|
||||
for (i = models.length - 1; i >= 0; i--) {
|
||||
if(!(model = this._prepareModel(models[i], options))) {
|
||||
this.trigger("error", this, models[i], options);
|
||||
models.splice(i, 1);
|
||||
for (i = 0, l = models.length; i < l; i++) {
|
||||
if (!(model = this._prepareModel(attrs = models[i], options))) {
|
||||
this.trigger('invalid', this, attrs, options);
|
||||
continue;
|
||||
}
|
||||
models[i] = model;
|
||||
|
||||
existing = model.id != null && this._byId[model.id];
|
||||
// If a duplicate is found, prevent it from being added and
|
||||
// optionally merge it into the existing model.
|
||||
if (existing || this._byCid[model.cid]) {
|
||||
if (options && options.merge && existing) {
|
||||
existing.set(model.attributes, options);
|
||||
needsSort = sort;
|
||||
if (existing = this.get(model)) {
|
||||
if (options.merge) {
|
||||
existing.set(attrs === model ? model.attributes : attrs, options);
|
||||
if (sort && !doSort && existing.hasChanged(sortAttr)) doSort = true;
|
||||
}
|
||||
models.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is a new model, push it to the `add` list.
|
||||
add.push(model);
|
||||
|
||||
// Listen to added models' events, and index models for lookup by
|
||||
// `id` and by `cid`.
|
||||
model.on('all', this._onModelEvent, this);
|
||||
this._byCid[model.cid] = model;
|
||||
this._byId[model.cid] = model;
|
||||
if (model.id != null) this._byId[model.id] = model;
|
||||
}
|
||||
|
||||
// See if sorting is needed, update `length` and splice in new models.
|
||||
if (models.length) needsSort = sort;
|
||||
this.length += models.length;
|
||||
args = [at != null ? at : this.models.length, 0];
|
||||
push.apply(args, models);
|
||||
splice.apply(this.models, args);
|
||||
if (add.length) {
|
||||
if (sort) doSort = true;
|
||||
this.length += add.length;
|
||||
if (at != null) {
|
||||
splice.apply(this.models, [at, 0].concat(add));
|
||||
} else {
|
||||
push.apply(this.models, add);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the collection if appropriate.
|
||||
if (needsSort && this.comparator && at == null) this.sort({silent: true});
|
||||
// Silently sort the collection if appropriate.
|
||||
if (doSort) this.sort({silent: true});
|
||||
|
||||
if (options && options.silent) return this;
|
||||
if (options.silent) return this;
|
||||
|
||||
// Trigger `add` events.
|
||||
while (model = models.shift()) {
|
||||
model.trigger('add', model, this, options);
|
||||
for (i = 0, l = add.length; i < l; i++) {
|
||||
(model = add[i]).trigger('add', model, this, options);
|
||||
}
|
||||
|
||||
// Trigger `sort` if the collection was sorted.
|
||||
if (doSort) this.trigger('sort', this, options);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Remove a model, or a list of models from the set. Pass silent to avoid
|
||||
// firing the `remove` event for every model removed.
|
||||
// Remove a model, or a list of models from the set.
|
||||
remove: function(models, options) {
|
||||
var i, l, index, model;
|
||||
options || (options = {});
|
||||
models = _.isArray(models) ? models.slice() : [models];
|
||||
options || (options = {});
|
||||
var i, l, index, model;
|
||||
for (i = 0, l = models.length; i < l; i++) {
|
||||
model = this.get(models[i]);
|
||||
if (!model) continue;
|
||||
delete this._byId[model.id];
|
||||
delete this._byCid[model.cid];
|
||||
delete this._byId[model.cid];
|
||||
index = this.indexOf(model);
|
||||
this.models.splice(index, 1);
|
||||
this.length--;
|
||||
@@ -734,7 +707,8 @@
|
||||
// Get a model from the set by id.
|
||||
get: function(obj) {
|
||||
if (obj == null) return void 0;
|
||||
return this._byId[obj.id != null ? obj.id : obj] || this._byCid[obj.cid || obj];
|
||||
this._idAttr || (this._idAttr = this.model.prototype.idAttribute);
|
||||
return this._byId[obj.id || obj.cid || obj[this._idAttr] || obj];
|
||||
},
|
||||
|
||||
// Get the model at the given index.
|
||||
@@ -760,14 +734,16 @@
|
||||
if (!this.comparator) {
|
||||
throw new Error('Cannot sort a set without a comparator');
|
||||
}
|
||||
options || (options = {});
|
||||
|
||||
// Run sort based on type of `comparator`.
|
||||
if (_.isString(this.comparator) || this.comparator.length === 1) {
|
||||
this.models = this.sortBy(this.comparator, this);
|
||||
} else {
|
||||
this.models.sort(_.bind(this.comparator, this));
|
||||
}
|
||||
|
||||
if (!options || !options.silent) this.trigger('sort', this, options);
|
||||
if (!options.silent) this.trigger('sort', this, options);
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -779,11 +755,10 @@
|
||||
// Smartly update a collection with a change set of models, adding,
|
||||
// removing, and merging as necessary.
|
||||
update: function(models, options) {
|
||||
options = _.extend({add: true, merge: true, remove: true}, options);
|
||||
if (options.parse) models = this.parse(models, options);
|
||||
var model, i, l, existing;
|
||||
var add = [], remove = [], modelMap = {};
|
||||
var idAttr = this.model.prototype.idAttribute;
|
||||
options = _.extend({add: true, merge: true, remove: true}, options);
|
||||
if (options.parse) models = this.parse(models);
|
||||
|
||||
// Allow a single model (or no argument) to be passed.
|
||||
if (!_.isArray(models)) models = models ? [models] : [];
|
||||
@@ -794,7 +769,7 @@
|
||||
// Determine which models to add and merge, and which to remove.
|
||||
for (i = 0, l = models.length; i < l; i++) {
|
||||
model = models[i];
|
||||
existing = this.get(model.id || model.cid || model[idAttr]);
|
||||
existing = this.get(model);
|
||||
if (options.remove && existing) modelMap[existing.cid] = true;
|
||||
if ((options.add && !existing) || (options.merge && existing)) {
|
||||
add.push(model);
|
||||
@@ -818,11 +793,11 @@
|
||||
// any `add` or `remove` events. Fires `reset` when finished.
|
||||
reset: function(models, options) {
|
||||
options || (options = {});
|
||||
if (options.parse) models = this.parse(models);
|
||||
if (options.parse) models = this.parse(models, options);
|
||||
for (var i = 0, l = this.models.length; i < l; i++) {
|
||||
this._removeReference(this.models[i]);
|
||||
}
|
||||
options.previousModels = this.models;
|
||||
options.previousModels = this.models.slice();
|
||||
this._reset();
|
||||
if (models) this.add(models, _.extend({silent: true}, options));
|
||||
if (!options.silent) this.trigger('reset', this, options);
|
||||
@@ -830,14 +805,13 @@
|
||||
},
|
||||
|
||||
// Fetch the default set of models for this collection, resetting the
|
||||
// collection when they arrive. If `add: true` is passed, appends the
|
||||
// models to the collection instead of resetting.
|
||||
// collection when they arrive. If `update: true` is passed, the response
|
||||
// data will be passed through the `update` method instead of `reset`.
|
||||
fetch: function(options) {
|
||||
options = options ? _.clone(options) : {};
|
||||
if (options.parse === void 0) options.parse = true;
|
||||
var collection = this;
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
options.success = function(collection, resp, options) {
|
||||
var method = options.update ? 'update' : 'reset';
|
||||
collection[method](resp, options);
|
||||
if (success) success(collection, resp, options);
|
||||
@@ -849,11 +823,10 @@
|
||||
// collection immediately, unless `wait: true` is passed, in which case we
|
||||
// wait for the server to agree.
|
||||
create: function(model, options) {
|
||||
var collection = this;
|
||||
options = options ? _.clone(options) : {};
|
||||
model = this._prepareModel(model, options);
|
||||
if (!model) return false;
|
||||
if (!options.wait) collection.add(model, options);
|
||||
if (!(model = this._prepareModel(model, options))) return false;
|
||||
if (!options.wait) this.add(model, options);
|
||||
var collection = this;
|
||||
var success = options.success;
|
||||
options.success = function(model, resp, options) {
|
||||
if (options.wait) collection.add(model, options);
|
||||
@@ -865,7 +838,7 @@
|
||||
|
||||
// **parse** converts a response into a list of models to be added to the
|
||||
// collection. The default implementation is just to pass it through.
|
||||
parse: function(resp) {
|
||||
parse: function(resp, options) {
|
||||
return resp;
|
||||
},
|
||||
|
||||
@@ -874,19 +847,11 @@
|
||||
return new this.constructor(this.models);
|
||||
},
|
||||
|
||||
// Proxy to _'s chain. Can't be proxied the same way the rest of the
|
||||
// underscore methods are proxied because it relies on the underscore
|
||||
// constructor.
|
||||
chain: function() {
|
||||
return _(this.models).chain();
|
||||
},
|
||||
|
||||
// Reset all internal state. Called when the collection is reset.
|
||||
_reset: function() {
|
||||
this.length = 0;
|
||||
this.models = [];
|
||||
this.models.length = 0;
|
||||
this._byId = {};
|
||||
this._byCid = {};
|
||||
},
|
||||
|
||||
// Prepare a model or hash of attributes to be added to this collection.
|
||||
@@ -920,6 +885,14 @@
|
||||
if (model.id != null) this._byId[model.id] = model;
|
||||
}
|
||||
this.trigger.apply(this, arguments);
|
||||
},
|
||||
|
||||
sortedIndex: function (model, value, context) {
|
||||
value || (value = this.comparator);
|
||||
var iterator = _.isFunction(value) ? value : function(model) {
|
||||
return model.get(value);
|
||||
};
|
||||
return _.sortedIndex(this.models, model, iterator, context);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -928,9 +901,9 @@
|
||||
var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
|
||||
'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
|
||||
'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
|
||||
'max', 'min', 'sortedIndex', 'toArray', 'size', 'first', 'head', 'take',
|
||||
'initial', 'rest', 'tail', 'last', 'without', 'indexOf', 'shuffle',
|
||||
'lastIndexOf', 'isEmpty'];
|
||||
'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
|
||||
'tail', 'drop', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf',
|
||||
'isEmpty', 'chain'];
|
||||
|
||||
// Mix in each Underscore method as a proxy to `Collection#models`.
|
||||
_.each(methods, function(method) {
|
||||
@@ -969,7 +942,7 @@
|
||||
// Cached regular expressions for matching named param parts and splatted
|
||||
// parts of route strings.
|
||||
var optionalParam = /\((.*?)\)/g;
|
||||
var namedParam = /:\w+/g;
|
||||
var namedParam = /(\(\?)?:\w+/g;
|
||||
var splatParam = /\*\w+/g;
|
||||
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
|
||||
|
||||
@@ -993,6 +966,7 @@
|
||||
var args = this._extractParameters(route, fragment);
|
||||
callback && callback.apply(this, args);
|
||||
this.trigger.apply(this, ['route:' + name].concat(args));
|
||||
this.trigger('route', name, args);
|
||||
Backbone.history.trigger('route', this, name, args);
|
||||
}, this));
|
||||
return this;
|
||||
@@ -1020,7 +994,9 @@
|
||||
_routeToRegExp: function(route) {
|
||||
route = route.replace(escapeRegExp, '\\$&')
|
||||
.replace(optionalParam, '(?:$1)?')
|
||||
.replace(namedParam, '([^\/]+)')
|
||||
.replace(namedParam, function(match, optional){
|
||||
return optional ? match : '([^\/]+)';
|
||||
})
|
||||
.replace(splatParam, '(.*?)');
|
||||
return new RegExp('^' + route + '$');
|
||||
},
|
||||
@@ -1121,9 +1097,9 @@
|
||||
// Depending on whether we're using pushState or hashes, and whether
|
||||
// 'onhashchange' is supported, determine how we check the URL state.
|
||||
if (this._hasPushState) {
|
||||
Backbone.$(window).bind('popstate', this.checkUrl);
|
||||
Backbone.$(window).on('popstate', this.checkUrl);
|
||||
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
|
||||
Backbone.$(window).bind('hashchange', this.checkUrl);
|
||||
Backbone.$(window).on('hashchange', this.checkUrl);
|
||||
} else if (this._wantsHashChange) {
|
||||
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
|
||||
}
|
||||
@@ -1155,7 +1131,7 @@
|
||||
// Disable Backbone.history, perhaps temporarily. Not useful in a real app,
|
||||
// but possibly useful for unit testing Routers.
|
||||
stop: function() {
|
||||
Backbone.$(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
|
||||
Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
|
||||
clearInterval(this._checkUrlInterval);
|
||||
History.started = false;
|
||||
},
|
||||
@@ -1298,18 +1274,6 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
// For small amounts of DOM Elements, where a full-blown template isn't
|
||||
// needed, use **make** to manufacture elements, one at a time.
|
||||
//
|
||||
// var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
|
||||
//
|
||||
make: function(tagName, attributes, content) {
|
||||
var el = document.createElement(tagName);
|
||||
if (attributes) Backbone.$(el).attr(attributes);
|
||||
if (content != null) Backbone.$(el).html(content);
|
||||
return el;
|
||||
},
|
||||
|
||||
// Change the view's element (`this.el` property), including event
|
||||
// re-delegation.
|
||||
setElement: function(element, delegate) {
|
||||
@@ -1347,9 +1311,9 @@
|
||||
method = _.bind(method, this);
|
||||
eventName += '.delegateEvents' + this.cid;
|
||||
if (selector === '') {
|
||||
this.$el.bind(eventName, method);
|
||||
this.$el.on(eventName, method);
|
||||
} else {
|
||||
this.$el.delegate(selector, eventName, method);
|
||||
this.$el.on(eventName, selector, method);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1358,7 +1322,7 @@
|
||||
// You usually don't need to use this, but may wish to if you have multiple
|
||||
// Backbone views attached to the same DOM element.
|
||||
undelegateEvents: function() {
|
||||
this.$el.unbind('.delegateEvents' + this.cid);
|
||||
this.$el.off('.delegateEvents' + this.cid);
|
||||
},
|
||||
|
||||
// Performs the initial configuration of a View with a set of options.
|
||||
@@ -1379,7 +1343,8 @@
|
||||
var attrs = _.extend({}, _.result(this, 'attributes'));
|
||||
if (this.id) attrs.id = _.result(this, 'id');
|
||||
if (this.className) attrs['class'] = _.result(this, 'className');
|
||||
this.setElement(this.make(_.result(this, 'tagName'), attrs), false);
|
||||
var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
|
||||
this.setElement($el, false);
|
||||
} else {
|
||||
this.setElement(_.result(this, 'el'), false);
|
||||
}
|
||||
@@ -1461,19 +1426,19 @@
|
||||
}
|
||||
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
if (success) success(resp, status, xhr);
|
||||
options.success = function(resp) {
|
||||
if (success) success(model, resp, options);
|
||||
model.trigger('sync', model, resp, options);
|
||||
};
|
||||
|
||||
var error = options.error;
|
||||
options.error = function(xhr, status, thrown) {
|
||||
options.error = function(xhr) {
|
||||
if (error) error(model, xhr, options);
|
||||
model.trigger('error', model, xhr, options);
|
||||
};
|
||||
|
||||
// Make the request, allowing the user to override any Ajax options.
|
||||
var xhr = Backbone.ajax(_.extend(params, options));
|
||||
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
|
||||
model.trigger('request', model, xhr, options);
|
||||
return xhr;
|
||||
};
|
||||
@@ -1499,7 +1464,7 @@
|
||||
if (protoProps && _.has(protoProps, 'constructor')) {
|
||||
child = protoProps.constructor;
|
||||
} else {
|
||||
child = function(){ parent.apply(this, arguments); };
|
||||
child = function(){ return parent.apply(this, arguments); };
|
||||
}
|
||||
|
||||
// Add static properties to the constructor function, if supplied.
|
||||
|
||||
159
vendor/backbone/test/collection.js
vendored
159
vendor/backbone/test/collection.js
vendored
@@ -62,13 +62,15 @@ $(document).ready(function() {
|
||||
strictEqual(collection.last().get('a'), 4);
|
||||
});
|
||||
|
||||
test("get", 3, function() {
|
||||
test("get", 5, function() {
|
||||
equal(col.get(0), d);
|
||||
equal(col.get(2), b);
|
||||
equal(col.get({id: 1}), c);
|
||||
equal(col.get(c.clone()), c);
|
||||
equal(col.get(col.first().cid), col.first());
|
||||
});
|
||||
|
||||
test("get with non-default ids", 2, function() {
|
||||
test("get with non-default ids", 4, function() {
|
||||
var col = new Backbone.Collection();
|
||||
var MongoModel = Backbone.Model.extend({
|
||||
idAttribute: '_id'
|
||||
@@ -78,6 +80,12 @@ $(document).ready(function() {
|
||||
equal(col.get(100), model);
|
||||
model.set({_id: 101});
|
||||
equal(col.get(101), model);
|
||||
|
||||
var Col2 = Backbone.Collection.extend({ model: MongoModel });
|
||||
var col2 = new Col2();
|
||||
col2.push(model);
|
||||
equal(col2.get({_id: 101}), model);
|
||||
equal(col2.get(model.clone()), model);
|
||||
});
|
||||
|
||||
test("update index when id changes", 3, function() {
|
||||
@@ -354,7 +362,9 @@ $(document).ready(function() {
|
||||
|
||||
test("model destroy removes from all collections", 3, function() {
|
||||
var e = new Backbone.Model({id: 5, title: 'Othello'});
|
||||
e.sync = function(method, model, options) { options.success({}); };
|
||||
e.sync = function(method, model, options) {
|
||||
options.success(model, [], options);
|
||||
};
|
||||
var colE = new Backbone.Collection([e]);
|
||||
var colF = new Backbone.Collection([e]);
|
||||
e.destroy();
|
||||
@@ -409,7 +419,7 @@ $(document).ready(function() {
|
||||
equal(model.collection, collection);
|
||||
});
|
||||
|
||||
test("create enforces validation", 1, function() {
|
||||
test("create with validate:true enforces validation", 1, function() {
|
||||
var ValidatingModel = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
return "fail";
|
||||
@@ -419,10 +429,10 @@ $(document).ready(function() {
|
||||
model: ValidatingModel
|
||||
});
|
||||
var col = new ValidatingCollection();
|
||||
equal(col.create({"foo":"bar"}), false);
|
||||
equal(col.create({"foo":"bar"}, {validate:true}), false);
|
||||
});
|
||||
|
||||
test("a failing create runs the error callback", 1, function() {
|
||||
test("a failing create returns model with errors", function() {
|
||||
var ValidatingModel = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
return "fail";
|
||||
@@ -431,11 +441,10 @@ $(document).ready(function() {
|
||||
var ValidatingCollection = Backbone.Collection.extend({
|
||||
model: ValidatingModel
|
||||
});
|
||||
var flag = false;
|
||||
var callback = function(model, error) { flag = true; };
|
||||
var col = new ValidatingCollection();
|
||||
col.create({"foo":"bar"}, { error: callback });
|
||||
equal(flag, true);
|
||||
var m = col.create({"foo":"bar"});
|
||||
equal(m.validationError, 'fail');
|
||||
equal(col.length, 1);
|
||||
});
|
||||
|
||||
test("initialize", 1, function() {
|
||||
@@ -488,9 +497,21 @@ $(document).ready(function() {
|
||||
[4, 0]);
|
||||
});
|
||||
|
||||
test("sortedIndex", function () {
|
||||
var model = new Backbone.Model({key: 2});
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: 'key'
|
||||
}))([model, {key: 1}]);
|
||||
equal(collection.sortedIndex(model), 1);
|
||||
equal(collection.sortedIndex(model, 'key'), 1);
|
||||
equal(collection.sortedIndex(model, function (model) {
|
||||
return model.get('key');
|
||||
}), 1);
|
||||
});
|
||||
|
||||
test("reset", 10, function() {
|
||||
var resetCount = 0;
|
||||
var models = col.models;
|
||||
var models = col.models.slice();
|
||||
col.on('reset', function() { resetCount += 1; });
|
||||
col.reset([]);
|
||||
equal(resetCount, 1);
|
||||
@@ -559,7 +580,7 @@ $(document).ready(function() {
|
||||
equal(col.length, 0);
|
||||
});
|
||||
|
||||
test("#861, adding models to a collection which do not pass validation", function() {
|
||||
test("#861, adding models to a collection which do not pass validation, with validate:true", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
if (attrs.id == 3) return "id can't be 3";
|
||||
@@ -573,18 +594,18 @@ $(document).ready(function() {
|
||||
var collection = new Collection;
|
||||
collection.on("error", function() { ok(true); });
|
||||
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate:true});
|
||||
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
|
||||
});
|
||||
|
||||
test("Invalid models are discarded.", 5, function() {
|
||||
test("Invalid models are discarded with validate:true.", 5, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.on('test', function() { ok(true); });
|
||||
collection.model = Backbone.Model.extend({
|
||||
validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
|
||||
});
|
||||
var model = new collection.model({id: 1, valid: true});
|
||||
collection.add([model, {id: 2}]);
|
||||
collection.add([model, {id: 2}], {validate:true});
|
||||
model.trigger('test');
|
||||
ok(collection.get(model.cid));
|
||||
ok(collection.get(1));
|
||||
@@ -648,25 +669,42 @@ $(document).ready(function() {
|
||||
}
|
||||
};
|
||||
col.sync = m.sync = function( method, collection, options ){
|
||||
options.success();
|
||||
options.success(collection, [], options);
|
||||
};
|
||||
col.fetch(opts);
|
||||
col.create(m, opts);
|
||||
});
|
||||
|
||||
test("#1412 - Trigger 'sync' event.", 2, function() {
|
||||
test("#1412 - Trigger 'request' and 'sync' events.", 4, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.url = '/test';
|
||||
collection.on('sync', function() { ok(true); });
|
||||
Backbone.ajax = function(settings){ settings.success(); };
|
||||
|
||||
collection.on('request', function(obj, xhr, options) {
|
||||
ok(obj === collection, "collection has correct 'request' event after fetching");
|
||||
});
|
||||
collection.on('sync', function(obj, response, options) {
|
||||
ok(obj === collection, "collection has correct 'sync' event after fetching");
|
||||
});
|
||||
collection.fetch();
|
||||
collection.off();
|
||||
|
||||
collection.on('request', function(obj, xhr, options) {
|
||||
ok(obj === collection.get(1), "collection has correct 'request' event after one of its models save");
|
||||
});
|
||||
collection.on('sync', function(obj, response, options) {
|
||||
ok(obj === collection.get(1), "collection has correct 'sync' event after one of its models save");
|
||||
});
|
||||
collection.create({id: 1});
|
||||
collection.off();
|
||||
});
|
||||
|
||||
test("#1447 - create with wait adds model.", 1, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
var model = new Backbone.Model;
|
||||
model.sync = function(method, model, options){ options.success(); };
|
||||
model.sync = function(method, model, options){
|
||||
options.success(model, [], options);
|
||||
};
|
||||
collection.on('add', function(){ ok(true); });
|
||||
collection.create(model, {wait: true});
|
||||
});
|
||||
@@ -872,6 +910,24 @@ $(document).ready(function() {
|
||||
equal(c.length, 2);
|
||||
});
|
||||
|
||||
test("update + merge with default values defined", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
defaults: {
|
||||
key: 'value'
|
||||
}
|
||||
});
|
||||
var m = new Model({id: 1});
|
||||
var col = new Backbone.Collection([m], {model: Model});
|
||||
equal(col.first().get('key'), 'value');
|
||||
|
||||
col.update({id: 1, key: 'other'});
|
||||
equal(col.first().get('key'), 'other');
|
||||
|
||||
col.update({id: 1, other: 'value'});
|
||||
equal(col.first().get('key'), 'other');
|
||||
equal(col.length, 1);
|
||||
});
|
||||
|
||||
test("#1894 - Push should not trigger a sort", 0, function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
comparator: 'id',
|
||||
@@ -882,14 +938,14 @@ $(document).ready(function() {
|
||||
new Collection().push({id: 1});
|
||||
});
|
||||
|
||||
// test("`update` with non-normal id", function() {
|
||||
// var Collection = Backbone.Collection.extend({
|
||||
// model: Backbone.Model.extend({idAttribute: '_id'})
|
||||
// });
|
||||
// var collection = new Collection({_id: 1});
|
||||
// collection.update([{_id: 1, a: 1}], {add: false});
|
||||
// equal(collection.first().get('a'), 1);
|
||||
// });
|
||||
test("`update` with non-normal id", function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({idAttribute: '_id'})
|
||||
});
|
||||
var collection = new Collection({_id: 1});
|
||||
collection.update([{_id: 1, a: 1}], {add: false});
|
||||
equal(collection.first().get('a'), 1);
|
||||
});
|
||||
|
||||
test("#1894 - `sort` can optionally be turned off", 0, function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
@@ -906,8 +962,55 @@ $(document).ready(function() {
|
||||
return data.data;
|
||||
}
|
||||
}));
|
||||
var res = {status: 'ok', data:[{id: 1}]}
|
||||
var res = {status: 'ok', data:[{id: 1}]};
|
||||
collection.update(res, {parse: true});
|
||||
});
|
||||
|
||||
asyncTest("#1939 - `parse` is passed `options`", 1, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
url: '/',
|
||||
parse: function (data, options) {
|
||||
strictEqual(options.xhr.someHeader, 'headerValue');
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
var ajax = Backbone.ajax;
|
||||
Backbone.ajax = function (params) {
|
||||
_.defer(params.success);
|
||||
return {someHeader: 'headerValue'};
|
||||
};
|
||||
collection.fetch({
|
||||
success: function () { start(); }
|
||||
});
|
||||
Backbone.ajax = ajax;
|
||||
});
|
||||
|
||||
test("`add` only `sort`s when necessary", 2, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: 'a'
|
||||
}))([{id: 1}, {id: 2}, {id: 3}]);
|
||||
collection.on('sort', function () { ok(true); });
|
||||
collection.add({id: 4}); // do sort, new model
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // do sort, comparator change
|
||||
collection.add({id: 1, b: 1}, {merge: true}); // don't sort, no comparator change
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no comparator change
|
||||
collection.add(collection.models); // don't sort, nothing new
|
||||
collection.add(collection.models, {merge: true}); // don't sort
|
||||
});
|
||||
|
||||
test("`add` only `sort`s when necessary with comparator function", 3, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: function(a, b) {
|
||||
a.get('a') > b.get('a') ? 1 : (a.get('a') < b.get('a') ? -1 : 0);
|
||||
}
|
||||
}))([{id: 1}, {id: 2}, {id: 3}]);
|
||||
collection.on('sort', function () { ok(true); });
|
||||
collection.add({id: 4}); // do sort, new model
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // do sort, model change
|
||||
collection.add({id: 1, b: 1}, {merge: true}); // do sort, model change
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no model change
|
||||
collection.add(collection.models); // don't sort, nothing new
|
||||
collection.add(collection.models, {merge: true}); // don't sort
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
50
vendor/backbone/test/events.js
vendored
50
vendor/backbone/test/events.js
vendored
@@ -76,14 +76,50 @@ $(document).ready(function() {
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo and stopListening with event maps", 1, function() {
|
||||
test("listenTo and stopListening with event maps", 4, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenTo(b, {change: function(){ ok(true); }});
|
||||
b.trigger('change');
|
||||
a.listenTo(b, {change: function(){ ok(false); }});
|
||||
var cb = function(){ ok(true); };
|
||||
a.listenTo(b, {event: cb});
|
||||
b.trigger('event');
|
||||
a.listenTo(b, {event2: cb});
|
||||
b.on('event2', cb);
|
||||
a.stopListening(b, {event2: cb});
|
||||
b.trigger('event event2');
|
||||
a.stopListening();
|
||||
b.trigger('change');
|
||||
b.trigger('event event2');
|
||||
});
|
||||
|
||||
test("stopListening with omitted args", 2, function () {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var cb = function () { ok(true); };
|
||||
a.listenTo(b, 'event', cb);
|
||||
b.on('event', cb);
|
||||
a.listenTo(b, 'event2', cb);
|
||||
a.stopListening(null, {event: cb});
|
||||
b.trigger('event event2');
|
||||
});
|
||||
|
||||
test("listenTo yourself", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", function(){ ok(true); });
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
test("listenTo yourself cleans yourself up with stopListening", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", function(){ ok(true); });
|
||||
e.trigger("foo");
|
||||
e.stopListening();
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
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");
|
||||
ok(true);
|
||||
});
|
||||
|
||||
test("trigger all for each event", 3, function() {
|
||||
@@ -360,4 +396,8 @@ $(document).ready(function() {
|
||||
Backbone.trigger('all');
|
||||
});
|
||||
|
||||
test("once without a callback is a noop", 0, function() {
|
||||
_.extend({}, Backbone.Events).once('event').trigger('event');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
301
vendor/backbone/test/model.js
vendored
301
vendor/backbone/test/model.js
vendored
@@ -202,9 +202,9 @@ $(document).ready(function() {
|
||||
ok(changeCount == 1, "Change count should NOT have incremented.");
|
||||
|
||||
a.validate = function(attrs) {
|
||||
equal(attrs.foo, void 0, "don't ignore values when unsetting");
|
||||
equal(attrs.foo, void 0, "validate:true passed while unsetting");
|
||||
};
|
||||
a.unset('foo');
|
||||
a.unset('foo', {validate: true});
|
||||
equal(a.get('foo'), void 0, "Foo should have changed");
|
||||
delete a.validate;
|
||||
ok(changeCount == 2, "Change count should have incremented for unset.");
|
||||
@@ -213,6 +213,24 @@ $(document).ready(function() {
|
||||
equal(a.id, undefined, "Unsetting the id should remove the id property.");
|
||||
});
|
||||
|
||||
test("#2030 - set with failed validate, followed by another set triggers change", function () {
|
||||
var attr = 0, main = 0, error = 0;
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function (attr) {
|
||||
if (attr.x > 1) {
|
||||
error++;
|
||||
return "this is an error";
|
||||
}
|
||||
}
|
||||
});
|
||||
var model = new Model({x:0});
|
||||
model.on('change:x', function () { attr++; });
|
||||
model.on('change', function () { main++; });
|
||||
model.set({x:2}, {validate:true});
|
||||
model.set({x:1}, {validate:true});
|
||||
deepEqual([attr, main, error], [1, 1, 1]);
|
||||
});
|
||||
|
||||
test("set triggers changes in the correct order", function() {
|
||||
var value = null;
|
||||
var model = new Backbone.Model;
|
||||
@@ -223,15 +241,16 @@ $(document).ready(function() {
|
||||
equal(value, 'last');
|
||||
});
|
||||
|
||||
test("set falsy values in the correct order", 1, function() {
|
||||
test("set falsy values in the correct order", 2, function() {
|
||||
var model = new Backbone.Model({result: 'result'});
|
||||
model.on('change', function() {
|
||||
equal(model.changed.result, false);
|
||||
equal(model.changed.result, void 0);
|
||||
equal(model.previous('result'), false);
|
||||
});
|
||||
model.set({result: void 0}, {silent: true});
|
||||
model.set({result: null}, {silent: true});
|
||||
model.set({result: false}, {silent: true});
|
||||
model.change();
|
||||
model.set({result: void 0});
|
||||
});
|
||||
|
||||
test("multiple unsets", 1, function() {
|
||||
@@ -245,14 +264,12 @@ $(document).ready(function() {
|
||||
equal(i, 2, 'Unset does not fire an event for missing attributes.');
|
||||
});
|
||||
|
||||
test("unset and changedAttributes", 2, function() {
|
||||
test("unset and changedAttributes", 1, function() {
|
||||
var model = new Backbone.Model({a: 1});
|
||||
model.unset('a', {silent: true});
|
||||
var changedAttributes = model.changedAttributes();
|
||||
ok('a' in changedAttributes, 'changedAttributes should contain unset properties');
|
||||
|
||||
changedAttributes = model.changedAttributes();
|
||||
ok('a' in changedAttributes, 'changedAttributes should contain unset properties when running changedAttributes again after an unset.');
|
||||
model.on('change', function() {
|
||||
ok('a' in model.changedAttributes(), 'changedAttributes should contain unset properties');
|
||||
});
|
||||
model.unset('a');
|
||||
});
|
||||
|
||||
test("using a non-default id attribute.", 5, function() {
|
||||
@@ -272,6 +289,21 @@ $(document).ready(function() {
|
||||
equal(model.get('name'), '');
|
||||
});
|
||||
|
||||
test("setting an object", 1, function() {
|
||||
var model = new Backbone.Model({
|
||||
custom: { foo: 1 }
|
||||
});
|
||||
model.on('change', function() {
|
||||
ok(1);
|
||||
});
|
||||
model.set({
|
||||
custom: { foo: 1 } // no change should be fired
|
||||
});
|
||||
model.set({
|
||||
custom: { foo: 2 } // change event should be fired
|
||||
});
|
||||
});
|
||||
|
||||
test("clear", 3, function() {
|
||||
var changed;
|
||||
var model = new Backbone.Model({id: 1, name : "Model"});
|
||||
@@ -308,9 +340,9 @@ $(document).ready(function() {
|
||||
equal(model.get('two'), 4);
|
||||
});
|
||||
|
||||
test("change, hasChanged, changedAttributes, previous, previousAttributes", 12, function() {
|
||||
var model = new Backbone.Model({name : "Tim", age : 10});
|
||||
equal(model.changedAttributes(), false);
|
||||
test("change, hasChanged, changedAttributes, previous, previousAttributes", 9, function() {
|
||||
var model = new Backbone.Model({name: "Tim", age: 10});
|
||||
deepEqual(model.changedAttributes(), false);
|
||||
model.on('change', function() {
|
||||
ok(model.hasChanged('name'), 'name changed');
|
||||
ok(!model.hasChanged('age'), 'age did not');
|
||||
@@ -320,17 +352,13 @@ $(document).ready(function() {
|
||||
});
|
||||
equal(model.hasChanged(), false);
|
||||
equal(model.hasChanged(undefined), false);
|
||||
model.set({name : 'Rob'}, {silent : true});
|
||||
equal(model.hasChanged(), true);
|
||||
equal(model.hasChanged(undefined), true);
|
||||
equal(model.hasChanged('name'), true);
|
||||
model.change();
|
||||
model.set({name : 'Rob'});
|
||||
equal(model.get('name'), 'Rob');
|
||||
});
|
||||
|
||||
test("changedAttributes", 3, function() {
|
||||
var model = new Backbone.Model({a: 'a', b: 'b'});
|
||||
equal(model.changedAttributes(), false);
|
||||
deepEqual(model.changedAttributes(), false);
|
||||
equal(model.changedAttributes({a: 'a'}), false);
|
||||
equal(model.changedAttributes({a: 'b'}).a, 'b');
|
||||
});
|
||||
@@ -341,8 +369,7 @@ $(document).ready(function() {
|
||||
model.on('change', function(model, options) {
|
||||
value = options.prefix + model.get('name');
|
||||
});
|
||||
model.set({name: 'Bob'}, {silent: true});
|
||||
model.change({prefix: 'Mr. '});
|
||||
model.set({name: 'Bob'}, {prefix: 'Mr. '});
|
||||
equal(value, 'Mr. Bob');
|
||||
model.set({name: 'Sue'}, {prefix: 'Ms. '});
|
||||
equal(value, 'Ms. Sue');
|
||||
@@ -368,19 +395,21 @@ $(document).ready(function() {
|
||||
model.set({lastName: 'Hicks'});
|
||||
});
|
||||
|
||||
test("validate after save", 1, function() {
|
||||
test("validate after save", 2, function() {
|
||||
var lastError, model = new Backbone.Model();
|
||||
model.validate = function(attrs) {
|
||||
if (attrs.admin) return "Can't change admin status.";
|
||||
};
|
||||
model.sync = function(method, model, options) {
|
||||
options.success.call(this, {admin: true});
|
||||
options.success.call(this, this, {admin: true}, options);
|
||||
};
|
||||
model.save(null, {error: function(model, error) {
|
||||
model.on('invalid', function(model, error) {
|
||||
lastError = error;
|
||||
}});
|
||||
});
|
||||
model.save(null);
|
||||
|
||||
equal(lastError, "Can't change admin status.");
|
||||
equal(model.validationError, "Can't change admin status.");
|
||||
});
|
||||
|
||||
test("save", 2, function() {
|
||||
@@ -406,13 +435,24 @@ $(document).ready(function() {
|
||||
test("save in positional style", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.sync = function(method, model, options) {
|
||||
options.success();
|
||||
options.success(model, {}, options);
|
||||
};
|
||||
model.save('title', 'Twelfth Night');
|
||||
equal(model.get('title'), 'Twelfth Night');
|
||||
});
|
||||
|
||||
|
||||
test("save with non-object success response", 2, function () {
|
||||
var model = new Backbone.Model();
|
||||
model.sync = function(method, model, options) {
|
||||
options.success(model, '', options);
|
||||
options.success(model, null, options);
|
||||
};
|
||||
model.save({testing:'empty'}, {
|
||||
success: function (model) {
|
||||
deepEqual(model.attributes, {testing:'empty'});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("fetch", 2, function() {
|
||||
doc.fetch();
|
||||
@@ -442,14 +482,16 @@ $(document).ready(function() {
|
||||
model.validate = function(attrs) {
|
||||
if (attrs.admin != this.get('admin')) return "Can't change admin status.";
|
||||
};
|
||||
model.on('error', function(model, error) {
|
||||
model.on('invalid', function(model, error) {
|
||||
lastError = error;
|
||||
});
|
||||
var result = model.set({a: 100});
|
||||
equal(result, model);
|
||||
equal(model.get('a'), 100);
|
||||
equal(lastError, undefined);
|
||||
result = model.set({a: 200, admin: false});
|
||||
result = model.set({admin: true});
|
||||
equal(model.get('admin'), true);
|
||||
result = model.set({a: 200, admin: false}, {validate:true});
|
||||
equal(lastError, "Can't change admin status.");
|
||||
equal(result, false);
|
||||
equal(model.get('a'), 100);
|
||||
@@ -467,10 +509,10 @@ $(document).ready(function() {
|
||||
model.set({name: "Two"});
|
||||
equal(model.get('name'), 'Two');
|
||||
equal(error, undefined);
|
||||
model.unset('name');
|
||||
model.unset('name', {validate: true});
|
||||
equal(error, true);
|
||||
equal(model.get('name'), 'Two');
|
||||
model.clear();
|
||||
model.clear({validate:true});
|
||||
equal(model.get('name'), 'Two');
|
||||
delete model.validate;
|
||||
model.clear();
|
||||
@@ -483,21 +525,18 @@ $(document).ready(function() {
|
||||
model.validate = function(attrs) {
|
||||
if (attrs.admin) return "Can't change admin status.";
|
||||
};
|
||||
var callback = function(model, error) {
|
||||
lastError = error;
|
||||
};
|
||||
model.on('error', function(model, error) {
|
||||
model.on('invalid', function(model, error) {
|
||||
boundError = true;
|
||||
});
|
||||
var result = model.set({a: 100}, {error: callback});
|
||||
var result = model.set({a: 100}, {validate:true});
|
||||
equal(result, model);
|
||||
equal(model.get('a'), 100);
|
||||
equal(lastError, undefined);
|
||||
equal(model.validationError, null);
|
||||
equal(boundError, undefined);
|
||||
result = model.set({a: 200, admin: true}, {error: callback});
|
||||
result = model.set({a: 200, admin: true}, {validate:true});
|
||||
equal(result, false);
|
||||
equal(model.get('a'), 100);
|
||||
equal(lastError, "Can't change admin status.");
|
||||
equal(model.validationError, "Can't change admin status.");
|
||||
equal(boundError, true);
|
||||
});
|
||||
|
||||
@@ -592,6 +631,13 @@ $(document).ready(function() {
|
||||
ok(model.get('x') === a);
|
||||
});
|
||||
|
||||
test("set same value does not trigger change", 0, function() {
|
||||
var model = new Backbone.Model({x: 1});
|
||||
model.on('change change:x', function() { ok(false); });
|
||||
model.set({x: 1});
|
||||
model.set({x: 1});
|
||||
});
|
||||
|
||||
test("unset does not fire a change for undefined attributes", 0, function() {
|
||||
var model = new Backbone.Model({x: undefined});
|
||||
model.on('change:x', function(){ ok(false); });
|
||||
@@ -603,19 +649,29 @@ $(document).ready(function() {
|
||||
ok('x' in model.attributes);
|
||||
});
|
||||
|
||||
test("change fires change:attr", 1, function() {
|
||||
test("hasChanged works outside of change events, and true within", 6, function() {
|
||||
var model = new Backbone.Model({x: 1});
|
||||
model.set({x: 2}, {silent: true});
|
||||
model.on('change:x', function(){ ok(true); });
|
||||
model.change();
|
||||
});
|
||||
|
||||
test("hasChanged is false after original values are set", 2, function() {
|
||||
var model = new Backbone.Model({x: 1});
|
||||
model.on('change:x', function(){ ok(false); });
|
||||
model.on('change:x', function() {
|
||||
ok(model.hasChanged('x'));
|
||||
equal(model.get('x'), 1);
|
||||
});
|
||||
model.set({x: 2}, {silent: true});
|
||||
ok(model.hasChanged());
|
||||
model.set({x: 1}, {silent: true});
|
||||
equal(model.hasChanged('x'), true);
|
||||
model.set({x: 1});
|
||||
ok(model.hasChanged());
|
||||
equal(model.hasChanged('x'), true);
|
||||
});
|
||||
|
||||
test("hasChanged gets cleared on the following set", 4, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.set({x: 1});
|
||||
ok(model.hasChanged());
|
||||
model.set({x: 1});
|
||||
ok(!model.hasChanged());
|
||||
model.set({x: 2});
|
||||
ok(model.hasChanged());
|
||||
model.set({});
|
||||
ok(!model.hasChanged());
|
||||
});
|
||||
|
||||
@@ -664,7 +720,7 @@ $(document).ready(function() {
|
||||
test("#1030 - `save` with `wait` results in correct attributes if success is called during sync", 2, function() {
|
||||
var model = new Backbone.Model({x: 1, y: 2});
|
||||
model.sync = function(method, model, options) {
|
||||
options.success();
|
||||
options.success(model, {}, options);
|
||||
};
|
||||
model.on("change:x", function() { ok(true); });
|
||||
model.save({x: 3}, {wait: true});
|
||||
@@ -678,6 +734,13 @@ $(document).ready(function() {
|
||||
model.save({x: 1}, {wait: true});
|
||||
});
|
||||
|
||||
test("save turns on parse flag", function () {
|
||||
var Model = Backbone.Model.extend({
|
||||
sync: function(method, model, options) { ok(options.parse); }
|
||||
});
|
||||
new Model().save();
|
||||
});
|
||||
|
||||
test("nested `set` during `'change:attr'`", 2, function() {
|
||||
var events = [];
|
||||
var model = new Backbone.Model();
|
||||
@@ -691,25 +754,19 @@ $(document).ready(function() {
|
||||
model.set({x: true});
|
||||
deepEqual(events, ['change:y', 'change:x', 'change']);
|
||||
events = [];
|
||||
model.change();
|
||||
deepEqual(events, ['change:z', 'change']);
|
||||
model.set({z: true});
|
||||
deepEqual(events, []);
|
||||
});
|
||||
|
||||
test("nested `change` only fires once", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change', function() {
|
||||
ok(true);
|
||||
model.change();
|
||||
model.set({x: true});
|
||||
});
|
||||
model.set({x: true});
|
||||
});
|
||||
|
||||
test("no `'change'` event if no changes", 0, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change', function() { ok(false); });
|
||||
model.change();
|
||||
});
|
||||
|
||||
test("nested `set` during `'change'`", 6, function() {
|
||||
var count = 0;
|
||||
var model = new Backbone.Model();
|
||||
@@ -721,13 +778,13 @@ $(document).ready(function() {
|
||||
model.set({y: true});
|
||||
break;
|
||||
case 1:
|
||||
deepEqual(this.changedAttributes(), {y: true});
|
||||
equal(model.previous('x'), true);
|
||||
deepEqual(this.changedAttributes(), {x: true, y: true});
|
||||
equal(model.previous('x'), undefined);
|
||||
model.set({z: true});
|
||||
break;
|
||||
case 2:
|
||||
deepEqual(this.changedAttributes(), {z: true});
|
||||
equal(model.previous('y'), true);
|
||||
deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
|
||||
equal(model.previous('y'), undefined);
|
||||
break;
|
||||
default:
|
||||
ok(false);
|
||||
@@ -736,30 +793,34 @@ $(document).ready(function() {
|
||||
model.set({x: true});
|
||||
});
|
||||
|
||||
test("nested `'change'` with silent", 3, function() {
|
||||
test("nested `change` with silent", 3, function() {
|
||||
var count = 0;
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:y', function() { ok(true); });
|
||||
model.on('change:y', function() { ok(false); });
|
||||
model.on('change', function() {
|
||||
switch(count++) {
|
||||
case 0:
|
||||
deepEqual(this.changedAttributes(), {x: true});
|
||||
model.set({y: true}, {silent: true});
|
||||
model.set({z: true});
|
||||
break;
|
||||
case 1:
|
||||
deepEqual(this.changedAttributes(), {y: true, z: true});
|
||||
deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
|
||||
break;
|
||||
case 2:
|
||||
deepEqual(this.changedAttributes(), {z: false});
|
||||
break;
|
||||
default:
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
model.set({x: true});
|
||||
model.set({z: true});
|
||||
model.set({z: false});
|
||||
});
|
||||
|
||||
test("nested `'change:attr'` with silent", 1, function() {
|
||||
test("nested `change:attr` with silent", 0, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:y', function(){ ok(true); });
|
||||
model.on('change:y', function(){ ok(false); });
|
||||
model.on('change', function() {
|
||||
model.set({y: true}, {silent: true});
|
||||
model.set({z: true});
|
||||
@@ -777,21 +838,25 @@ $(document).ready(function() {
|
||||
equal(val, 2);
|
||||
});
|
||||
model.set({x: true});
|
||||
model.change();
|
||||
});
|
||||
|
||||
test("multiple nested changes with silent", 2, function() {
|
||||
test("multiple nested changes with silent", 1, function() {
|
||||
var changes = [];
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:b', function(model, val) { changes.push(val); });
|
||||
model.on('change', function() {
|
||||
model.set({b: 1});
|
||||
model.set({b: 2}, {silent: true});
|
||||
});
|
||||
model.set({b: 0});
|
||||
deepEqual(changes, [0, 1]);
|
||||
model.change();
|
||||
deepEqual(changes, [0, 1, 2, 1]);
|
||||
});
|
||||
|
||||
test("basic silent change semantics", 1, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.set({x: 1});
|
||||
model.on('change', function(){ ok(true); });
|
||||
model.set({x: 2}, {silent: true});
|
||||
model.set({x: 1});
|
||||
});
|
||||
|
||||
test("nested set multiple times", 1, function() {
|
||||
@@ -828,7 +893,7 @@ $(document).ready(function() {
|
||||
}
|
||||
};
|
||||
model.sync = function(method, model, options) {
|
||||
options.success();
|
||||
options.success(model, {}, options);
|
||||
};
|
||||
model.save({id: 1}, opts);
|
||||
model.fetch(opts);
|
||||
@@ -866,7 +931,7 @@ $(document).ready(function() {
|
||||
validate: function(){ return 'invalid'; }
|
||||
});
|
||||
var model = new Model({id: 1});
|
||||
model.on('error', function(){ ok(true); });
|
||||
model.on('invalid', function(){ ok(true); });
|
||||
model.save();
|
||||
});
|
||||
|
||||
@@ -885,7 +950,7 @@ $(document).ready(function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
sync: function(method, model, options) {
|
||||
setTimeout(function(){
|
||||
options.success();
|
||||
options.success(model, {}, options);
|
||||
start();
|
||||
}, 0);
|
||||
}
|
||||
@@ -895,9 +960,9 @@ $(document).ready(function() {
|
||||
.save(null, {wait: true});
|
||||
});
|
||||
|
||||
test("#1664 - Changing from one value, silently to another, back to original does not trigger change.", 0, function() {
|
||||
test("#1664 - Changing from one value, silently to another, back to original triggers a change.", 1, function() {
|
||||
var model = new Backbone.Model({x:1});
|
||||
model.on('change:x', function() { ok(false); });
|
||||
model.on('change:x', function() { ok(true); });
|
||||
model.set({x:2},{silent:true});
|
||||
model.set({x:3},{silent:true});
|
||||
model.set({x:1});
|
||||
@@ -910,15 +975,11 @@ $(document).ready(function() {
|
||||
model.set({a:'c'}, {silent:true});
|
||||
model.set({b:2}, {silent:true});
|
||||
model.unset('c', {silent:true});
|
||||
model.set({a:'a'}, {silent:true});
|
||||
model.set({b:1}, {silent:true});
|
||||
model.set({c:'item'}, {silent:true});
|
||||
});
|
||||
model.on('change:a change:b change:c', function(model, val) { changes.push(val); });
|
||||
model.set({a:'a', b:1, c:'item'});
|
||||
deepEqual(changes, ['a',1,'item']);
|
||||
model.change();
|
||||
deepEqual(changes, ['a',1,'item']);
|
||||
deepEqual(model.attributes, {a: 'c', b: 2});
|
||||
});
|
||||
|
||||
test("#1791 - `attributes` is available for `parse`", function() {
|
||||
@@ -929,7 +990,7 @@ $(document).ready(function() {
|
||||
expect(0);
|
||||
});
|
||||
|
||||
test("silent changes in last `change` event back to original does not trigger change", 2, function() {
|
||||
test("silent changes in last `change` event back to original triggers change", 2, function() {
|
||||
var changes = [];
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:a change:b change:c', function(model, val) { changes.push(val); });
|
||||
@@ -938,9 +999,8 @@ $(document).ready(function() {
|
||||
});
|
||||
model.set({a:'a'});
|
||||
deepEqual(changes, ['a']);
|
||||
model.set({a:'a'}, {silent:true});
|
||||
model.change();
|
||||
deepEqual(changes, ['a']);
|
||||
model.set({a:'a'});
|
||||
deepEqual(changes, ['a', 'a']);
|
||||
});
|
||||
|
||||
test("#1943 change calculations should use _.isEqual", function() {
|
||||
@@ -949,4 +1009,65 @@ $(document).ready(function() {
|
||||
equal(model.changedAttributes(), false);
|
||||
});
|
||||
|
||||
test("#1964 - final `change` event is always fired, regardless of interim changes", 1, function () {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:property', function() {
|
||||
model.set('property', 'bar');
|
||||
});
|
||||
model.on('change', function() {
|
||||
ok(true);
|
||||
});
|
||||
model.set('property', 'foo');
|
||||
});
|
||||
|
||||
test("isValid", function() {
|
||||
var model = new Backbone.Model({valid: true});
|
||||
model.validate = function(attrs) {
|
||||
if (!attrs.valid) return "invalid";
|
||||
};
|
||||
equal(model.isValid(), true);
|
||||
equal(model.set({valid: false}, {validate:true}), false);
|
||||
equal(model.isValid(), true);
|
||||
model.set({valid:false});
|
||||
equal(model.isValid(), false);
|
||||
ok(!model.set('valid', false, {validate: true}));
|
||||
});
|
||||
|
||||
test("#1179 - isValid returns true in the absence of validate.", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.validate = null;
|
||||
ok(model.isValid());
|
||||
});
|
||||
|
||||
test("#1961 - Creating a model with {validate:true} will call validate and use the error callback", function () {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function (attrs) {
|
||||
if (attrs.id === 1) return "This shouldn't happen";
|
||||
}
|
||||
});
|
||||
var model = new Model({id: 1}, {validate: true});
|
||||
equal(model.validationError, "This shouldn't happen");
|
||||
});
|
||||
|
||||
test("toJSON receives attrs during save(..., {wait: true})", 1, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
url: '/test',
|
||||
toJSON: function() {
|
||||
strictEqual(this.attributes.x, 1);
|
||||
return _.clone(this.attributes);
|
||||
}
|
||||
});
|
||||
var model = new Model;
|
||||
model.save({x: 1}, {wait: true});
|
||||
});
|
||||
|
||||
test("#2034 - nested set with silent only triggers one change", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change', function() {
|
||||
model.set({b: true}, {silent: true});
|
||||
ok(true);
|
||||
});
|
||||
model.set({a: true});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
35
vendor/backbone/test/router.js
vendored
35
vendor/backbone/test/router.js
vendored
@@ -69,7 +69,9 @@ $(document).ready(function() {
|
||||
"contacts": "contacts",
|
||||
"contacts/new": "newContact",
|
||||
"contacts/:id": "loadContact",
|
||||
"route-event/:arg": "routeEvent",
|
||||
"optional(/:item)": "optionalItem",
|
||||
"named/optional/(y:z)": "namedOptional",
|
||||
"splat/*args/end": "splat",
|
||||
"*first/complex-:part/*rest": "complex",
|
||||
":entity?*args": "query",
|
||||
@@ -110,23 +112,30 @@ $(document).ready(function() {
|
||||
this.arg = arg != void 0 ? arg : null;
|
||||
},
|
||||
|
||||
splat : function(args) {
|
||||
splat: function(args) {
|
||||
this.args = args;
|
||||
},
|
||||
|
||||
complex : function(first, part, rest) {
|
||||
complex: function(first, part, rest) {
|
||||
this.first = first;
|
||||
this.part = part;
|
||||
this.rest = rest;
|
||||
},
|
||||
|
||||
query : function(entity, args) {
|
||||
query: function(entity, args) {
|
||||
this.entity = entity;
|
||||
this.queryArgs = args;
|
||||
},
|
||||
|
||||
anything : function(whatever) {
|
||||
anything: function(whatever) {
|
||||
this.anything = whatever;
|
||||
},
|
||||
|
||||
namedOptional: function(z) {
|
||||
this.z = z;
|
||||
},
|
||||
|
||||
routeEvent: function(arg) {
|
||||
}
|
||||
|
||||
});
|
||||
@@ -502,4 +511,22 @@ $(document).ready(function() {
|
||||
strictEqual(history.getFragment('/fragment '), 'fragment');
|
||||
});
|
||||
|
||||
test("#1980 - Optional parameters.", 2, function() {
|
||||
location.replace('http://example.com#named/optional/y');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.z, undefined);
|
||||
location.replace('http://example.com#named/optional/y123');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.z, '123');
|
||||
});
|
||||
|
||||
test("#2062 - Trigger 'route' event on router instance.", 2, function() {
|
||||
router.on('route', function(name, args) {
|
||||
strictEqual(name, 'routeEvent');
|
||||
deepEqual(args, ['x']);
|
||||
});
|
||||
location.replace('http://example.com#route-event/x');
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
16
vendor/backbone/test/view.js
vendored
16
vendor/backbone/test/view.js
vendored
@@ -29,22 +29,6 @@ $(document).ready(function() {
|
||||
strictEqual(view.$('a b').html(), 'test');
|
||||
});
|
||||
|
||||
test("make", 3, function() {
|
||||
var div = view.make('div', {id: 'test-div'}, "one two three");
|
||||
|
||||
equal(div.tagName.toLowerCase(), 'div');
|
||||
equal(div.id, 'test-div');
|
||||
equal($(div).text(), 'one two three');
|
||||
});
|
||||
|
||||
test("make can take falsy values for content", 2, function() {
|
||||
var div = view.make('div', {id: 'test-div'}, 0);
|
||||
equal($(div).text(), '0');
|
||||
|
||||
div = view.make('div', {id: 'test-div'}, '');
|
||||
equal($(div).text(), '');
|
||||
});
|
||||
|
||||
test("initialize", 1, function() {
|
||||
var View = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
|
||||
4
vendor/benchmark.js/LICENSE.txt
vendored
4
vendor/benchmark.js/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2010-2012 Mathias Bynens <http://mathiasbynens.be/>
|
||||
Copyright 2010-2013 Mathias Bynens <http://mathiasbynens.be/>
|
||||
Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
|
||||
Modified by John-David Dalton <http://allyoucanleet.com/>
|
||||
|
||||
@@ -19,4 +19,4 @@ 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.
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
9
vendor/benchmark.js/benchmark.js
vendored
9
vendor/benchmark.js/benchmark.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Benchmark.js v1.0.0 <http://benchmarkjs.com/>
|
||||
* Copyright 2010-2012 Mathias Bynens <http://mths.be/>
|
||||
* Copyright 2010-2013 Mathias Bynens <http://mths.be/>
|
||||
* Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
|
||||
* Modified by John-David Dalton <http://allyoucanleet.com/>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
@@ -990,7 +990,7 @@
|
||||
result = String(fn);
|
||||
} else if (support.decompilation) {
|
||||
// escape the `{` for Firefox 1
|
||||
result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1];
|
||||
result = (/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn) || 0)[1];
|
||||
}
|
||||
// trim string
|
||||
result = (result || '').replace(/^\s+|\s+$/g, '');
|
||||
@@ -1648,7 +1648,10 @@
|
||||
function interpolate(string, object) {
|
||||
forOwn(object, function(value, key) {
|
||||
// escape regexp special characters in `key`
|
||||
string = string.replace(RegExp('#\\{' + key.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + '\\}', 'g'), value);
|
||||
string = string.replace(
|
||||
RegExp('#\\{' + key.replace(/([.*+?^${}()|[\]\\])/g, '\\$1') + '\\}', 'g'),
|
||||
value.replace(/\$/g, '$$$$')
|
||||
);
|
||||
});
|
||||
return string;
|
||||
}
|
||||
|
||||
2
vendor/docdown/LICENSE.txt
vendored
2
vendor/docdown/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Copyright 2011-2013 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
|
||||
|
||||
2
vendor/docdown/docdown.php
vendored
2
vendor/docdown/docdown.php
vendored
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/*!
|
||||
* Docdown v1.0.0-pre
|
||||
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Copyright 2011-2013 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
*/
|
||||
require(dirname(__FILE__) . '/src/DocDown/Generator.php');
|
||||
|
||||
119
vendor/docdown/src/DocDown/Alias.php
vendored
119
vendor/docdown/src/DocDown/Alias.php
vendored
@@ -29,15 +29,16 @@ class Alias {
|
||||
$this->_category = $owner->getCategory();
|
||||
$this->_desc = $owner->getDesc();
|
||||
$this->_example = $owner->getExample();
|
||||
$this->_isCtor = $owner->isCtor();
|
||||
$this->_isLicense = $owner->isLicense();
|
||||
$this->_isPlugin = $owner->isPlugin();
|
||||
$this->_isPrivate = $owner->isPrivate();
|
||||
$this->_isStatic = $owner->isStatic();
|
||||
$this->_lineNumber = $owner->getLineNumber();
|
||||
$this->_members = $owner->getMembers();
|
||||
$this->_params = $owner->getParams();
|
||||
$this->_returns = $owner->getReturns();
|
||||
$this->_type = $owner->getType();
|
||||
$this->_isCtor = $owner->isCtor();
|
||||
$this->_isPlugin = $owner->isPlugin();
|
||||
$this->_isPrivate = $owner->isPrivate();
|
||||
$this->_isStatic = $owner->isStatic();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -96,6 +97,66 @@ class Alias {
|
||||
return $this->_example;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is an alias.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true`.
|
||||
*/
|
||||
public function isAlias() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is a constructor.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if a constructor, else `false`.
|
||||
*/
|
||||
public function isCtor() {
|
||||
return $this->_isCtor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is a license.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if a license, else `false`.
|
||||
*/
|
||||
public function isLicense() {
|
||||
return $this->_isLicense;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry *is* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isPlugin() {
|
||||
return $this->_isPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is private.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if private, else `false`.
|
||||
*/
|
||||
public function isPrivate() {
|
||||
return $this->_isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is *not* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isStatic() {
|
||||
return $this->_isStatic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the owner entry's line number.
|
||||
*
|
||||
@@ -161,55 +222,5 @@ class Alias {
|
||||
public function getType() {
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is an alias.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true`.
|
||||
*/
|
||||
public function isAlias() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is a constructor.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if a constructor, else `false`.
|
||||
*/
|
||||
public function isCtor() {
|
||||
return $this->_isCtor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry *is* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isPlugin() {
|
||||
return $this->_isPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is private.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if private, else `false`.
|
||||
*/
|
||||
public function isPrivate() {
|
||||
return $this->_isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the owner entry is *not* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isStatic() {
|
||||
return $this->_isStatic;
|
||||
}
|
||||
}
|
||||
?>
|
||||
175
vendor/docdown/src/DocDown/Entry.php
vendored
175
vendor/docdown/src/DocDown/Entry.php
vendored
@@ -217,6 +217,100 @@ class Entry {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is an alias.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `false`.
|
||||
*/
|
||||
public function isAlias() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is a constructor.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if a constructor, else `false`.
|
||||
*/
|
||||
public function isCtor() {
|
||||
if (!isset($this->_isCtor)) {
|
||||
$this->_isCtor = !!preg_match('/\* *@constructor\b/', $this->entry);
|
||||
}
|
||||
return $this->_isCtor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is a license.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if a license, else `false`.
|
||||
*/
|
||||
public function isLicense() {
|
||||
if (!isset($this->_isLicense)) {
|
||||
$this->_isLicense = !!preg_match('/\* *@license\b/', $this->entry);
|
||||
}
|
||||
return $this->_isLicense;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry *is* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isPlugin() {
|
||||
if (!isset($this->_isPlugin)) {
|
||||
$this->_isPlugin = !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
|
||||
}
|
||||
return $this->_isPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is private.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if private, else `false`.
|
||||
*/
|
||||
public function isPrivate() {
|
||||
if (!isset($this->_isPrivate)) {
|
||||
$this->_isPrivate = $this->isLicense() || !!preg_match('/\* *@private\b/', $this->entry) || !preg_match('/\* *@[a-z]+\b/', $this->entry);
|
||||
}
|
||||
return $this->_isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is *not* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isStatic() {
|
||||
if (isset($this->_isStatic)) {
|
||||
return $this->_isStatic;
|
||||
}
|
||||
|
||||
$public = !$this->isPrivate();
|
||||
$result = $public && !!preg_match('/\* *@static\b/', $this->entry);
|
||||
|
||||
// set in cases where it isn't explicitly stated
|
||||
if ($public && !$result) {
|
||||
if ($parent = array_pop(preg_split('/[#.]/', $this->getMembers(0)))) {
|
||||
foreach (Entry::getEntries($this->source) as $entry) {
|
||||
$entry = new Entry($entry, $this->source);
|
||||
if ($entry->getName() == $parent) {
|
||||
$result = !$entry->isCtor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
$this->_isStatic = $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the entry's line number.
|
||||
*
|
||||
@@ -344,86 +438,5 @@ class Entry {
|
||||
$this->_type = $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is an alias.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `false`.
|
||||
*/
|
||||
public function isAlias() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is a constructor.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if a constructor, else `false`.
|
||||
*/
|
||||
public function isCtor() {
|
||||
if (!isset($this->_isCtor)) {
|
||||
$this->_isCtor = !!preg_match('/\* *@constructor\b/', $this->entry);
|
||||
}
|
||||
return $this->_isCtor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry *is* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isPlugin() {
|
||||
if (!isset($this->_isPlugin)) {
|
||||
$this->_isPlugin = !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
|
||||
}
|
||||
return $this->_isPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is private.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if private, else `false`.
|
||||
*/
|
||||
public function isPrivate() {
|
||||
if (!isset($this->_isPrivate)) {
|
||||
$this->_isPrivate = !!preg_match('/\* *@private\b/', $this->entry) || !preg_match('/\* *@[a-z]+\b/', $this->entry);
|
||||
}
|
||||
return $this->_isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entry is *not* assigned to a prototype.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
|
||||
*/
|
||||
public function isStatic() {
|
||||
if (isset($this->_isStatic)) {
|
||||
return $this->_isStatic;
|
||||
}
|
||||
|
||||
$public = !$this->isPrivate();
|
||||
$result = $public && !!preg_match('/\* *@static\b/', $this->entry);
|
||||
|
||||
// set in cases where it isn't explicitly stated
|
||||
if ($public && !$result) {
|
||||
if ($parent = array_pop(preg_split('/[#.]/', $this->getMembers(0)))) {
|
||||
foreach (Entry::getEntries($this->source) as $entry) {
|
||||
$entry = new Entry($entry, $this->source);
|
||||
if ($entry->getName() == $parent) {
|
||||
$result = !$entry->isCtor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
$this->_isStatic = $result;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
||||
2
vendor/platform.js/LICENSE.txt
vendored
2
vendor/platform.js/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Copyright 2011-2013 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
|
||||
|
||||
4
vendor/platform.js/platform.js
vendored
4
vendor/platform.js/platform.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Platform.js v1.0.0 <http://mths.be/platform>
|
||||
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Copyright 2010-2013 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
*/
|
||||
;(function(window) {
|
||||
@@ -885,7 +885,7 @@
|
||||
* The CPU architecture the OS is built for.
|
||||
*
|
||||
* @memberOf platform.os
|
||||
* @type String|Null
|
||||
* @type Number|Null
|
||||
*/
|
||||
'architecture': null,
|
||||
|
||||
|
||||
2
vendor/qunit-clib/LICENSE.txt
vendored
2
vendor/qunit-clib/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Copyright 2011-2013 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
|
||||
|
||||
13
vendor/qunit-clib/README.md
vendored
13
vendor/qunit-clib/README.md
vendored
@@ -1,4 +1,4 @@
|
||||
# QUnit CLIB <sup>v1.0.0</sup>
|
||||
# QUnit CLIB <sup>v1.2.0</sup>
|
||||
## command-line interface boilerplate
|
||||
|
||||
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
|
||||
@@ -9,23 +9,24 @@ QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
|
||||
|
||||
## Support
|
||||
|
||||
QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, RingoJS v0.8.0, and Rhino v1.7RC3-RC5.
|
||||
QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.19, Narwhal v0.3.2, PhantomJS 1.8.1, RingoJS v0.9, and Rhino v1.7RC5.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
(function(window) {
|
||||
|
||||
// use a single load function
|
||||
// use a single "load" function
|
||||
var load = typeof require == 'function' ? require : window.load;
|
||||
|
||||
// load QUnit and CLIB if needed
|
||||
var QUnit =
|
||||
window.QUnit || (
|
||||
window.setTimeout || (window.addEventListener = window.setTimeout = / /),
|
||||
window.addEventListener || (window.addEventListener = Function.prototype),
|
||||
window.setTimeout || (window.setTimeout = Function.prototype),
|
||||
window.QUnit = load('path/to/qunit.js') || window.QUnit,
|
||||
load('path/to/qunit-clib.js'),
|
||||
(window.addEventListener || 0).test && delete window.addEventListener,
|
||||
window.addEventListener === Function.prototype && delete window.addEventListener,
|
||||
window.QUnit
|
||||
);
|
||||
|
||||
@@ -38,7 +39,7 @@ QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, Ring
|
||||
});
|
||||
|
||||
// must call `QUnit.start()` if using QUnit < 1.3.0 with Node.js or any
|
||||
// version of QUnit with Narwhal, Rhino, or RingoJS
|
||||
// version of QUnit with Narwhal, PhantomJS, Rhino, or RingoJS
|
||||
if (!window.document) {
|
||||
QUnit.start();
|
||||
}
|
||||
|
||||
513
vendor/qunit-clib/qunit-clib.js
vendored
513
vendor/qunit-clib/qunit-clib.js
vendored
@@ -1,324 +1,269 @@
|
||||
/*!
|
||||
* QUnit CLI Boilerplate v1.0.0
|
||||
* QUnit CLI Boilerplate v1.2.0
|
||||
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
*/
|
||||
;(function(global) {
|
||||
;(function(window) {
|
||||
'use strict';
|
||||
|
||||
/** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
|
||||
global.console || (global.console = { 'log': global.print });
|
||||
|
||||
/** Reduce global.QUnit.QUnit -> global.QUnit */
|
||||
global.QUnit && (QUnit = QUnit.QUnit || QUnit);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/** Used as a horizontal rule in console output */
|
||||
var hr = '----------------------------------------';
|
||||
|
||||
/** Shortcut used to convert array-like objects to arrays */
|
||||
var slice = [].slice;
|
||||
|
||||
/** Used to resolve a value's internal [[Class]] */
|
||||
var toString = {}.toString;
|
||||
|
||||
/** Used by timer methods */
|
||||
var doneCalled,
|
||||
timer,
|
||||
counter = 0,
|
||||
ids = {};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* An iteration utility for arrays.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} callback The function called per iteration.
|
||||
*/
|
||||
function each(array, callback) {
|
||||
var index = -1,
|
||||
length = array.length;
|
||||
|
||||
while (++index < length) {
|
||||
callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified `value` is a function.
|
||||
*
|
||||
* @private
|
||||
* @param {Mixed} value The value to check.
|
||||
* @returns {Boolean} Returns `true` if `value` is a function, else `false`.
|
||||
*/
|
||||
function isFunction(value) {
|
||||
return toString.call(value) == '[object Function]';
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Timeout fallbacks based on the work of Andrea Giammarchi and Weston C.
|
||||
* https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js
|
||||
* http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
|
||||
*/
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Clears the delay set by `setInterval` or `setTimeout`.
|
||||
*
|
||||
* @memberOf global
|
||||
* @param {Number} id The ID of the timeout to be cleared.
|
||||
*/
|
||||
function clearTimer(id) {
|
||||
if (ids[id]) {
|
||||
ids[id].cancel();
|
||||
timer.purge();
|
||||
delete ids[id];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules timer-based callbacks.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} fn The function to call.
|
||||
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
|
||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
||||
* @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly.
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function schedule(fn, delay, args, repeated) {
|
||||
// Rhino 1.7RC4 will error assigning `task` below
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=775566
|
||||
var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
|
||||
'run': function() {
|
||||
fn.apply(global, args);
|
||||
/**
|
||||
* Schedules timer-based callbacks.
|
||||
*
|
||||
* @private
|
||||
* @param {Function|String} fn The function to call.
|
||||
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
|
||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
||||
* @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly.
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function schedule(fn, delay, args, repeated) {
|
||||
// Rhino 1.7RC4 will error assigning `task` below
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=775566
|
||||
var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
|
||||
'run': function() {
|
||||
fn.apply(window, args);
|
||||
}
|
||||
});
|
||||
// support non-functions
|
||||
if (typeof fn != 'function') {
|
||||
fn = (function(code) {
|
||||
code = String(code);
|
||||
return function() { eval(code); };
|
||||
}(fn));
|
||||
}
|
||||
});
|
||||
// support non-functions
|
||||
if (!isFunction(fn)) {
|
||||
fn = (function(code) {
|
||||
code = String(code);
|
||||
return function() { eval(code); };
|
||||
}(fn));
|
||||
// used by setInterval
|
||||
if (repeated) {
|
||||
timer.schedule(task, delay, delay);
|
||||
}
|
||||
// used by setTimeout
|
||||
else {
|
||||
timer.schedule(task, delay);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
// used by setInterval
|
||||
if (repeated) {
|
||||
timer.schedule(task, delay, delay);
|
||||
}
|
||||
// used by setTimeout
|
||||
else {
|
||||
timer.schedule(task, delay);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a code snippet or function repeatedly, with a delay between each call.
|
||||
*
|
||||
* @memberOf global
|
||||
* @param {Function|String} fn The function to call or string to evaluate.
|
||||
* @oaram {Number} delay The number of milliseconds to delay each `fn` call.
|
||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function setInterval(fn, delay) {
|
||||
return schedule(fn, delay, slice.call(arguments, 2), true);
|
||||
}
|
||||
/**
|
||||
* Clears the delay set by `setInterval` or `setTimeout`.
|
||||
*
|
||||
* @memberOf window
|
||||
* @param {Number} id The ID of the timeout to be cleared.
|
||||
*/
|
||||
function clearTimer(id) {
|
||||
if (ids[id]) {
|
||||
ids[id].cancel();
|
||||
timer.purge();
|
||||
delete ids[id];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a code snippet or a function after specified delay.
|
||||
*
|
||||
* @memberOf global
|
||||
* @param {Function|String} fn The function to call or string to evaluate.
|
||||
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
|
||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function setTimeout(fn, delay) {
|
||||
return schedule(fn, delay, slice.call(arguments, 2));
|
||||
}
|
||||
/**
|
||||
* Executes a code snippet or function repeatedly, with a delay between each call.
|
||||
*
|
||||
* @memberOf window
|
||||
* @param {Function|String} fn The function to call or string to evaluate.
|
||||
* @oaram {Number} delay The number of milliseconds to delay each `fn` call.
|
||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function setInterval(fn, delay) {
|
||||
return schedule(fn, delay, slice.call(arguments, 2), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a code snippet or a function after specified delay.
|
||||
*
|
||||
* @memberOf window
|
||||
* @param {Function|String} fn The function to call or string to evaluate.
|
||||
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
|
||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
||||
* @returns {Number} The the ID of the timeout.
|
||||
*/
|
||||
function setTimeout(fn, delay) {
|
||||
return schedule(fn, delay, slice.call(arguments, 2));
|
||||
}
|
||||
|
||||
try {
|
||||
var counter = 0,
|
||||
ids = {},
|
||||
slice = Array.prototype.slice,
|
||||
timer = new java.util.Timer;
|
||||
|
||||
window.clearInterval =
|
||||
window.clearTimeout = clearTimer;
|
||||
window.setInterval = setInterval;
|
||||
window.setTimeout = setTimeout;
|
||||
} catch(e) { }
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A logging callback triggered when all testing is completed.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `failed`, `passed`,
|
||||
* `runtime`, and `total`.
|
||||
*/
|
||||
function done(details) {
|
||||
// stop `asyncTest()` from erroneously calling `done()` twice in
|
||||
// environments w/o timeouts
|
||||
if (doneCalled) {
|
||||
return;
|
||||
}
|
||||
doneCalled = true;
|
||||
console.log(hr);
|
||||
console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total);
|
||||
console.log(' Finished in ' + details.runtime + ' milliseconds.');
|
||||
console.log(hr);
|
||||
(function() {
|
||||
|
||||
// exit out of Rhino
|
||||
try {
|
||||
quit();
|
||||
} catch(e) { }
|
||||
/** Used as a horizontal rule in console output */
|
||||
var hr = '----------------------------------------';
|
||||
|
||||
// exit out of Node.js
|
||||
try {
|
||||
if (details.failed) {
|
||||
console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.');
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
/** Shorten `window.QUnit.QUnit` to `window.QUnit` */
|
||||
window.QUnit && (QUnit = QUnit.QUnit || QUnit);
|
||||
|
||||
/**
|
||||
* A logging callback triggered when all testing is completed.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `failed`, `passed`, `runtime`, and `total`.
|
||||
*/
|
||||
QUnit.done(function() {
|
||||
var ran;
|
||||
return function(details) {
|
||||
// stop `asyncTest()` from erroneously calling `done()` twice in
|
||||
// environments w/o timeouts
|
||||
if (ran) {
|
||||
return;
|
||||
}
|
||||
ran = true;
|
||||
|
||||
console.log(hr);
|
||||
console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total);
|
||||
console.log(' Finished in ' + details.runtime + ' milliseconds.');
|
||||
console.log(hr);
|
||||
|
||||
// exit out of Rhino
|
||||
try {
|
||||
quit();
|
||||
} catch(e) { }
|
||||
|
||||
// exit out of Node.js or PhantomJS
|
||||
try {
|
||||
var process = window.process || window.phantom;
|
||||
if (details.failed) {
|
||||
console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.');
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
} catch(e) { }
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* A logging callback triggered after every assertion.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `actual`, `expected`, `message`, and `result`.
|
||||
*/
|
||||
QUnit.log(function(details) {
|
||||
var expected = details.expected,
|
||||
result = details.result,
|
||||
type = typeof expected != 'undefined' ? 'EQ' : 'OK';
|
||||
|
||||
var assertion = [
|
||||
result ? 'PASS' : 'FAIL',
|
||||
type,
|
||||
details.message || 'ok'
|
||||
];
|
||||
|
||||
if (!result && type == 'EQ') {
|
||||
assertion.push('Expected: ' + expected + ', Actual: ' + details.actual);
|
||||
}
|
||||
} catch(e) { }
|
||||
}
|
||||
QUnit.config.testStats.assertions.push(assertion.join(' | '));
|
||||
});
|
||||
|
||||
/**
|
||||
* A logging callback triggered after every assertion.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `actual`, `expected`,
|
||||
* `message`, and `result`.
|
||||
*/
|
||||
function log(details) {
|
||||
var expected = details.expected,
|
||||
result = details.result,
|
||||
type = typeof expected != 'undefined' ? 'EQ' : 'OK';
|
||||
/**
|
||||
* A logging callback triggered at the start of every test module.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with property `name`.
|
||||
*/
|
||||
QUnit.moduleStart(function(details) {
|
||||
console.log(hr);
|
||||
console.log(details.name);
|
||||
console.log(hr);
|
||||
});
|
||||
|
||||
var assertion = [
|
||||
result ? 'PASS' : 'FAIL',
|
||||
type,
|
||||
details.message || 'ok'
|
||||
];
|
||||
/**
|
||||
* Converts an object into a string representation.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @type Function
|
||||
* @param {Object} object The object to stringify.
|
||||
* @returns {String} The result string.
|
||||
*/
|
||||
QUnit.jsDump.parsers.object = (function() {
|
||||
var func = QUnit.jsDump.parsers.object;
|
||||
return function(object) {
|
||||
// fork to support Rhino's error objects
|
||||
if (typeof object.rhinoException == 'object') {
|
||||
return object.name +
|
||||
' { message: "' + object.message +
|
||||
'", fileName: "' + object.fileName +
|
||||
'", lineNumber: ' + object.lineNumber + ' }';
|
||||
}
|
||||
return func(object);
|
||||
};
|
||||
}());
|
||||
|
||||
if (!result && type == 'EQ') {
|
||||
assertion.push('Expected: ' + expected + ', Actual: ' + details.actual);
|
||||
}
|
||||
QUnit.config.testStats.assertions.push(assertion.join(' | '));
|
||||
}
|
||||
/**
|
||||
* A logging callback triggered after a test is completed.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `failed`, `name`, `passed`, and `total`.
|
||||
*/
|
||||
QUnit.testDone(function(details) {
|
||||
var assertions = QUnit.config.testStats.assertions,
|
||||
testName = details.name;
|
||||
|
||||
/**
|
||||
* A logging callback triggered at the start of every test module.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with property `name`.
|
||||
*/
|
||||
function moduleStart(details) {
|
||||
console.log(hr);
|
||||
console.log(details.name);
|
||||
console.log(hr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object into a string representation.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @type Function
|
||||
* @param {Object} object The object to stringify.
|
||||
* @returns {String} The result string.
|
||||
*/
|
||||
var parseObject = (function() {
|
||||
var func = QUnit.jsDump.parsers.object;
|
||||
return function(object) {
|
||||
// fork to support Rhino's error objects
|
||||
if (typeof object.rhinoException == 'object') {
|
||||
return object.name +
|
||||
' { message: "' + object.message +
|
||||
'", fileName: "' + object.fileName +
|
||||
'", lineNumber: ' + object.lineNumber + ' }';
|
||||
if (details.failed > 0) {
|
||||
console.log(' FAIL - '+ testName);
|
||||
assertions.forEach(function(value) {
|
||||
console.log(' ' + value);
|
||||
});
|
||||
}
|
||||
return func(object);
|
||||
else {
|
||||
console.log(' PASS - ' + testName);
|
||||
}
|
||||
assertions.length = 0;
|
||||
});
|
||||
|
||||
/**
|
||||
* An object used to hold information about the current running test.
|
||||
*
|
||||
* @memberOf QUnit.config
|
||||
* @type Object
|
||||
*/
|
||||
QUnit.config.testStats = {
|
||||
|
||||
/**
|
||||
* An array of test summaries (pipe separated).
|
||||
*
|
||||
* @memberOf QUnit.config.testStats
|
||||
* @type Array
|
||||
*/
|
||||
'assertions': []
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* A logging callback triggered after a test is completed.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `failed`, `name`,
|
||||
* `passed`, and `total`.
|
||||
*/
|
||||
function testDone(details) {
|
||||
var assertions = QUnit.config.testStats.assertions,
|
||||
testName = details.name;
|
||||
|
||||
if (details.failed > 0) {
|
||||
console.log(' FAIL - '+ testName);
|
||||
each(assertions, function(value) {
|
||||
console.log(' ' + value);
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log(' PASS - ' + testName);
|
||||
}
|
||||
assertions.length = 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* An object used to hold information about the current running test.
|
||||
*
|
||||
* @memberOf QUnit.config
|
||||
* @type Object
|
||||
*/
|
||||
QUnit.config.testStats = {
|
||||
|
||||
/**
|
||||
* An array of test summaries (pipe separated).
|
||||
*
|
||||
* @memberOf QUnit.config.testStats
|
||||
* @type Array
|
||||
*/
|
||||
'assertions': []
|
||||
};
|
||||
|
||||
// add shortcuts to the global
|
||||
// expose shortcuts
|
||||
// exclude `module` because some environments have it as a built-in object
|
||||
each(['asyncTest', 'deepEqual', 'equal', 'equals', 'expect', 'notDeepEqual',
|
||||
'notEqual', 'notStrictEqual', 'ok', 'raises', 'same', 'start', 'stop',
|
||||
'strictEqual', 'test', 'throws'], function(funcName) {
|
||||
var func = QUnit[funcName];
|
||||
if (func) {
|
||||
global[funcName] = func;
|
||||
}
|
||||
('asyncTest deepEqual equal equals expect notDeepEqual notEqual notStrictEqual ' +
|
||||
'ok raises same start stop strictEqual test throws').replace(/\S+/g, function(methodName) {
|
||||
window[methodName] = QUnit[methodName];
|
||||
});
|
||||
|
||||
// expose timer methods to global
|
||||
try {
|
||||
timer = new java.util.Timer;
|
||||
if (!isFunction(global.clearInterval)) {
|
||||
global.clearInterval = clearTimer;
|
||||
}
|
||||
if (!isFunction(global.clearTimeout)) {
|
||||
global.clearTimeout = clearTimer;
|
||||
}
|
||||
if (!isFunction(global.setInterval)) {
|
||||
global.setInterval = setInterval;
|
||||
}
|
||||
if (!isFunction(global.setTimeout)) {
|
||||
global.setTimeout = setTimeout;
|
||||
}
|
||||
} catch(e) { }
|
||||
|
||||
// add callbacks
|
||||
QUnit.done(done);
|
||||
QUnit.log(log);
|
||||
QUnit.moduleStart(moduleStart);
|
||||
QUnit.testDone(testDone);
|
||||
|
||||
// add wrapped function
|
||||
QUnit.jsDump.parsers.object = parseObject;
|
||||
|
||||
// add `console.log()` support for Narwhal, Rhino, and RingoJS
|
||||
if (!window.console && window.print) {
|
||||
window.console = { 'log': window.print };
|
||||
}
|
||||
// must call `QUnit.start()` in the test file if using QUnit < 1.3.0 with
|
||||
// Node.js or any version of QUnit with Narwhal, Rhino, or RingoJS
|
||||
// Node.js or any version of QUnit with Narwhal, PhantomJS, Rhino, or RingoJS
|
||||
QUnit.init();
|
||||
|
||||
}(typeof global == 'object' && global || this));
|
||||
|
||||
17
vendor/qunit/README.md
vendored
17
vendor/qunit/README.md
vendored
@@ -23,9 +23,6 @@ If you are interested in helping developing QUnit, you are in the right place.
|
||||
For related discussions, visit the
|
||||
[QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing).
|
||||
|
||||
Planning for a qunitjs.com site and other testing tools related work now happens
|
||||
on the [jQuery Testing Team planning wiki](http://jquerytesting.pbworks.com/w/page/41556026/FrontPage).
|
||||
|
||||
Development
|
||||
-----------
|
||||
|
||||
@@ -49,11 +46,17 @@ tag, update them again to the next version, commit and push commits and tags
|
||||
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
|
||||
or whitespace cleanups.
|
||||
|
||||
To upload to code.jquery.com (replace $version accordingly):
|
||||
To upload to code.jquery.com (replace $version accordingly), ssh to code.origin.jquery.com:
|
||||
|
||||
scp -q qunit/qunit.js jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.js
|
||||
scp -q qunit/qunit.css jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.css
|
||||
cp qunit/qunit.js /var/www/html/code.jquery.com/qunit/qunit-$version.js
|
||||
cp qunit/qunit.css /var/www/html/code.jquery.com/qunit/qunit-$version.css
|
||||
|
||||
Then update /var/www/html/code.jquery.com/index.html and purge it with:
|
||||
|
||||
curl -s http://code.origin.jquery.com/?reload
|
||||
curl -s http://code.origin.jquery.com/?reload
|
||||
|
||||
Update web-base-template to link to those files for qunitjs.com.
|
||||
|
||||
Publish to npm via
|
||||
|
||||
npm publish
|
||||
|
||||
1863
vendor/qunit/qunit/qunit-1.8.0.js
vendored
1863
vendor/qunit/qunit/qunit-1.8.0.js
vendored
File diff suppressed because it is too large
Load Diff
15
vendor/qunit/qunit/qunit.css
vendored
15
vendor/qunit/qunit/qunit.css
vendored
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -111,7 +111,12 @@
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
#qunit-tests li .runtime {
|
||||
float: right;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.qunit-assert-list {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
@@ -122,6 +127,10 @@
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
.qunit-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
|
||||
491
vendor/qunit/qunit/qunit.js
vendored
491
vendor/qunit/qunit/qunit.js
vendored
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
@@ -11,6 +11,7 @@
|
||||
(function( window ) {
|
||||
|
||||
var QUnit,
|
||||
assert,
|
||||
config,
|
||||
onErrorFnPrev,
|
||||
testId = 0,
|
||||
@@ -20,18 +21,67 @@ var QUnit,
|
||||
// Keep a local reference to Date (GH-283)
|
||||
Date = window.Date,
|
||||
defined = {
|
||||
setTimeout: typeof window.setTimeout !== "undefined",
|
||||
sessionStorage: (function() {
|
||||
var x = "qunit-test-string";
|
||||
try {
|
||||
sessionStorage.setItem( x, x );
|
||||
sessionStorage.removeItem( x );
|
||||
return true;
|
||||
} catch( e ) {
|
||||
return false;
|
||||
setTimeout: typeof window.setTimeout !== "undefined",
|
||||
sessionStorage: (function() {
|
||||
var x = "qunit-test-string";
|
||||
try {
|
||||
sessionStorage.setItem( x, x );
|
||||
sessionStorage.removeItem( x );
|
||||
return true;
|
||||
} catch( e ) {
|
||||
return false;
|
||||
}
|
||||
}())
|
||||
},
|
||||
/**
|
||||
* Provides a normalized error string, correcting an issue
|
||||
* with IE 7 (and prior) where Error.prototype.toString is
|
||||
* not properly implemented
|
||||
*
|
||||
* Based on http://es5.github.com/#x15.11.4.4
|
||||
*
|
||||
* @param {String|Error} error
|
||||
* @return {String} error message
|
||||
*/
|
||||
errorString = function( error ) {
|
||||
var name, message,
|
||||
errorString = error.toString();
|
||||
if ( errorString.substring( 0, 7 ) === "[object" ) {
|
||||
name = error.name ? error.name.toString() : "Error";
|
||||
message = error.message ? error.message.toString() : "";
|
||||
if ( name && message ) {
|
||||
return name + ": " + message;
|
||||
} else if ( name ) {
|
||||
return name;
|
||||
} else if ( message ) {
|
||||
return message;
|
||||
} else {
|
||||
return "Error";
|
||||
}
|
||||
} else {
|
||||
return errorString;
|
||||
}
|
||||
}())
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Makes a clone of an object using only Array or Object as base,
|
||||
* and copies over the own enumerable properties.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object} New object with only the own properties (recursively).
|
||||
*/
|
||||
objectValues = function( obj ) {
|
||||
// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
|
||||
/*jshint newcap: false */
|
||||
var key, val,
|
||||
vals = QUnit.is( "array", obj ) ? [] : {};
|
||||
for ( key in obj ) {
|
||||
if ( hasOwn.call( obj, key ) ) {
|
||||
val = obj[key];
|
||||
vals[key] = val === Object(val) ? objectValues(val) : val;
|
||||
}
|
||||
}
|
||||
return vals;
|
||||
};
|
||||
|
||||
function Test( settings ) {
|
||||
extend( this, settings );
|
||||
@@ -44,11 +94,11 @@ Test.count = 0;
|
||||
Test.prototype = {
|
||||
init: function() {
|
||||
var a, b, li,
|
||||
tests = id( "qunit-tests" );
|
||||
tests = id( "qunit-tests" );
|
||||
|
||||
if ( tests ) {
|
||||
b = document.createElement( "strong" );
|
||||
b.innerHTML = this.name;
|
||||
b.innerHTML = this.nameHtml;
|
||||
|
||||
// `a` initialized at top of scope
|
||||
a = document.createElement( "a" );
|
||||
@@ -92,6 +142,7 @@ Test.prototype = {
|
||||
teardown: function() {}
|
||||
}, this.moduleTestEnvironment );
|
||||
|
||||
this.started = +new Date();
|
||||
runLoggingCallbacks( "testStart", QUnit, {
|
||||
name: this.testName,
|
||||
module: this.module
|
||||
@@ -111,7 +162,7 @@ Test.prototype = {
|
||||
try {
|
||||
this.testEnvironment.setup.call( this.testEnvironment );
|
||||
} catch( e ) {
|
||||
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
|
||||
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
|
||||
}
|
||||
},
|
||||
run: function() {
|
||||
@@ -120,22 +171,28 @@ Test.prototype = {
|
||||
var running = id( "qunit-testresult" );
|
||||
|
||||
if ( running ) {
|
||||
running.innerHTML = "Running: <br/>" + this.name;
|
||||
running.innerHTML = "Running: <br/>" + this.nameHtml;
|
||||
}
|
||||
|
||||
if ( this.async ) {
|
||||
QUnit.stop();
|
||||
}
|
||||
|
||||
this.callbackStarted = +new Date();
|
||||
|
||||
if ( config.notrycatch ) {
|
||||
this.callback.call( this.testEnvironment, QUnit.assert );
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.callback.call( this.testEnvironment, QUnit.assert );
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
} catch( e ) {
|
||||
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) );
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
|
||||
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
|
||||
// else next test will carry the responsibility
|
||||
saveGlobal();
|
||||
|
||||
@@ -148,38 +205,43 @@ Test.prototype = {
|
||||
teardown: function() {
|
||||
config.current = this;
|
||||
if ( config.notrycatch ) {
|
||||
if ( typeof this.callbackRuntime === "undefined" ) {
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
}
|
||||
this.testEnvironment.teardown.call( this.testEnvironment );
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
this.testEnvironment.teardown.call( this.testEnvironment );
|
||||
} catch( e ) {
|
||||
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
|
||||
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
|
||||
}
|
||||
}
|
||||
checkPollution();
|
||||
},
|
||||
finish: function() {
|
||||
config.current = this;
|
||||
if ( config.requireExpects && this.expected == null ) {
|
||||
if ( config.requireExpects && this.expected === null ) {
|
||||
QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
|
||||
} else if ( this.expected != null && this.expected != this.assertions.length ) {
|
||||
} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
|
||||
QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
|
||||
} else if ( this.expected == null && !this.assertions.length ) {
|
||||
} else if ( this.expected === null && !this.assertions.length ) {
|
||||
QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
|
||||
}
|
||||
|
||||
var assertion, a, b, i, li, ol,
|
||||
var i, assertion, a, b, time, li, ol,
|
||||
test = this,
|
||||
good = 0,
|
||||
bad = 0,
|
||||
tests = id( "qunit-tests" );
|
||||
|
||||
this.runtime = +new Date() - this.started;
|
||||
config.stats.all += this.assertions.length;
|
||||
config.moduleStats.all += this.assertions.length;
|
||||
|
||||
if ( tests ) {
|
||||
ol = document.createElement( "ol" );
|
||||
ol.className = "qunit-assert-list";
|
||||
|
||||
for ( i = 0; i < this.assertions.length; i++ ) {
|
||||
assertion = this.assertions[i];
|
||||
@@ -208,22 +270,22 @@ Test.prototype = {
|
||||
}
|
||||
|
||||
if ( bad === 0 ) {
|
||||
ol.style.display = "none";
|
||||
addClass( ol, "qunit-collapsed" );
|
||||
}
|
||||
|
||||
// `b` initialized at top of scope
|
||||
b = document.createElement( "strong" );
|
||||
b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
|
||||
b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
|
||||
|
||||
addEvent(b, "click", function() {
|
||||
var next = b.nextSibling.nextSibling,
|
||||
display = next.style.display;
|
||||
next.style.display = display === "none" ? "block" : "none";
|
||||
var next = b.parentNode.lastChild,
|
||||
collapsed = hasClass( next, "qunit-collapsed" );
|
||||
( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
|
||||
});
|
||||
|
||||
addEvent(b, "dblclick", function( e ) {
|
||||
var target = e && e.target ? e.target : window.event.srcElement;
|
||||
if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
|
||||
if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
|
||||
target = target.parentNode;
|
||||
}
|
||||
if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
|
||||
@@ -231,13 +293,19 @@ Test.prototype = {
|
||||
}
|
||||
});
|
||||
|
||||
// `time` initialized at top of scope
|
||||
time = document.createElement( "span" );
|
||||
time.className = "runtime";
|
||||
time.innerHTML = this.runtime + " ms";
|
||||
|
||||
// `li` initialized at top of scope
|
||||
li = id( this.id );
|
||||
li.className = bad ? "fail" : "pass";
|
||||
li.removeChild( li.firstChild );
|
||||
a = li.firstChild;
|
||||
li.appendChild( b );
|
||||
li.appendChild ( a );
|
||||
li.appendChild( a );
|
||||
li.appendChild( time );
|
||||
li.appendChild( ol );
|
||||
|
||||
} else {
|
||||
@@ -255,7 +323,8 @@ Test.prototype = {
|
||||
module: this.module,
|
||||
failed: bad,
|
||||
passed: this.assertions.length - bad,
|
||||
total: this.assertions.length
|
||||
total: this.assertions.length,
|
||||
duration: this.runtime
|
||||
});
|
||||
|
||||
QUnit.reset();
|
||||
@@ -321,7 +390,7 @@ QUnit = {
|
||||
|
||||
test: function( testName, expected, callback, async ) {
|
||||
var test,
|
||||
name = "<span class='test-name'>" + escapeInnerText( testName ) + "</span>";
|
||||
nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
|
||||
|
||||
if ( arguments.length === 2 ) {
|
||||
callback = expected;
|
||||
@@ -329,11 +398,11 @@ QUnit = {
|
||||
}
|
||||
|
||||
if ( config.currentModule ) {
|
||||
name = "<span class='module-name'>" + config.currentModule + "</span>: " + name;
|
||||
nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
|
||||
}
|
||||
|
||||
test = new Test({
|
||||
name: name,
|
||||
nameHtml: nameHtml,
|
||||
testName: testName,
|
||||
expected: expected,
|
||||
async: async,
|
||||
@@ -360,6 +429,18 @@ QUnit = {
|
||||
},
|
||||
|
||||
start: function( count ) {
|
||||
// QUnit hasn't been initialized yet.
|
||||
// Note: RequireJS (et al) may delay onLoad
|
||||
if ( config.semaphore === undefined ) {
|
||||
QUnit.begin(function() {
|
||||
// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
|
||||
setTimeout(function() {
|
||||
QUnit.start( count );
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
config.semaphore -= count || 1;
|
||||
// don't start until equal number of stop-calls
|
||||
if ( config.semaphore > 0 ) {
|
||||
@@ -368,6 +449,8 @@ QUnit = {
|
||||
// ignore if start is called more often then stop
|
||||
if ( config.semaphore < 0 ) {
|
||||
config.semaphore = 0;
|
||||
QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
|
||||
return;
|
||||
}
|
||||
// A slight delay, to avoid any current callbacks
|
||||
if ( defined.setTimeout ) {
|
||||
@@ -403,11 +486,14 @@ QUnit = {
|
||||
}
|
||||
};
|
||||
|
||||
// `assert` initialized at top of scope
|
||||
// Asssert helpers
|
||||
// All of these must call either QUnit.push() or manually do:
|
||||
// All of these must either call QUnit.push() or manually do:
|
||||
// - runLoggingCallbacks( "log", .. );
|
||||
// - config.current.assertions.push({ .. });
|
||||
QUnit.assert = {
|
||||
// We attach it to the QUnit object *after* we expose the public API,
|
||||
// otherwise `assert` will become a global variable in browsers (#341).
|
||||
assert = {
|
||||
/**
|
||||
* Asserts rough true-ish result.
|
||||
* @name ok
|
||||
@@ -428,14 +514,14 @@ QUnit.assert = {
|
||||
message: msg
|
||||
};
|
||||
|
||||
msg = escapeInnerText( msg || (result ? "okay" : "failed" ) );
|
||||
msg = escapeText( msg || (result ? "okay" : "failed" ) );
|
||||
msg = "<span class='test-message'>" + msg + "</span>";
|
||||
|
||||
if ( !result ) {
|
||||
source = sourceFromStacktrace( 2 );
|
||||
if ( source ) {
|
||||
details.source = source;
|
||||
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>";
|
||||
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
|
||||
}
|
||||
}
|
||||
runLoggingCallbacks( "log", QUnit, details );
|
||||
@@ -453,6 +539,7 @@ QUnit.assert = {
|
||||
* @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
|
||||
*/
|
||||
equal: function( actual, expected, message ) {
|
||||
/*jshint eqeqeq:false */
|
||||
QUnit.push( expected == actual, actual, expected, message );
|
||||
},
|
||||
|
||||
@@ -461,9 +548,30 @@ QUnit.assert = {
|
||||
* @function
|
||||
*/
|
||||
notEqual: function( actual, expected, message ) {
|
||||
/*jshint eqeqeq:false */
|
||||
QUnit.push( expected != actual, actual, expected, message );
|
||||
},
|
||||
|
||||
/**
|
||||
* @name propEqual
|
||||
* @function
|
||||
*/
|
||||
propEqual: function( actual, expected, message ) {
|
||||
actual = objectValues(actual);
|
||||
expected = objectValues(expected);
|
||||
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
|
||||
},
|
||||
|
||||
/**
|
||||
* @name notPropEqual
|
||||
* @function
|
||||
*/
|
||||
notPropEqual: function( actual, expected, message ) {
|
||||
actual = objectValues(actual);
|
||||
expected = objectValues(expected);
|
||||
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
|
||||
},
|
||||
|
||||
/**
|
||||
* @name deepEqual
|
||||
* @function
|
||||
@@ -496,8 +604,9 @@ QUnit.assert = {
|
||||
QUnit.push( expected !== actual, actual, expected, message );
|
||||
},
|
||||
|
||||
throws: function( block, expected, message ) {
|
||||
"throws": function( block, expected, message ) {
|
||||
var actual,
|
||||
expectedOutput = expected,
|
||||
ok = false;
|
||||
|
||||
// 'expected' is optional
|
||||
@@ -518,18 +627,20 @@ QUnit.assert = {
|
||||
// we don't want to validate thrown error
|
||||
if ( !expected ) {
|
||||
ok = true;
|
||||
expectedOutput = null;
|
||||
// expected is a regexp
|
||||
} else if ( QUnit.objectType( expected ) === "regexp" ) {
|
||||
ok = expected.test( actual );
|
||||
ok = expected.test( errorString( actual ) );
|
||||
// expected is a constructor
|
||||
} else if ( actual instanceof expected ) {
|
||||
ok = true;
|
||||
// expected is a validation function which returns true is validation passed
|
||||
} else if ( expected.call( {}, actual ) === true ) {
|
||||
expectedOutput = null;
|
||||
ok = true;
|
||||
}
|
||||
|
||||
QUnit.push( ok, actual, null, message );
|
||||
QUnit.push( ok, actual, expectedOutput, message );
|
||||
} else {
|
||||
QUnit.pushFailure( message, null, 'No exception was thrown.' );
|
||||
}
|
||||
@@ -538,15 +649,16 @@ QUnit.assert = {
|
||||
|
||||
/**
|
||||
* @deprecate since 1.8.0
|
||||
* Kept assertion helpers in root for backwards compatibility
|
||||
* Kept assertion helpers in root for backwards compatibility.
|
||||
*/
|
||||
extend( QUnit, QUnit.assert );
|
||||
extend( QUnit, assert );
|
||||
|
||||
/**
|
||||
* @deprecated since 1.9.0
|
||||
* Kept global "raises()" for backwards compatibility
|
||||
* Kept root "raises()" for backwards compatibility.
|
||||
* (Note that we don't introduce assert.raises).
|
||||
*/
|
||||
QUnit.raises = QUnit.assert.throws;
|
||||
QUnit.raises = assert[ "throws" ];
|
||||
|
||||
/**
|
||||
* @deprecated since 1.0.0, replaced with error pushes since 1.3.0
|
||||
@@ -622,6 +734,15 @@ config = {
|
||||
moduleDone: []
|
||||
};
|
||||
|
||||
// Export global variables, unless an 'exports' object exists,
|
||||
// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
|
||||
if ( typeof exports === "undefined" ) {
|
||||
extend( window, QUnit );
|
||||
|
||||
// Expose QUnit object
|
||||
window.QUnit = QUnit;
|
||||
}
|
||||
|
||||
// Initialize more QUnit.config and QUnit.urlParams
|
||||
(function() {
|
||||
var i,
|
||||
@@ -655,18 +776,11 @@ config = {
|
||||
QUnit.isLocal = location.protocol === "file:";
|
||||
}());
|
||||
|
||||
// Export global variables, unless an 'exports' object exists,
|
||||
// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
|
||||
if ( typeof exports === "undefined" ) {
|
||||
extend( window, QUnit );
|
||||
|
||||
// Expose QUnit object
|
||||
window.QUnit = QUnit;
|
||||
}
|
||||
|
||||
// Extend QUnit object,
|
||||
// these after set here because they should not be exposed as global functions
|
||||
extend( QUnit, {
|
||||
assert: assert,
|
||||
|
||||
config: config,
|
||||
|
||||
// Initialize the configuration options
|
||||
@@ -681,7 +795,7 @@ extend( QUnit, {
|
||||
autorun: false,
|
||||
filter: "",
|
||||
queue: [],
|
||||
semaphore: 0
|
||||
semaphore: 1
|
||||
});
|
||||
|
||||
var tests, banner, result,
|
||||
@@ -689,7 +803,7 @@ extend( QUnit, {
|
||||
|
||||
if ( qunit ) {
|
||||
qunit.innerHTML =
|
||||
"<h1 id='qunit-header'>" + escapeInnerText( document.title ) + "</h1>" +
|
||||
"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
|
||||
"<h2 id='qunit-banner'></h2>" +
|
||||
"<div id='qunit-testrunner-toolbar'></div>" +
|
||||
"<h2 id='qunit-userAgent'></h2>" +
|
||||
@@ -745,7 +859,7 @@ extend( QUnit, {
|
||||
|
||||
// Safe object type checking
|
||||
is: function( type, obj ) {
|
||||
return QUnit.objectType( obj ) == type;
|
||||
return QUnit.objectType( obj ) === type;
|
||||
},
|
||||
|
||||
objectType: function( obj ) {
|
||||
@@ -757,7 +871,8 @@ extend( QUnit, {
|
||||
return "null";
|
||||
}
|
||||
|
||||
var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || "";
|
||||
var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
|
||||
type = match && match[1] || "";
|
||||
|
||||
switch ( type ) {
|
||||
case "Number":
|
||||
@@ -794,16 +909,16 @@ extend( QUnit, {
|
||||
expected: expected
|
||||
};
|
||||
|
||||
message = escapeInnerText( message ) || ( result ? "okay" : "failed" );
|
||||
message = escapeText( message ) || ( result ? "okay" : "failed" );
|
||||
message = "<span class='test-message'>" + message + "</span>";
|
||||
output = message;
|
||||
|
||||
if ( !result ) {
|
||||
expected = escapeInnerText( QUnit.jsDump.parse(expected) );
|
||||
actual = escapeInnerText( QUnit.jsDump.parse(actual) );
|
||||
expected = escapeText( QUnit.jsDump.parse(expected) );
|
||||
actual = escapeText( QUnit.jsDump.parse(actual) );
|
||||
output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
|
||||
|
||||
if ( actual != expected ) {
|
||||
if ( actual !== expected ) {
|
||||
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
|
||||
output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
|
||||
}
|
||||
@@ -812,7 +927,7 @@ extend( QUnit, {
|
||||
|
||||
if ( source ) {
|
||||
details.source = source;
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
|
||||
}
|
||||
|
||||
output += "</table>";
|
||||
@@ -839,19 +954,19 @@ extend( QUnit, {
|
||||
message: message
|
||||
};
|
||||
|
||||
message = escapeInnerText( message ) || "error";
|
||||
message = escapeText( message ) || "error";
|
||||
message = "<span class='test-message'>" + message + "</span>";
|
||||
output = message;
|
||||
|
||||
output += "<table>";
|
||||
|
||||
if ( actual ) {
|
||||
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeInnerText( actual ) + "</pre></td></tr>";
|
||||
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
|
||||
}
|
||||
|
||||
if ( source ) {
|
||||
details.source = source;
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
|
||||
}
|
||||
|
||||
output += "</table>";
|
||||
@@ -876,7 +991,8 @@ extend( QUnit, {
|
||||
querystring += encodeURIComponent( key ) + "=" +
|
||||
encodeURIComponent( params[ key ] ) + "&";
|
||||
}
|
||||
return window.location.pathname + querystring.slice( 0, -1 );
|
||||
return window.location.protocol + "//" + window.location.host +
|
||||
window.location.pathname + querystring.slice( 0, -1 );
|
||||
},
|
||||
|
||||
extend: extend,
|
||||
@@ -907,7 +1023,7 @@ extend( QUnit.constructor.prototype, {
|
||||
// testStart: { name }
|
||||
testStart: registerLoggingCallback( "testStart" ),
|
||||
|
||||
// testDone: { name, failed, passed, total }
|
||||
// testDone: { name, failed, passed, total, duration }
|
||||
testDone: registerLoggingCallback( "testDone" ),
|
||||
|
||||
// moduleStart: { name }
|
||||
@@ -925,9 +1041,10 @@ QUnit.load = function() {
|
||||
runLoggingCallbacks( "begin", QUnit, {} );
|
||||
|
||||
// Initialize the config, saving the execution queue
|
||||
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter,
|
||||
numModules = 0,
|
||||
moduleFilterHtml = "",
|
||||
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
|
||||
urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
|
||||
numModules = 0,
|
||||
moduleFilterHtml = "",
|
||||
urlConfigHtml = "",
|
||||
oldconfig = extend( {}, config );
|
||||
|
||||
@@ -948,14 +1065,24 @@ QUnit.load = function() {
|
||||
};
|
||||
}
|
||||
config[ val.id ] = QUnit.urlParams[ val.id ];
|
||||
urlConfigHtml += "<input id='qunit-urlconfig-" + val.id + "' name='" + val.id + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + " title='" + val.tooltip + "'><label for='qunit-urlconfig-" + val.id + "' title='" + val.tooltip + "'>" + val.label + "</label>";
|
||||
urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
|
||||
"' name='" + escapeText( val.id ) +
|
||||
"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
|
||||
" title='" + escapeText( val.tooltip ) +
|
||||
"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
|
||||
"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
|
||||
}
|
||||
|
||||
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + ( config.module === undefined ? "selected" : "" ) + ">< All Modules ></option>";
|
||||
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
|
||||
( config.module === undefined ? "selected='selected'" : "" ) +
|
||||
">< All Modules ></option>";
|
||||
|
||||
for ( i in config.modules ) {
|
||||
if ( config.modules.hasOwnProperty( i ) ) {
|
||||
numModules += 1;
|
||||
moduleFilterHtml += "<option value='" + encodeURIComponent(i) + "' " + ( config.module === i ? "selected" : "" ) + ">" + i + "</option>";
|
||||
moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " +
|
||||
( config.module === i ? "selected='selected'" : "" ) +
|
||||
">" + escapeText(i) + "</option>";
|
||||
}
|
||||
}
|
||||
moduleFilterHtml += "</select>";
|
||||
@@ -1014,22 +1141,28 @@ QUnit.load = function() {
|
||||
label.innerHTML = "Hide passed tests";
|
||||
toolbar.appendChild( label );
|
||||
|
||||
urlConfigCheckboxes = document.createElement( 'span' );
|
||||
urlConfigCheckboxes.innerHTML = urlConfigHtml;
|
||||
addEvent( urlConfigCheckboxes, "change", function( event ) {
|
||||
var params = {};
|
||||
params[ event.target.name ] = event.target.checked ? true : undefined;
|
||||
urlConfigCheckboxesContainer = document.createElement("span");
|
||||
urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
|
||||
urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
|
||||
// For oldIE support:
|
||||
// * Add handlers to the individual elements instead of the container
|
||||
// * Use "click" instead of "change"
|
||||
// * Fallback from event.target to event.srcElement
|
||||
addEvents( urlConfigCheckboxes, "click", function( event ) {
|
||||
var params = {},
|
||||
target = event.target || event.srcElement;
|
||||
params[ target.name ] = target.checked ? true : undefined;
|
||||
window.location = QUnit.url( params );
|
||||
});
|
||||
toolbar.appendChild( urlConfigCheckboxes );
|
||||
toolbar.appendChild( urlConfigCheckboxesContainer );
|
||||
|
||||
if (numModules > 1) {
|
||||
moduleFilter = document.createElement( 'span' );
|
||||
moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
|
||||
moduleFilter.innerHTML = moduleFilterHtml;
|
||||
addEvent( moduleFilter, "change", function() {
|
||||
addEvent( moduleFilter.lastChild, "change", function() {
|
||||
var selectBox = moduleFilter.getElementsByTagName("select")[0],
|
||||
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
|
||||
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
|
||||
|
||||
window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
|
||||
});
|
||||
@@ -1106,7 +1239,7 @@ function done() {
|
||||
" milliseconds.<br/>",
|
||||
"<span class='passed'>",
|
||||
passed,
|
||||
"</span> tests of <span class='total'>",
|
||||
"</span> assertions of <span class='total'>",
|
||||
config.stats.all,
|
||||
"</span> passed, <span class='failed'>",
|
||||
config.stats.bad,
|
||||
@@ -1199,7 +1332,7 @@ function validTest( test ) {
|
||||
function extractStacktrace( e, offset ) {
|
||||
offset = offset === undefined ? 3 : offset;
|
||||
|
||||
var stack, include, i, regex;
|
||||
var stack, include, i;
|
||||
|
||||
if ( e.stacktrace ) {
|
||||
// Opera
|
||||
@@ -1213,7 +1346,7 @@ function extractStacktrace( e, offset ) {
|
||||
if ( fileName ) {
|
||||
include = [];
|
||||
for ( i = offset; i < stack.length; i++ ) {
|
||||
if ( stack[ i ].indexOf( fileName ) != -1 ) {
|
||||
if ( stack[ i ].indexOf( fileName ) !== -1 ) {
|
||||
break;
|
||||
}
|
||||
include.push( stack[ i ] );
|
||||
@@ -1242,17 +1375,27 @@ function sourceFromStacktrace( offset ) {
|
||||
}
|
||||
}
|
||||
|
||||
function escapeInnerText( s ) {
|
||||
/**
|
||||
* Escape text for attribute or text content.
|
||||
*/
|
||||
function escapeText( s ) {
|
||||
if ( !s ) {
|
||||
return "";
|
||||
}
|
||||
s = s + "";
|
||||
return s.replace( /[\&<>]/g, function( s ) {
|
||||
// Both single quotes and double quotes (for attributes)
|
||||
return s.replace( /['"<>&]/g, function( s ) {
|
||||
switch( s ) {
|
||||
case "&": return "&";
|
||||
case "<": return "<";
|
||||
case ">": return ">";
|
||||
default: return s;
|
||||
case '\'':
|
||||
return ''';
|
||||
case '"':
|
||||
return '"';
|
||||
case '<':
|
||||
return '<';
|
||||
case '>':
|
||||
return '>';
|
||||
case '&':
|
||||
return '&';
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1300,7 +1443,7 @@ function saveGlobal() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkPollution( name ) {
|
||||
function checkPollution() {
|
||||
var newGlobals,
|
||||
deletedGlobals,
|
||||
old = config.pollution;
|
||||
@@ -1349,16 +1492,53 @@ function extend( a, b ) {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} elem
|
||||
* @param {string} type
|
||||
* @param {Function} fn
|
||||
*/
|
||||
function addEvent( elem, type, fn ) {
|
||||
// Standards-based browsers
|
||||
if ( elem.addEventListener ) {
|
||||
elem.addEventListener( type, fn, false );
|
||||
} else if ( elem.attachEvent ) {
|
||||
elem.attachEvent( "on" + type, fn );
|
||||
// IE
|
||||
} else {
|
||||
fn();
|
||||
elem.attachEvent( "on" + type, fn );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array|NodeList} elems
|
||||
* @param {string} type
|
||||
* @param {Function} fn
|
||||
*/
|
||||
function addEvents( elems, type, fn ) {
|
||||
var i = elems.length;
|
||||
while ( i-- ) {
|
||||
addEvent( elems[i], type, fn );
|
||||
}
|
||||
}
|
||||
|
||||
function hasClass( elem, name ) {
|
||||
return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
|
||||
}
|
||||
|
||||
function addClass( elem, name ) {
|
||||
if ( !hasClass( elem, name ) ) {
|
||||
elem.className += (elem.className ? " " : "") + name;
|
||||
}
|
||||
}
|
||||
|
||||
function removeClass( elem, name ) {
|
||||
var set = " " + elem.className + " ";
|
||||
// Class name may appear multiple times
|
||||
while ( set.indexOf(" " + name + " ") > -1 ) {
|
||||
set = set.replace(" " + name + " " , " ");
|
||||
}
|
||||
// If possible, trim it for prettiness, but not neccecarily
|
||||
elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
|
||||
}
|
||||
|
||||
function id( name ) {
|
||||
return !!( typeof document !== "undefined" && document && document.getElementById ) &&
|
||||
document.getElementById( name );
|
||||
@@ -1372,7 +1552,6 @@ function registerLoggingCallback( key ) {
|
||||
|
||||
// Supports deprecated method of completely overwriting logging callbacks
|
||||
function runLoggingCallbacks( key, scope, args ) {
|
||||
//debugger;
|
||||
var i, callbacks;
|
||||
if ( QUnit.hasOwnProperty( key ) ) {
|
||||
QUnit[ key ].call(scope, args );
|
||||
@@ -1414,6 +1593,7 @@ QUnit.equiv = (function() {
|
||||
|
||||
// for string, boolean, number and null
|
||||
function useStrictEquality( b, a ) {
|
||||
/*jshint eqeqeq:false */
|
||||
if ( b instanceof a.constructor || a instanceof b.constructor ) {
|
||||
// to catch short annotaion VS 'new' annotation of a
|
||||
// declaration
|
||||
@@ -1610,7 +1790,8 @@ QUnit.jsDump = (function() {
|
||||
|
||||
var reName = /^function (\w+)/,
|
||||
jsDump = {
|
||||
parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance
|
||||
// type is used mostly internally, you can fix a (custom)type in advance
|
||||
parse: function( obj, type, stack ) {
|
||||
stack = stack || [ ];
|
||||
var inStack, res,
|
||||
parser = this.parsers[ type || this.typeOf(obj) ];
|
||||
@@ -1618,18 +1799,16 @@ QUnit.jsDump = (function() {
|
||||
type = typeof parser;
|
||||
inStack = inArray( obj, stack );
|
||||
|
||||
if ( inStack != -1 ) {
|
||||
if ( inStack !== -1 ) {
|
||||
return "recursion(" + (inStack - stack.length) + ")";
|
||||
}
|
||||
//else
|
||||
if ( type == "function" ) {
|
||||
if ( type === "function" ) {
|
||||
stack.push( obj );
|
||||
res = parser.call( this, obj, stack );
|
||||
stack.pop();
|
||||
return res;
|
||||
}
|
||||
// else
|
||||
return ( type == "string" ) ? parser : this.parsers.error;
|
||||
return ( type === "string" ) ? parser : this.parsers.error;
|
||||
},
|
||||
typeOf: function( obj ) {
|
||||
var type;
|
||||
@@ -1656,6 +1835,8 @@ QUnit.jsDump = (function() {
|
||||
( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
|
||||
) {
|
||||
type = "array";
|
||||
} else if ( obj.constructor === Error.prototype.constructor ) {
|
||||
type = "error";
|
||||
} else {
|
||||
type = typeof obj;
|
||||
}
|
||||
@@ -1664,7 +1845,8 @@ QUnit.jsDump = (function() {
|
||||
separator: function() {
|
||||
return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? " " : " ";
|
||||
},
|
||||
indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
|
||||
// extra can be a number, shortcut for increasing-calling-decreasing
|
||||
indent: function( extra ) {
|
||||
if ( !this.multiline ) {
|
||||
return "";
|
||||
}
|
||||
@@ -1693,13 +1875,16 @@ QUnit.jsDump = (function() {
|
||||
parsers: {
|
||||
window: "[Window]",
|
||||
document: "[Document]",
|
||||
error: "[ERROR]", //when no parser is found, shouldn"t happen
|
||||
error: function(error) {
|
||||
return "Error(\"" + error.message + "\")";
|
||||
},
|
||||
unknown: "[Unknown]",
|
||||
"null": "null",
|
||||
"undefined": "undefined",
|
||||
"function": function( fn ) {
|
||||
var ret = "function",
|
||||
name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE
|
||||
// functions never have name in IE
|
||||
name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
|
||||
|
||||
if ( name ) {
|
||||
ret += " " + name;
|
||||
@@ -1715,13 +1900,9 @@ QUnit.jsDump = (function() {
|
||||
object: function( map, stack ) {
|
||||
var ret = [ ], keys, key, val, i;
|
||||
QUnit.jsDump.up();
|
||||
if ( Object.keys ) {
|
||||
keys = Object.keys( map );
|
||||
} else {
|
||||
keys = [];
|
||||
for ( key in map ) {
|
||||
keys.push( key );
|
||||
}
|
||||
keys = [];
|
||||
for ( key in map ) {
|
||||
keys.push( key );
|
||||
}
|
||||
keys.sort();
|
||||
for ( i = 0; i < keys.length; i++ ) {
|
||||
@@ -1733,21 +1914,34 @@ QUnit.jsDump = (function() {
|
||||
return join( "{", ret, "}" );
|
||||
},
|
||||
node: function( node ) {
|
||||
var a, val,
|
||||
var len, i, val,
|
||||
open = QUnit.jsDump.HTML ? "<" : "<",
|
||||
close = QUnit.jsDump.HTML ? ">" : ">",
|
||||
tag = node.nodeName.toLowerCase(),
|
||||
ret = open + tag;
|
||||
ret = open + tag,
|
||||
attrs = node.attributes;
|
||||
|
||||
for ( a in QUnit.jsDump.DOMAttrs ) {
|
||||
val = node[ QUnit.jsDump.DOMAttrs[a] ];
|
||||
if ( val ) {
|
||||
ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" );
|
||||
if ( attrs ) {
|
||||
for ( i = 0, len = attrs.length; i < len; i++ ) {
|
||||
val = attrs[i].nodeValue;
|
||||
// IE6 includes all attributes in .attributes, even ones not explicitly set.
|
||||
// Those have values like undefined, null, 0, false, "" or "inherit".
|
||||
if ( val && val !== "inherit" ) {
|
||||
ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret + close + open + "/" + tag + close;
|
||||
ret += close;
|
||||
|
||||
// Show content of TextNode or CDATASection
|
||||
if ( node.nodeType === 3 || node.nodeType === 4 ) {
|
||||
ret += node.nodeValue;
|
||||
}
|
||||
|
||||
return ret + open + "/" + tag + close;
|
||||
},
|
||||
functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function
|
||||
// function calls it internally, it's the arguments part of the function
|
||||
functionArgs: function( fn ) {
|
||||
var args,
|
||||
l = fn.length;
|
||||
|
||||
@@ -1757,54 +1951,34 @@ QUnit.jsDump = (function() {
|
||||
|
||||
args = new Array(l);
|
||||
while ( l-- ) {
|
||||
args[l] = String.fromCharCode(97+l);//97 is 'a'
|
||||
// 97 is 'a'
|
||||
args[l] = String.fromCharCode(97+l);
|
||||
}
|
||||
return " " + args.join( ", " ) + " ";
|
||||
},
|
||||
key: quote, //object calls it internally, the key part of an item in a map
|
||||
functionCode: "[code]", //function calls it internally, it's the content of the function
|
||||
attribute: quote, //node calls it internally, it's an html attribute value
|
||||
// object calls it internally, the key part of an item in a map
|
||||
key: quote,
|
||||
// function calls it internally, it's the content of the function
|
||||
functionCode: "[code]",
|
||||
// node calls it internally, it's an html attribute value
|
||||
attribute: quote,
|
||||
string: quote,
|
||||
date: quote,
|
||||
regexp: literal, //regex
|
||||
regexp: literal,
|
||||
number: literal,
|
||||
"boolean": literal
|
||||
},
|
||||
DOMAttrs: {
|
||||
//attributes to dump from nodes, name=>realName
|
||||
id: "id",
|
||||
name: "name",
|
||||
"class": "className"
|
||||
},
|
||||
HTML: false,//if true, entities are escaped ( <, >, \t, space and \n )
|
||||
indentChar: " ",//indentation unit
|
||||
multiline: true //if true, items in a collection, are separated by a \n, else just a space.
|
||||
// if true, entities are escaped ( <, >, \t, space and \n )
|
||||
HTML: false,
|
||||
// indentation unit
|
||||
indentChar: " ",
|
||||
// if true, items in a collection, are separated by a \n, else just a space.
|
||||
multiline: true
|
||||
};
|
||||
|
||||
return jsDump;
|
||||
}());
|
||||
|
||||
// from Sizzle.js
|
||||
function getText( elems ) {
|
||||
var i, elem,
|
||||
ret = "";
|
||||
|
||||
for ( i = 0; elems[i]; i++ ) {
|
||||
elem = elems[i];
|
||||
|
||||
// Get the text from text nodes and CDATA nodes
|
||||
if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
|
||||
ret += elem.nodeValue;
|
||||
|
||||
// Traverse everything else, except comment nodes
|
||||
} else if ( elem.nodeType !== 8 ) {
|
||||
ret += getText( elem.childNodes );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// from jquery.js
|
||||
function inArray( elem, array ) {
|
||||
if ( array.indexOf ) {
|
||||
@@ -1835,13 +2009,14 @@ function inArray( elem, array ) {
|
||||
* QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
|
||||
*/
|
||||
QUnit.diff = (function() {
|
||||
/*jshint eqeqeq:false, eqnull:true */
|
||||
function diff( o, n ) {
|
||||
var i,
|
||||
ns = {},
|
||||
os = {};
|
||||
|
||||
for ( i = 0; i < n.length; i++ ) {
|
||||
if ( ns[ n[i] ] == null ) {
|
||||
if ( !hasOwn.call( ns, n[i] ) ) {
|
||||
ns[ n[i] ] = {
|
||||
rows: [],
|
||||
o: null
|
||||
@@ -1851,7 +2026,7 @@ QUnit.diff = (function() {
|
||||
}
|
||||
|
||||
for ( i = 0; i < o.length; i++ ) {
|
||||
if ( os[ o[i] ] == null ) {
|
||||
if ( !hasOwn.call( os, o[i] ) ) {
|
||||
os[ o[i] ] = {
|
||||
rows: [],
|
||||
n: null
|
||||
@@ -1864,7 +2039,7 @@ QUnit.diff = (function() {
|
||||
if ( !hasOwn.call( ns, i ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) {
|
||||
if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
|
||||
n[ ns[i].rows[0] ] = {
|
||||
text: n[ ns[i].rows[0] ],
|
||||
row: os[i].rows[0]
|
||||
@@ -1970,7 +2145,7 @@ QUnit.diff = (function() {
|
||||
|
||||
// for CommonJS enviroments, export everything
|
||||
if ( typeof exports !== "undefined" ) {
|
||||
extend(exports, QUnit);
|
||||
extend( exports, QUnit );
|
||||
}
|
||||
|
||||
// get at whatever the global object is, like window in browsers
|
||||
|
||||
39
vendor/requirejs/require.js
vendored
39
vendor/requirejs/require.js
vendored
@@ -1,18 +1,18 @@
|
||||
/** vim: et:ts=4:sw=4:sts=4
|
||||
* @license RequireJS 2.1.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* @license RequireJS 2.1.4 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/jrburke/requirejs for details
|
||||
*/
|
||||
//Not using strict: uneven strict support in browsers, #392, and causes
|
||||
//problems with requirejs.exec()/transpiler plugins that may not be strict.
|
||||
/*jslint regexp: true, nomen: true, sloppy: true */
|
||||
/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
|
||||
/*global window, navigator, document, importScripts, setTimeout, opera */
|
||||
|
||||
var requirejs, require, define;
|
||||
(function (global) {
|
||||
var req, s, head, baseElement, dataMain, src,
|
||||
interactiveScript, currentlyAddingScript, mainScript, subPath,
|
||||
version = '2.1.2',
|
||||
version = '2.1.4',
|
||||
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
|
||||
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
|
||||
jsSuffixRegExp = /\.js$/,
|
||||
@@ -21,7 +21,6 @@ var requirejs, require, define;
|
||||
ostring = op.toString,
|
||||
hasOwn = op.hasOwnProperty,
|
||||
ap = Array.prototype,
|
||||
aps = ap.slice,
|
||||
apsp = ap.splice,
|
||||
isBrowser = !!(typeof window !== 'undefined' && navigator && document),
|
||||
isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
|
||||
@@ -918,8 +917,7 @@ var requirejs, require, define;
|
||||
name = this.map.name,
|
||||
parentName = this.map.parentMap ? this.map.parentMap.name : null,
|
||||
localRequire = context.makeRequire(map.parentMap, {
|
||||
enableBuildCallback: true,
|
||||
skipMap: true
|
||||
enableBuildCallback: true
|
||||
});
|
||||
|
||||
//If current map is not normalized, wait for that
|
||||
@@ -1017,8 +1015,11 @@ var requirejs, require, define;
|
||||
try {
|
||||
req.exec(text);
|
||||
} catch (e) {
|
||||
throw new Error('fromText eval for ' + moduleName +
|
||||
' failed: ' + e);
|
||||
return onError(makeError('fromtexteval',
|
||||
'fromText eval for ' + id +
|
||||
' failed: ' + e,
|
||||
e,
|
||||
[id]));
|
||||
}
|
||||
|
||||
if (hasInteractive) {
|
||||
@@ -1395,16 +1396,21 @@ var requirejs, require, define;
|
||||
* plain URLs like nameToUrl.
|
||||
*/
|
||||
toUrl: function (moduleNamePlusExt) {
|
||||
var index = moduleNamePlusExt.lastIndexOf('.'),
|
||||
ext = null;
|
||||
var ext, url,
|
||||
index = moduleNamePlusExt.lastIndexOf('.'),
|
||||
segment = moduleNamePlusExt.split('/')[0],
|
||||
isRelative = segment === '.' || segment === '..';
|
||||
|
||||
if (index !== -1) {
|
||||
//Have a file extension alias, and it is not the
|
||||
//dots from a relative path.
|
||||
if (index !== -1 && (!isRelative || index > 1)) {
|
||||
ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
|
||||
moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
|
||||
}
|
||||
|
||||
return context.nameToUrl(normalize(moduleNamePlusExt,
|
||||
relMap && relMap.id, true), ext);
|
||||
url = context.nameToUrl(normalize(moduleNamePlusExt,
|
||||
relMap && relMap.id, true), ext || '.fake');
|
||||
return ext ? url : url.substring(0, url.length - 5);
|
||||
},
|
||||
|
||||
defined: function (id) {
|
||||
@@ -1449,10 +1455,11 @@ var requirejs, require, define;
|
||||
|
||||
/**
|
||||
* Called to enable a module if it is still in the registry
|
||||
* awaiting enablement. parent module is passed in for context,
|
||||
* used by the optimizer.
|
||||
* awaiting enablement. A second arg, parent, the parent module,
|
||||
* is passed in for context, when this method is overriden by
|
||||
* the optimizer. Not shown here to keep code compact.
|
||||
*/
|
||||
enable: function (depMap, parent) {
|
||||
enable: function (depMap) {
|
||||
var mod = getOwn(registry, depMap.id);
|
||||
if (mod) {
|
||||
getModule(depMap).enable();
|
||||
|
||||
4
vendor/underscore/LICENSE
vendored
4
vendor/underscore/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud
|
||||
Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
@@ -19,4 +19,4 @@ 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.
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
2
vendor/underscore/test/arrays.js
vendored
2
vendor/underscore/test/arrays.js
vendored
@@ -182,7 +182,7 @@ $(document).ready(function() {
|
||||
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
|
||||
|
||||
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
|
||||
index = _.lastIndexOf(numbers, 2, 2);
|
||||
var index = _.lastIndexOf(numbers, 2, 2);
|
||||
equal(index, 1, 'supports the fromIndex argument');
|
||||
});
|
||||
|
||||
|
||||
10
vendor/underscore/test/collections.js
vendored
10
vendor/underscore/test/collections.js
vendored
@@ -22,7 +22,7 @@ $(document).ready(function() {
|
||||
equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.');
|
||||
delete obj.constructor.prototype.four;
|
||||
|
||||
answer = null;
|
||||
var answer = null;
|
||||
_.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
|
||||
ok(answer, 'can reference the original collection from inside the iterator');
|
||||
|
||||
@@ -260,6 +260,14 @@ $(document).ready(function() {
|
||||
equal(result[0].a, 1);
|
||||
});
|
||||
|
||||
test('findWhere', function() {
|
||||
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
|
||||
var result = _.findWhere(list, {a: 1});
|
||||
deepEqual(result, {a: 1, b: 2});
|
||||
result = _.findWhere(list, {b: 4});
|
||||
deepEqual(result, {a: 1, b: 4});
|
||||
});
|
||||
|
||||
test('max', function() {
|
||||
equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
|
||||
|
||||
|
||||
137
vendor/underscore/test/functions.js
vendored
137
vendor/underscore/test/functions.js
vendored
@@ -18,10 +18,10 @@ $(document).ready(function() {
|
||||
func = _.bind(func, this, 'hello');
|
||||
equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
|
||||
|
||||
var func = _.bind(func, this, 'curly');
|
||||
func = _.bind(func, this, 'curly');
|
||||
equal(func(), 'hello: curly', 'the function was completely applied in advance');
|
||||
|
||||
var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
|
||||
func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
|
||||
func = _.bind(func, this, 'hello', 'moe', 'curly');
|
||||
equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
|
||||
|
||||
@@ -34,10 +34,15 @@ $(document).ready(function() {
|
||||
// To test this with a modern browser, set underscore's nativeBind to undefined
|
||||
var F = function () { return this; };
|
||||
var Boundf = _.bind(F, {hello: "moe curly"});
|
||||
var newBoundf = new Boundf();
|
||||
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");
|
||||
});
|
||||
|
||||
test("partial", function() {
|
||||
var obj = {name: 'moe'};
|
||||
var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
|
||||
|
||||
obj.func = _.partial(func, 'a', 'b');
|
||||
equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
|
||||
});
|
||||
|
||||
test("bindAll", function() {
|
||||
@@ -95,80 +100,67 @@ $(document).ready(function() {
|
||||
asyncTest("throttle", 2, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
throttledIncr(); throttledIncr(); throttledIncr();
|
||||
setTimeout(throttledIncr, 70);
|
||||
setTimeout(throttledIncr, 120);
|
||||
setTimeout(throttledIncr, 140);
|
||||
setTimeout(throttledIncr, 190);
|
||||
setTimeout(throttledIncr, 220);
|
||||
setTimeout(throttledIncr, 240);
|
||||
_.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30);
|
||||
_.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400);
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
throttledIncr(); throttledIncr();
|
||||
|
||||
equal(counter, 1, "incr was called immediately");
|
||||
_.delay(function(){ equal(counter, 2, "incr was throttled"); start(); }, 64);
|
||||
});
|
||||
|
||||
asyncTest("throttle arguments", 2, function() {
|
||||
var value = 0;
|
||||
var update = function(val){ value = val; };
|
||||
var throttledUpdate = _.throttle(update, 100);
|
||||
throttledUpdate(1); throttledUpdate(2); throttledUpdate(3);
|
||||
setTimeout(function(){ throttledUpdate(4); }, 120);
|
||||
setTimeout(function(){ throttledUpdate(5); }, 140);
|
||||
setTimeout(function(){ throttledUpdate(6); }, 250);
|
||||
_.delay(function(){ equal(value, 1, "updated to latest value"); }, 40);
|
||||
_.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400);
|
||||
var throttledUpdate = _.throttle(update, 32);
|
||||
throttledUpdate(1); throttledUpdate(2);
|
||||
_.delay(function(){ throttledUpdate(3); }, 64);
|
||||
equal(value, 1, "updated to latest value");
|
||||
_.delay(function(){ equal(value, 3, "updated to latest value"); start(); }, 96);
|
||||
});
|
||||
|
||||
asyncTest("throttle once", 2, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ return ++counter; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
var result = throttledIncr();
|
||||
_.delay(function(){
|
||||
equal(result, 1, "throttled functions return their value");
|
||||
equal(counter, 1, "incr was called once"); start();
|
||||
}, 220);
|
||||
}, 64);
|
||||
});
|
||||
|
||||
asyncTest("throttle twice", 1, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
throttledIncr(); throttledIncr();
|
||||
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220);
|
||||
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 64);
|
||||
});
|
||||
|
||||
asyncTest("throttle repeatedly with results", 9, function() {
|
||||
asyncTest("throttle repeatedly with results", 6, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ return ++counter; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
var throttledIncr = _.throttle(incr, 64);
|
||||
var results = [];
|
||||
var saveResult = function() { results.push(throttledIncr()); };
|
||||
saveResult(); saveResult(); saveResult();
|
||||
setTimeout(saveResult, 70);
|
||||
setTimeout(saveResult, 120);
|
||||
setTimeout(saveResult, 140);
|
||||
setTimeout(saveResult, 190);
|
||||
setTimeout(saveResult, 240);
|
||||
setTimeout(saveResult, 260);
|
||||
saveResult(); saveResult();
|
||||
_.delay(saveResult, 32);
|
||||
_.delay(saveResult, 80);
|
||||
_.delay(saveResult, 96);
|
||||
_.delay(saveResult, 144);
|
||||
_.delay(function() {
|
||||
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], 1, "incr was throttled");
|
||||
equal(results[4], 2, "incr was called twice");
|
||||
equal(results[5], 2, "incr was throttled");
|
||||
equal(results[6], 2, "incr was throttled");
|
||||
equal(results[7], 3, "incr was called thrice");
|
||||
equal(results[8], 3, "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();
|
||||
}, 400);
|
||||
}, 192);
|
||||
});
|
||||
|
||||
asyncTest("throttle triggers trailing call after repeatedly invoked", 2, function() {
|
||||
var actual;
|
||||
asyncTest("throttle triggers trailing call when invoked repeatedly", 2, function() {
|
||||
var counter = 0;
|
||||
var limit = 80;
|
||||
var limit = 48;
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
|
||||
@@ -176,62 +168,49 @@ $(document).ready(function() {
|
||||
while ((new Date - stamp) < limit) {
|
||||
throttledIncr();
|
||||
}
|
||||
_.delay(function() {
|
||||
actual = counter + 2;
|
||||
throttledIncr();
|
||||
throttledIncr();
|
||||
}, 64);
|
||||
|
||||
_.delay(function() {
|
||||
equal(counter, actual);
|
||||
start();
|
||||
}, 128);
|
||||
|
||||
var lastCount = counter;
|
||||
ok(counter > 1);
|
||||
|
||||
_.delay(function() {
|
||||
ok(counter > lastCount);
|
||||
start();
|
||||
}, 96);
|
||||
});
|
||||
|
||||
asyncTest("debounce", 1, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ counter++; };
|
||||
var debouncedIncr = _.debounce(incr, 50);
|
||||
debouncedIncr(); debouncedIncr(); debouncedIncr();
|
||||
setTimeout(debouncedIncr, 30);
|
||||
setTimeout(debouncedIncr, 60);
|
||||
setTimeout(debouncedIncr, 90);
|
||||
setTimeout(debouncedIncr, 120);
|
||||
setTimeout(debouncedIncr, 150);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
|
||||
var debouncedIncr = _.debounce(incr, 32);
|
||||
debouncedIncr(); debouncedIncr();
|
||||
_.delay(debouncedIncr, 16);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96);
|
||||
});
|
||||
|
||||
asyncTest("debounce asap", 5, function() {
|
||||
var a, b, c;
|
||||
asyncTest("debounce asap", 4, function() {
|
||||
var a, b;
|
||||
var counter = 0;
|
||||
var incr = function(){ return ++counter; };
|
||||
var debouncedIncr = _.debounce(incr, 50, true);
|
||||
var debouncedIncr = _.debounce(incr, 64, true);
|
||||
a = debouncedIncr();
|
||||
b = debouncedIncr();
|
||||
c = debouncedIncr();
|
||||
equal(a, 1);
|
||||
equal(b, 1);
|
||||
equal(c, 1);
|
||||
equal(counter, 1, 'incr was called immediately');
|
||||
setTimeout(debouncedIncr, 30);
|
||||
setTimeout(debouncedIncr, 60);
|
||||
setTimeout(debouncedIncr, 90);
|
||||
setTimeout(debouncedIncr, 120);
|
||||
setTimeout(debouncedIncr, 150);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
|
||||
_.delay(debouncedIncr, 16);
|
||||
_.delay(debouncedIncr, 32);
|
||||
_.delay(debouncedIncr, 48);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 128);
|
||||
});
|
||||
|
||||
asyncTest("debounce asap recursively", 2, function() {
|
||||
var counter = 0;
|
||||
var debouncedIncr = _.debounce(function(){
|
||||
counter++;
|
||||
if (counter < 5) debouncedIncr();
|
||||
}, 50, true);
|
||||
if (counter < 10) debouncedIncr();
|
||||
}, 32, true);
|
||||
debouncedIncr();
|
||||
equal(counter, 1, 'incr was called immediately');
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70);
|
||||
equal(counter, 1, "incr was called immediately");
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96);
|
||||
});
|
||||
|
||||
test("once", function() {
|
||||
|
||||
4
vendor/underscore/test/objects.js
vendored
4
vendor/underscore/test/objects.js
vendored
@@ -555,7 +555,7 @@ $(document).ready(function() {
|
||||
value();
|
||||
ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain');
|
||||
});
|
||||
|
||||
|
||||
test("has", function () {
|
||||
var obj = {foo: "bar", func: function () {} };
|
||||
ok (_.has(obj, "foo"), "has() checks that the object has a property.");
|
||||
@@ -563,7 +563,7 @@ $(document).ready(function() {
|
||||
ok (_.has(obj, "func"), "has() works for functions too.");
|
||||
obj.hasOwnProperty = null;
|
||||
ok (_.has(obj, "foo"), "has() works even when the hasOwnProperty method is deleted.");
|
||||
child = {};
|
||||
var child = {};
|
||||
child.prototype = obj;
|
||||
ok (_.has(child, "foo") == false, "has() does not check the prototype chain for a property.")
|
||||
});
|
||||
|
||||
20
vendor/underscore/test/utility.js
vendored
20
vendor/underscore/test/utility.js
vendored
@@ -25,6 +25,20 @@ $(document).ready(function() {
|
||||
equal(_.identity(moe), moe, 'moe is the same as his identity');
|
||||
});
|
||||
|
||||
test("random", function() {
|
||||
var array = _.range(1000);
|
||||
var min = Math.pow(2, 31);
|
||||
var max = Math.pow(2, 62);
|
||||
|
||||
ok(_.every(array, function() {
|
||||
return _.random(min, max) >= min;
|
||||
}), "should produce a random number greater than or equal to the minimum number");
|
||||
|
||||
ok(_.some(array, function() {
|
||||
return _.random(Number.MAX_VALUE) > 0;
|
||||
}), "should produce a random number when passed `Number.MAX_VALUE`");
|
||||
});
|
||||
|
||||
test("uniqueId", function() {
|
||||
var ids = [], i = 0;
|
||||
while(i++ < 100) ids.push(_.uniqueId());
|
||||
@@ -82,7 +96,7 @@ $(document).ready(function() {
|
||||
equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
|
||||
|
||||
var fancyTemplate = _.template("<ul><% \
|
||||
for (key in people) { \
|
||||
for (var key in people) { \
|
||||
%><li><%= people[key] %></li><% } %></ul>");
|
||||
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');
|
||||
@@ -137,7 +151,7 @@ $(document).ready(function() {
|
||||
interpolate : /\{\{=([\s\S]+?)\}\}/g
|
||||
};
|
||||
|
||||
var custom = _.template("<ul>{{ for (key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
|
||||
var custom = _.template("<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
|
||||
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');
|
||||
|
||||
@@ -152,7 +166,7 @@ $(document).ready(function() {
|
||||
interpolate : /<\?=([\s\S]+?)\?>/g
|
||||
};
|
||||
|
||||
var customWithSpecialChars = _.template("<ul><? for (key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
|
||||
var customWithSpecialChars = _.template("<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
|
||||
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');
|
||||
|
||||
|
||||
6
vendor/underscore/underscore-min.js
vendored
6
vendor/underscore/underscore-min.js
vendored
File diff suppressed because one or more lines are too long
58
vendor/underscore/underscore.js
vendored
58
vendor/underscore/underscore.js
vendored
@@ -1,6 +1,6 @@
|
||||
// Underscore.js 1.4.3
|
||||
// Underscore.js 1.4.4
|
||||
// http://underscorejs.org
|
||||
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore may be freely distributed under the MIT license.
|
||||
|
||||
(function() {
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.4.3';
|
||||
_.VERSION = '1.4.4';
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
@@ -224,8 +224,9 @@
|
||||
// Invoke a method (with arguments) on every item in a collection.
|
||||
_.invoke = function(obj, method) {
|
||||
var args = slice.call(arguments, 2);
|
||||
var isFunc = _.isFunction(method);
|
||||
return _.map(obj, function(value) {
|
||||
return (_.isFunction(method) ? method : value[method]).apply(value, args);
|
||||
return (isFunc ? method : value[method]).apply(value, args);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -235,10 +236,10 @@
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `filter`: selecting only objects
|
||||
// with specific `key:value` pairs.
|
||||
_.where = function(obj, attrs) {
|
||||
if (_.isEmpty(attrs)) return [];
|
||||
return _.filter(obj, function(value) {
|
||||
// containing specific `key:value` pairs.
|
||||
_.where = function(obj, attrs, first) {
|
||||
if (_.isEmpty(attrs)) return first ? null : [];
|
||||
return _[first ? 'find' : 'filter'](obj, function(value) {
|
||||
for (var key in attrs) {
|
||||
if (attrs[key] !== value[key]) return false;
|
||||
}
|
||||
@@ -246,6 +247,12 @@
|
||||
});
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `find`: getting the first object
|
||||
// containing specific `key:value` pairs.
|
||||
_.findWhere = function(obj, attrs) {
|
||||
return _.where(obj, attrs, true);
|
||||
};
|
||||
|
||||
// Return the maximum element or (element-based computation).
|
||||
// Can't optimize arrays of integers longer than 65,535 elements.
|
||||
// See: https://bugs.webkit.org/show_bug.cgi?id=80797
|
||||
@@ -567,26 +574,23 @@
|
||||
// Function (ahem) Functions
|
||||
// ------------------
|
||||
|
||||
// Reusable constructor function for prototype setting.
|
||||
var ctor = function(){};
|
||||
|
||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||
// optionally). Binding with arguments is also known as `curry`.
|
||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
||||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||||
// available.
|
||||
_.bind = function(func, context) {
|
||||
var args, bound;
|
||||
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
if (!_.isFunction(func)) throw new TypeError;
|
||||
args = slice.call(arguments, 2);
|
||||
return bound = function() {
|
||||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||||
ctor.prototype = func.prototype;
|
||||
var self = new ctor;
|
||||
ctor.prototype = null;
|
||||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||||
if (Object(result) === result) return result;
|
||||
return self;
|
||||
var args = slice.call(arguments, 2);
|
||||
return function() {
|
||||
return func.apply(context, args.concat(slice.call(arguments)));
|
||||
};
|
||||
};
|
||||
|
||||
// Partially apply a function by creating a version that has had some of its
|
||||
// arguments pre-filled, without changing its dynamic `this` context.
|
||||
_.partial = function(func) {
|
||||
var args = slice.call(arguments, 1);
|
||||
return function() {
|
||||
return func.apply(this, args.concat(slice.call(arguments)));
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1019,7 +1023,7 @@
|
||||
max = min;
|
||||
min = 0;
|
||||
}
|
||||
return min + (0 | Math.random() * (max - min + 1));
|
||||
return min + Math.floor(Math.random() * (max - min + 1));
|
||||
};
|
||||
|
||||
// List of HTML entities for escaping.
|
||||
@@ -1075,7 +1079,7 @@
|
||||
// Useful for temporary DOM ids.
|
||||
var idCounter = 0;
|
||||
_.uniqueId = function(prefix) {
|
||||
var id = '' + (++idCounter);
|
||||
var id = ++idCounter + '';
|
||||
return prefix ? prefix + id : id;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user