Compare commits

...

38 Commits
0.8.0 ... 0.8.2

Author SHA1 Message Date
John-David Dalton
219138ade6 Bump to v0.8.2.
Former-commit-id: edbb9d995a63ec8fd5a3b1a47ccda7b30c353b35
2012-10-10 00:03:39 -07:00
John-David Dalton
9086d189b9 Update vendors.
Former-commit-id: e88301bddf23f177a2d14f2c729877eaede022e5
2012-10-09 20:11:57 -07:00
Kit Cambridge
d1178defe0 Add a note about npm link. See #88.
Former-commit-id: 11c4a9bce02e5f143b09d0edff80362e2e824b10
2012-10-09 15:22:26 -07:00
John-David Dalton
691a561a95 Merge pull request #87 from danheberden/typo_fix
Fix typo in `_.indexOf` docs.

Former-commit-id: 25305344f272cb875a612e37a93ae252a53e1b4b
2012-10-09 13:56:59 -07:00
Dan Heberden
aaaac93bd0 fix tiny baby super small almost didn't need to worry about fixing typo from isSorted to fromIndex for indexOf method
Former-commit-id: 6f2a7b3e11c4830ec47c174f24badca3ef2e6530
2012-10-09 16:53:56 -04:00
John-David Dalton
fd790566b2 Ensure _.throttle clears the timeout when func is called. [closes #86]
Former-commit-id: 6f3b777aa247f059d97f965c02323d4ee6ab8464
2012-10-09 02:15:06 -07:00
John-David Dalton
db3b429784 Update _.min, _.max, _.shuffle build dependencies.
Former-commit-id: 21c4c99f8ead92b90b46c299fee59098131758b1
2012-10-09 01:43:24 -07:00
John-David Dalton
40ed3278d4 Rebuild minified files and docs.
Former-commit-id: b14af8d9fcb9046c2faf4374fe2e6e83c4f4f835
2012-10-09 01:02:14 -07:00
John-David Dalton
d174b13111 Add object iteration unit tests for _.max, _.min, _.shuffle.
Former-commit-id: 45129100fbbfa14610cacb055c1fa393ae6ce153
2012-10-09 00:59:55 -07:00
John-David Dalton
1708663b32 Move _.max, _.min, _.shuffle back to "Collections" methods for compat but still optimized for arrays.
Former-commit-id: 28cd9298915ad123445400a5d061ac8e9432eb6b
2012-10-09 00:48:02 -07:00
John-David Dalton
6fdce4ad0d Re-optimize _.max, _.min, and _.sortedIndex.
Former-commit-id: 7f449a4fde6777f14a1def0d767f2926bdea07c9
2012-10-09 00:17:10 -07:00
John-David Dalton
fff8d5f07d Cleanup var names in lodash.js and continue to optimize for gzip.
Former-commit-id: 00d76bd7ab8b35d2b45237224662849e42d00bac
2012-10-07 22:26:23 -07:00
John-David Dalton
9c8e1f4706 Reduce _.compact and revert _.random use in _.shuffle.
Former-commit-id: 17d153cb09c262830f1497f93c0f3d9b279c8f8a
2012-10-07 19:32:56 -07:00
John-David Dalton
0a1036c78f Add unit tests to check "Collections" methods return values.
Former-commit-id: 6ac6cd97414035f74a102a51e913099e744d9a93
2012-10-07 18:18:20 -07:00
John-David Dalton
0e881a7972 Simplify _.shuffle and iterator options.
Former-commit-id: 341fd577d65725d47b26172d25b46dec2ac8e67f
2012-10-07 17:43:38 -07:00
John-David Dalton
839e52ba30 Organize docs by category. [closes #84]
Former-commit-id: f4ebda7c32a0ce9c5a86cdb0fd1e689f76557e42
2012-10-07 12:21:01 -07:00
John-David Dalton
8f7d5dcb4d Reduce lodash file size.
Former-commit-id: c6c309cbbc5f93bffb852726e831ba9f90c332a0
2012-10-06 23:39:41 -07:00
John-David Dalton
1104b28bc1 Update README.md to remove fixed Underscore issue.
Former-commit-id: 16fc177c33c2f2522fd9080c0974091ef8e97850
2012-10-06 23:38:25 -07:00
John-David Dalton
48521cb1e4 Update DocDown and Underscore.
Former-commit-id: 7744ef274a9d8b47975dc9f3e3283bd778bc5403
2012-10-06 22:31:08 -07:00
John-David Dalton
17e113dafb Update _.map to return an empty array when falsey values are passed.
Former-commit-id: 2f091fbeb140cbc0b8f3bd2df7a449a06239be0b
2012-10-06 21:17:50 -07:00
John-David Dalton
c33825a904 Reduce Underscore build and update Underscore version number.
Former-commit-id: fd631cd5525fa287c2af493bfe4a93668678977d
2012-10-06 20:58:21 -07:00
John-David Dalton
b07ef98c8f Update Backbone/Underscore vendor folders.
Former-commit-id: 3317d501fe535d91eefab8a5dcb3a88a791e20ac
2012-10-06 20:56:42 -07:00
John-David Dalton
b3d68893df Reduce deep _.clone array iteration and add _.each dependency.
Former-commit-id: 3cb599d294a693974483b892748e6f60186d0c50
2012-10-06 18:15:30 -07:00
John-David Dalton
1329599987 Simplify how deep _.clone handles booleans.
Former-commit-id: adf1d03677336131da2f62bd2fb6e2900c9889a4
2012-10-06 17:32:18 -07:00
John-David Dalton
2adf3f364c Add _.isPlainObject to the list of features in README.md. [ci skip]
Former-commit-id: ec81cdc9e7fef775871cc1c4a497e4d17e7716aa
2012-10-06 15:45:48 -07:00
John-David Dalton
436ee34a02 Simplify createIterator.
Former-commit-id: 0530a9db49488900843c6312cc0d30b1dc641120
2012-10-06 14:43:34 -07:00
John-David Dalton
4a6e17b214 Reduce lodash builds and cleanup README.md.
Former-commit-id: 3c6bbc236a35687c843a8cb27c29f71ed89d0ab0
2012-10-04 23:35:36 -07:00
John-David Dalton
6e9cbccde6 Bump to v0.8.1.
Former-commit-id: 1b63f03d4a7ca0cdc66e44cd987fddecaf88f9ce
2012-10-04 01:40:17 -07:00
John-David Dalton
a0cb8ec124 Cleanup lodash.js.
Former-commit-id: 7a2443719a96b36ae53b2f7d0fe2a1867d650f02
2012-10-04 00:28:45 -07:00
John-David Dalton
21217dfda3 Reduce createIterator.
Former-commit-id: 8c27ca8e4d1f71b2727dd988bc62194510a850dc
2012-10-04 00:02:43 -07:00
John-David Dalton
25ba18e570 Update vendors.
Former-commit-id: 94bb6b8541c223d3ef6eb8aad5fb5925f2d3be48
2012-10-03 23:21:51 -07:00
John-David Dalton
a210377f35 Add unit tests for passing falsey values to _.initial and _.rest.
Former-commit-id: 9d5d4960c175a3dd90af977b605ce309bc6446d3
2012-10-03 20:12:03 -07:00
John-David Dalton
07b9ca457f Cleanup build.js regexes.
Former-commit-id: 0d23053cd8ae20fa2268ba24b15db72c6cd7a85e
2012-10-03 09:09:40 -07:00
John-David Dalton
5f1372d39c Rebuild minified files and docs.
Former-commit-id: d8d8453fa79ab026be0acd44a1af967bdb0bc4cc
2012-10-03 09:09:20 -07:00
John-David Dalton
01b84c79f0 Revert removing falsey guards.
Former-commit-id: b5eeb5d4a0896eb030f20e7e91e54bf101535abc
2012-10-03 09:08:51 -07:00
John-David Dalton
4017443b1e Allow deep clone if requested via include or plus with the underscore build.
Former-commit-id: e86dba41f7265700330e57346a112b578873b390
2012-10-02 21:39:18 -07:00
John-David Dalton
fd2a17d244 Reduce lodash.underscore.min.js.
Former-commit-id: a5032bc542e1166fab6acfd7313c305dd8236d36
2012-10-02 01:43:49 -07:00
John-David Dalton
126804f7c3 Cleanup _.difference, _.intersecton, _.without.
Former-commit-id: 1ca8edb52a1c403fc2d8a8e1b3fd113ced9ff39e
2012-10-02 01:43:30 -07:00
28 changed files with 3883 additions and 3429 deletions

View File

@@ -1,4 +1,4 @@
# Lo-Dash <sup>v0.8.0</sup>
# Lo-Dash <sup>v0.8.2</sup>
[![build status](https://secure.travis-ci.org/bestiejs/lodash.png)](http://travis-ci.org/bestiejs/lodash)
A drop-in replacement<sup>[*](https://github.com/bestiejs/lodash/wiki/Drop-in-Disclaimer)</sup> for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
@@ -7,10 +7,10 @@ Lo-Dashs performance is gained by avoiding slower native methods, instead opt
## Download
* [Development build](https://raw.github.com/bestiejs/lodash/v0.8.0/lodash.js)
* [Production build](https://raw.github.com/bestiejs/lodash/v0.8.0/lodash.min.js)
* [Underscore build](https://raw.github.com/bestiejs/lodash/v0.8.0/lodash.underscore.min.js) tailored for projects already using Underscore
* CDN copies of ≤ [v0.8.0](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.8.0/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
* [Development build](https://raw.github.com/bestiejs/lodash/v0.8.2/lodash.js)
* [Production build](https://raw.github.com/bestiejs/lodash/v0.8.2/lodash.min.js)
* [Underscore build](https://raw.github.com/bestiejs/lodash/v0.8.2/lodash.underscore.min.js) tailored for projects already using Underscore
* CDN copies of ≤ [v0.8.2](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.8.2/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
## Dive in
@@ -38,6 +38,7 @@ For more information check out these screencasts over Lo-Dash:
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an objects own and inherited properties
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an objects own properties
* [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
* [_.lateBind](http://lodash.com/docs#lateBind) for late binding
* [_.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
@@ -48,7 +49,7 @@ For more information check out these screencasts over Lo-Dash:
## Support
Lo-Dash has been tested in at least Chrome 5-22, Firefox 1-15, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.11, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
Lo-Dash has been tested in at least Chrome 5~22, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.11, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
## Custom builds
@@ -161,7 +162,9 @@ Using [npm](http://npmjs.org/):
```bash
npm install lodash
npm install -g lodash
npm link lodash
```
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
@@ -170,6 +173,8 @@ In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
var _ = require('lodash');
```
**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your projects root directory before attempting to `require` it.
In [RingoJS v0.7.0-](http://ringojs.org/):
```js
@@ -197,21 +202,20 @@ require({
## Resolved Underscore.js issues
* Add AMD loader support [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L118-140)]
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L510-516)]
* Ensure *“Collections”* methods allow string `collection` arguments [[#247](https://github.com/documentcloud/underscore/issues/247), [#276](https://github.com/documentcloud/underscore/issues/276), [#561](https://github.com/documentcloud/underscore/pull/561), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L470-487)]
* 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/v0.8.0/test/test.js#L526-546)]
* 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/v0.8.0/test/test.js#L142-148)]
* `_.clone` should allow `deep` cloning [[#595](https://github.com/documentcloud/underscore/pull/595), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L215-224)]
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L267-276)]
* `_.extend` should recursively extend objects [[#379](https://github.com/documentcloud/underscore/pull/379), [#718](https://github.com/documentcloud/underscore/issues/718), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L946-968)]
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L465-468)]
* `_.forEach` should allow exiting iteration early [[#211](https://github.com/documentcloud/underscore/issues/211), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L556-570)]
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L703-708)]
* `_.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/v0.8.0/test/test.js#L763-775)]
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L856-858)]
* `_.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/v0.8.0/test/test.js#L1222-1225)]
* `_.throttle` should work when called in a loop [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L1525-1535)]
* Add AMD loader support [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L118-140)]
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L510-516)]
* Ensure *“Collections”* methods allow string `collection` arguments [[#247](https://github.com/documentcloud/underscore/issues/247), [#276](https://github.com/documentcloud/underscore/issues/276), [#561](https://github.com/documentcloud/underscore/pull/561), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L470-487)]
* 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/v0.8.2/test/test.js#L523-547)]
* 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/v0.8.2/test/test.js#L142-148)]
* `_.clone` should allow `deep` cloning [[#595](https://github.com/documentcloud/underscore/pull/595), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L214-225)]
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L267-276)]
* `_.extend` should recursively extend objects [[#379](https://github.com/documentcloud/underscore/pull/379), [#718](https://github.com/documentcloud/underscore/issues/718), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L968-990)]
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L465-468)]
* `_.forEach` should allow exiting iteration early [[#211](https://github.com/documentcloud/underscore/issues/211), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L553-571)]
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L712-717)]
* `_.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/v0.8.2/test/test.js#L772-784)]
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v0.8.2/test/test.js#L865-867)]
* `_.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/v0.8.2/test/test.js#L1243-1246)]
## Optimized methods <sup>(50+)</sup>
@@ -274,25 +278,13 @@ require({
## Release Notes
### <sup>v0.8.0</sup>
### <sup>v0.8.2</sup>
#### Compatibility Warnings ####
* Made `_.random` return `0` or `1` when no arguments are passed
* Moved late bind functionality from `_.bind` to [_.lateBind](http://lodash.com/docs#lateBind)
* Removed first argument falsey checks from methods
* Removed support for custom `clone`, `isEqual`, `toArray` methods from<br>
`_.clone`, `_.isEqual`, and `_.toArray`
#### Changes ####
* Added `-d`/`--debug`, `-m/--minify`, `minus`, `plus`, `settings`, and `template` build options
* Added `_.isPlainObject` and `_.lateBind`
* Allowed `_.sortedIndex` to accept a property name as the `callback` argument
* Ensured methods accept a `thisArg` of `null`
* Fixed the `iife` build option to accept more values
* Made `_.times` return an array of `callback` results
* Simplified `_.max`, `_.min`, and `_.reduceRight`
* Ensured `_.map` returns an array when passed a falsey collection
* Ensured `_.throttle` clears its timeout when `func` is called
* Made `_.max`, `_.min`, `_.shuffle` support iterating objects
* Reduced `createIterator`, `_.clone`, and `_.compact`
* Re-optimized `_.max`, `_.min`, and `_.sortedIndex`
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).

148
build.js
View File

@@ -67,7 +67,7 @@
'bind': ['isFunction'],
'bindAll': ['bind', 'isFunction'],
'chain': ['mixin'],
'clone': ['extend', 'forOwn', 'isArguments', 'isPlainObject'],
'clone': ['extend', 'forEach', 'forOwn', 'isArguments', 'isPlainObject'],
'compact': [],
'compose': [],
'contains': [],
@@ -118,10 +118,10 @@
'lastIndexOf': [],
'lateBind': ['isFunction'],
'map': ['identity'],
'max': ['identity'],
'max': ['forEach'],
'memoize': [],
'merge': ['isArray', 'isPlainObject'],
'min': ['identity'],
'min': ['forEach'],
'mixin': ['forEach', 'functions'],
'noConflict': [],
'object': [],
@@ -138,7 +138,7 @@
'reject': ['identity'],
'rest': [],
'result': ['isFunction'],
'shuffle': [],
'shuffle': ['forEach'],
'size': ['keys'],
'some': ['identity'],
'sortBy': ['identity'],
@@ -542,7 +542,7 @@
function matchFunction(source, funcName) {
var result = source.match(RegExp(
// match multi-line comment block (could be on a single line)
'\\n +/\\*[^*]*\\*+(?:[^/][^*]*\\*+)*/\\n' +
'(?:\\n +/\\*[^*]*\\*+(?:[^/][^*]*\\*+)*/\\n)?' +
// begin non-capturing group
'(?:' +
// match a function declaration
@@ -684,7 +684,7 @@
// remove `isKeysFast` from `inLoop.object` of `mapIteratorOptions`, `invoke`, `pairs`, `pluck`, and `sortBy`
.replace(/'\s*\+\s*\(isKeysFast[^)]+?\)\s*\+\s*'/g, '.push')
// remove data object property assignment in `createIterator`
.replace(/\s*.+?\.isKeysFast *=.+/, '');
.replace(/ *'isKeysFast':.+\n/, '');
}
/**
@@ -733,16 +733,12 @@
source = source.replace(RegExp('(var ' + varName + ' *=)[\\s\\S]+?(true;\\n)'), '$1$2');
}
source = source.replace(RegExp(
// begin non-capturing group
'(?:' +
// match multi-line comment block
'(?:\\n +/\\*[^*]*\\*+(?:[^/][^*]*\\*+)*/)?\\n' +
// match a variable declaration that's not part of a declaration list
'( +)var ' + varName + ' *= *(?:.+?(?:;|&&\\n[^;]+;)|(?:\\w+\\(|{)[\\s\\S]+?\\n\\1.+?;)\\n|' +
// match a variable in a declaration list
'\\n +' + varName + ' *=.+?,' +
// end non-capturing group
')'
'\\n +' + varName + ' *=.+?,'
), '');
// remove a varaible at the start of a variable declaration list
@@ -799,10 +795,8 @@
.replace(/(?: *\/\/.*\n)*(\s*)' *<% *if *\(useStrict\).+/, value ? "$1'\\'use strict\\';\\n' +" : '')
// remove `useStrict` from iterator options
.replace(/ *'useStrict': *false,\n/g, '')
// remove `useStrict` variable assignment in `createIterator`
.replace(/,\s*useStrict *=[^;]+/, '')
// remove `useStrict` data object property assignment in `createIterator`
.replace(/\s*.+?\.useStrict *=.+/, '');
.replace(/ *'useStrict':.+\n/, '');
}
/*--------------------------------------------------------------------------*/
@@ -954,6 +948,9 @@
// flag used to specify if the build should include the "use strict" directive
var useStrict = isStrict || !(isLegacy || isMobile);
// flag used to specify replacing Lo-Dash's `_.clone` with Underscore's
var useUnderscoreClone = isUnderscore;
/*------------------------------------------------------------------------*/
// names of methods to include in the build
@@ -978,6 +975,11 @@
(result = getDependencies(optionToMethodsArray(source, value)));
});
// use Lo-Dash's clone if explicitly requested
if (result && result.indexOf('clone') > -1) {
useUnderscoreClone = false;
}
// add method names required by Backbone and Underscore builds
if (isBackbone && !result) {
result = getDependencies(backboneDependencies);
@@ -1033,7 +1035,7 @@
}
}
if (isLegacy) {
_.each(['isBindFast', 'isKeysFast', 'isStrictFast', 'nativeBind', 'nativeGetPrototypeOf', 'nativeIsArray', 'nativeKeys'], function(varName) {
_.each(['getPrototypeOf', 'isBindFast', 'isKeysFast', 'isStrictFast', 'nativeBind', 'nativeIsArray', 'nativeKeys'], function(varName) {
source = replaceVar(source, varName, 'false');
});
@@ -1042,7 +1044,6 @@
}
else if (isUnderscore) {
// update dependencies
dependencyMap.clone = ['extend', 'isArray'];
dependencyMap.isEqual = ['isArray', 'isFunction'];
dependencyMap.isEmpty = ['isArray'];
@@ -1050,17 +1051,79 @@
source = removeVar(source, 'arrayLikeClasses');
source = removeVar(source, 'cloneableClasses');
// remove large array optimizations from `cachedContains`
source = source.replace(/( +)function cachedContains[\s\S]+?\n\1}/, [
' function cachedContains(array, fromIndex) {',
' return function(value) {',
' return indexOf(array, value, fromIndex || 0) > -1;',
' };',
// remove large array optimizations
source = removeFunction(source, 'cachedContains');
source = removeVar(source, 'largeArraySize');
// replace `_.clone`
if (useUnderscoreClone) {
dependencyMap.clone = ['extend', 'isArray'];
source = source.replace(/^( +)function clone[\s\S]+?\n\1}/m, [
' function clone(value) {',
' return value && objectTypes[typeof value]',
' ? (isArray(value) ? slice.call(value) : extend({}, value))',
' : value',
' }'
].join('\n'));
}
// replace `_.difference`
source = source.replace(/^( +)function difference[\s\S]+?\n\1}/m, [
' function difference(array) {',
' var index = -1,',
' length = array.length,',
' flattened = concat.apply(ArrayProto, arguments),',
' result = [];',
'',
' while (++index < length) {',
' var value = array[index]',
' if (indexOf(flattened, value, length) < 0) {',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// reduce the number of arguments passed to `cachedContains` from 3 to 2
source = source.replace(/(cachedContains\(\w+, *\w+), *\w+/g, '$1');
// replace `_.intersection`
source = source.replace(/^( +)function intersection[\s\S]+?\n\1}/m, [
' function intersection(array) {',
' var argsLength = arguments.length,',
' index = -1,',
' length = array.length,',
' result = [];',
'',
' array: while (++index < length) {',
' var value = array[index]',
' if (indexOf(result, value) < 0) {',
' for (var argsIndex = 1; argsIndex < argsLength; argsIndex++) {',
' if (indexOf(arguments[argsIndex], value) < 0) {',
' continue array;',
' }',
' }',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// replace `_.without`
source = source.replace(/^( +)function without[\s\S]+?\n\1}/m, [
' function without(array) {',
' var index = -1,',
' length = array.length,',
' result = [];',
'',
' while (++index < length) {',
' var value = array[index]',
' if (indexOf(arguments, value, 1) < 0) {',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// replace `arrayLikeClasses` in `_.isEmpty`
source = source.replace(/'if *\(arrayLikeClasses[\s\S]+?' \|\|\\n/, "'if (isArray(value) || className == stringClass ||");
@@ -1069,19 +1132,10 @@
source = source.replace(/(?: *\/\/.*\n)*( +)var isArr *= *arrayLikeClasses[^}]+}/, '$1var isArr = isArray(a);');
// remove "exit early" feature from `_.each`
source = source.replace(/( )+var baseIteratorOptions *=[\s\S]+?\n\1.+?;/, function(match) {
source = source.replace(/( +)var baseIteratorOptions *=[\s\S]+?\n\1.+?;/, function(match) {
return match.replace(/if *\(callback[^']+/, 'callback(value, index, collection)');
});
// remove `deep` clone functionality
source = source.replace(/( +)function clone[\s\S]+?\n\1}/, [
' function clone(value) {',
' return value && objectTypes[typeof value]',
' ? (isArray(value) ? slice.call(value) : extend({}, value))',
' : value',
' }'
].join('\n'));
// remove unused features from `createBound`
if (buildMethods.indexOf('partial') == -1) {
source = source.replace(matchFunction(source, 'createBound'), function(match) {
@@ -1180,6 +1234,8 @@
source = removeFromCreateIterator(source, 'nativeKeys');
}
/*----------------------------------------------------------------------*/
if (isMobile) {
// inline all functions defined with `createIterator`
_.functions(lodash).forEach(function(methodName) {
@@ -1200,8 +1256,14 @@
});
if (isUnderscore) {
// remove "compiled template cleanup" from `_.template`
source = source.replace(/(?:\s*\/\/.*)*\n *source *=.+?isEvaluating.+?reEmptyStringLeading[\s\S]+?\);/, '');
source = removeVar(source, 'reEmptyStringLeading');
source = removeVar(source, 'reEmptyStringMiddle');
source = removeVar(source, 'reEmptyStringTrailing');
// replace `isArguments` and its fallback
(function() {
// replace `isArguments` and its fallback
var snippet = matchFunction(source, 'isArguments')
.replace(/function isArguments/, 'lodash.isArguments = function');
@@ -1216,10 +1278,13 @@
}
else {
source = removeIsArgumentsFallback(source);
}
// remove `hasDontEnumBug`, `hasObjectSpliceBug`, `iteratesOwnLast`, `noArgsEnum` assignment
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var hasDontEnumBug\b[\s\S]+?}\(1\)\);\n/, '');
// remove `hasDontEnumBug`, `hasObjectSpliceBug`, `iteratesOwnLast`, `noArgsEnum` assignment
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var hasDontEnumBug\b[\s\S]+?}\(1\)\);\n/, '');
// remove `hasObjectSpliceBug` fix from the mutator Array functions mixin
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(hasObjectSpliceBug[\s\S]+?\n\1}/, '');
}
// remove `iteratesOwnLast` from `isPlainObject`
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(iteratesOwnLast[\s\S]+?\n\1}/, '');
@@ -1227,9 +1292,6 @@
// remove JScript [[DontEnum]] fix from `_.isEqual`
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(hasDontEnumBug[\s\S]+?\n\1}/, '');
// remove `hasObjectSpliceBug` fix from the mutator Array functions mixin
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(hasObjectSpliceBug[\s\S]+?\n\1}/, '');
// remove `noArraySliceOnStrings` from `_.toArray`
source = source.replace(/noArraySliceOnStrings *\?[^:]+: *([^)]+)/g, '$1');
@@ -1262,7 +1324,7 @@
.replace(/__p *\+= *' *';/g, '')
.replace(/(__p *\+= *)' *' *\+/g, '$1')
.replace(/(\{) *;|; *(\})/g, '$1$2')
.replace(/\(\(__t *= *\( *([^)]+) *\)\) *== *null *\? *'' *: *__t\)/g, '$1');
.replace(/\(\(__t *= *\( *([^)]+) *\)\) *== *null *\? *'' *: *__t\)/g, '($1)');
// remove the with-statement
snippet = snippet.replace(/ *with *\(.+?\) *{/, '\n').replace(/}([^}]*}[^}]*$)/, '$1');
@@ -1366,7 +1428,7 @@
source = removeVar(source, 'nativeIsArray');
}
if (isRemoved(source, 'isPlainObject')) {
source = removeVar(source, 'nativeGetPrototypeOf');
source = removeVar(source, 'getPrototypeOf');
}
if (isRemoved(source, 'keys')) {
source = removeFunction(source, 'shimKeys');

View File

@@ -10,7 +10,7 @@
'lodash':
'/*!\n' +
' Lo-Dash @VERSION lodash.com/license\n' +
' Underscore.js 1.4.0 underscorejs.org/LICENSE\n' +
' Underscore.js 1.4.2 underscorejs.org/LICENSE\n' +
'*/',
'underscore':
'/*! Underscore.js @VERSION underscorejs.org/LICENSE */'

View File

@@ -15,7 +15,6 @@
'createCallback',
'ctor',
'hasOwnProperty',
'identity',
'index',
'iteratee',
'length',

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,10 @@
// generate Markdown
$markdown = docdown(array(
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.8.0</sup>',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.8.2</sup>',
'toc' => 'categories',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
));
// save to a .md file

517
lodash.js
View File

@@ -1,7 +1,7 @@
/*!
* Lo-Dash v0.8.0 <http://lodash.com>
* Lo-Dash v0.8.2 <http://lodash.com>
* (c) 2012 John-David Dalton <http://allyoucanleet.com/>
* Based on Underscore.js 1.4.0 <http://underscorejs.org>
* Based on Underscore.js 1.4.2 <http://underscorejs.org>
* (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
* Available under MIT license <http://lodash.com/license>
*/
@@ -71,7 +71,10 @@
var templateCounter = 0;
/** Native method shortcuts */
var concat = ArrayProto.concat,
var ceil = Math.ceil,
concat = ArrayProto.concat,
floor = Math.floor,
getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
hasOwnProperty = ObjectProto.hasOwnProperty,
push = ArrayProto.push,
propertyIsEnumerable = ObjectProto.propertyIsEnumerable,
@@ -80,8 +83,6 @@
/* Native method shortcuts for methods with the same name as other `lodash` methods */
var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
nativeFloor = Math.floor,
nativeGetPrototypeOf = reNative.test(nativeGetPrototypeOf = Object.getPrototypeOf) && nativeGetPrototypeOf,
nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
nativeIsFinite = window.isFinite,
nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
@@ -235,6 +236,7 @@
*
* @name _
* @constructor
* @category Chaining
* @param {Mixed} value The value to wrap in a `lodash` instance.
* @returns {Object} Returns a `lodash` instance.
*/
@@ -314,7 +316,9 @@
// the `iteratee` may be reassigned by the `top` snippet
'var index, value, iteratee = <%= firstArg %>, ' +
// assign the `result` variable an initial value
'result<% if (init) { %> = <%= init %><% } %>;\n' +
'result = <%= init || firstArg %>;\n' +
// exit early if the first argument is falsey
'if (!<%= firstArg %>) return result;\n' +
// add code before the iteration branches
'<%= top %>;\n' +
@@ -427,7 +431,6 @@
*/
var baseIteratorOptions = {
'args': 'collection, callback, thisArg',
'init': 'collection',
'top': 'callback = createCallback(callback, thisArg)',
'inLoop': 'if (callback(value, index, collection) === false) return result'
};
@@ -452,7 +455,6 @@
'useHas': false,
'useStrict': false,
'args': 'object',
'init': 'object',
'top':
'for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {\n' +
' if (iteratee = arguments[argsIndex]) {',
@@ -480,7 +482,7 @@
/** Reusable iterator options for `invoke`, `map`, `pluck`, and `sortBy` */
var mapIteratorOptions = {
'init': '',
'init': 'collection || []',
'beforeLoop': {
'array': 'result = Array(length)',
'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]')
@@ -529,13 +531,11 @@
if (isLarge) {
// init value cache
var key,
index = fromIndex - 1;
var index = fromIndex - 1;
while (++index < length) {
// manually coerce `value` to string because `hasOwnProperty`, in some
// older versions of Firefox, coerces objects incorrectly
key = array[index] + '';
var key = array[index] + '';
(hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
}
}
@@ -664,14 +664,11 @@
* @private
* @param {Object} [options1, options2, ...] The compile options objects.
*
* useHas - A boolean to specify whether or not to use `hasOwnProperty` checks
* in the object loop.
* useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
*
* useStrict - A boolean to specify whether or not to include the ES5
* "use strict" directive.
* useStrict - A boolean to specify including the "use strict" directive.
*
* args - A string of comma separated arguments the iteration function will
* accept.
* args - A string of comma separated arguments the iteration function will accept.
*
* init - A string to specify the initial value of the `result` variable.
*
@@ -689,61 +686,49 @@
* @returns {Function} Returns the compiled function.
*/
function createIterator() {
var object,
prop,
value,
index = -1,
length = arguments.length;
// merge options into a template data object
var data = {
'bottom': '',
'hasDontEnumBug': hasDontEnumBug,
'init': '',
'isKeysFast': isKeysFast,
'noArgsEnum': noArgsEnum,
'noCharByIndex': noCharByIndex,
'shadowed': shadowed,
'top': '',
'useHas': true,
'useStrict': isStrictFast,
'arrayBranch': { 'beforeLoop': '' },
'objectBranch': { 'beforeLoop': '' }
};
while (++index < length) {
object = arguments[index];
for (prop in object) {
value = (value = object[prop]) == null ? '' : value;
var object,
index = -1;
// merge options into a template data object
while (object = arguments[++index]) {
for (var prop in object) {
var value = object[prop];
// keep this regexp explicit for the build pre-process
if (/beforeLoop|inLoop/.test(prop)) {
if (typeof value == 'string') {
value = { 'array': value, 'object': value };
}
data.arrayBranch[prop] = value.array || '';
data.objectBranch[prop] = value.object || '';
data.arrayBranch[prop] = value.array;
data.objectBranch[prop] = value.object;
} else {
data[prop] = value;
}
}
}
// set additional template `data` values
var args = data.args,
firstArg = /^[^,]+/.exec(args)[0],
init = data.init,
useStrict = data.useStrict;
data.firstArg = firstArg;
data.hasDontEnumBug = hasDontEnumBug;
data.init = init == null ? firstArg : init;
data.isKeysFast = isKeysFast;
data.noArgsEnum = noArgsEnum;
data.shadowed = shadowed;
data.useHas = data.useHas !== false;
data.useStrict = useStrict == null ? isStrictFast : useStrict;
if (data.noCharByIndex == null) {
data.noCharByIndex = noCharByIndex;
}
if (firstArg != 'collection' || !data.arrayBranch.inLoop) {
// set additional template `data` properties
var args = data.args;
if ((data.firstArg = /^[^,]+/.exec(args)[0]) != 'collection' || !data.arrayBranch.inLoop) {
data.arrayBranch = null;
}
// create the function factory
var factory = Function(
'arrayLikeClasses, ArrayProto, bind, compareAscending, concat, createCallback, ' +
'forIn, hasOwnProperty, identity, indexOf, isArguments, isArray, isFunction, ' +
'forIn, hasOwnProperty, indexOf, isArguments, isArray, isFunction, ' +
'isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' +
'slice, stringClass, toString, undefined',
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
@@ -752,7 +737,7 @@
// return the compiled function
return factory(
arrayLikeClasses, ArrayProto, bind, compareAscending, concat, createCallback,
forIn, hasOwnProperty, identity, indexOf, isArguments, isArray, isFunction,
forIn, hasOwnProperty, indexOf, isArguments, isArray, isFunction,
isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable,
slice, stringClass, toString
);
@@ -844,7 +829,7 @@
// fallback for browsers that can't detect `arguments` objects by [[Class]]
if (noArgsClass) {
isArguments = function(value) {
return !!(value && hasOwnProperty.call(value, 'callee'));
return value ? hasOwnProperty.call(value, 'callee') : false;
};
}
@@ -915,15 +900,15 @@
* _.isPlainObject({ 'name': 'moe', 'age': 40 });
* // => true
*/
var isPlainObject = !nativeGetPrototypeOf ? isPlainFallback : function(value) {
var isPlainObject = !getPrototypeOf ? isPlainFallback : function(value) {
if (!(value && typeof value == 'object')) {
return false;
}
var valueOf = value.valueOf,
objProto = typeof valueOf == 'function' && (objProto = nativeGetPrototypeOf(valueOf)) && nativeGetPrototypeOf(objProto);
objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
return objProto
? value == objProto || (nativeGetPrototypeOf(value) == objProto && !isArguments(value))
? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value))
: isPlainFallback(value);
};
@@ -981,7 +966,6 @@
var shimKeys = createIterator({
'args': 'object',
'init': '[]',
'top': 'if (!(object && objectTypes[typeof object])) throw TypeError()',
'inLoop': 'result.push(index)'
});
@@ -1071,8 +1055,6 @@
var ctor = value.constructor;
switch (className) {
case boolClass:
return new ctor(value == true);
case dateClass:
return new ctor(+value);
@@ -1083,7 +1065,6 @@
case regexpClass:
return ctor(value.source, reFlags.exec(value));
}
// check for circular references and return corresponding clone
stackA || (stackA = []);
stackB || (stackB = []);
@@ -1094,9 +1075,8 @@
return stackB[length];
}
}
// init cloned object
var result = isArr ? ctor(length = value.length) : {};
var result = isArr ? ctor(value.length) : {};
// add the source value to the stack of traversed objects
// and associate it with its clone
@@ -1104,16 +1084,10 @@
stackB.push(result);
// recursively populate clone (susceptible to call stack limits)
if (isArr) {
var index = -1;
while (++index < length) {
result[index] = clone(value[index], deep, null, stackA, stackB);
}
} else {
forOwn(value, function(objValue, key) {
result[key] = clone(objValue, deep, null, stackA, stackB);
});
}
(isArr ? forEach : forOwn)(value, function(objValue, key) {
result[key] = clone(objValue, deep, null, stackA, stackB);
});
return result;
}
@@ -1230,7 +1204,7 @@
'useHas': false,
'args': 'object',
'init': '[]',
'inLoop': 'if (isFunction(value)) result.push(index)',
'inLoop': 'isFunction(value) && result.push(index)',
'bottom': 'result.sort()'
});
@@ -1250,7 +1224,7 @@
* // => true
*/
function has(object, property) {
return hasOwnProperty.call(object, property);
return object ? hasOwnProperty.call(object, property) : false;
}
/**
@@ -1329,7 +1303,6 @@
'args': 'value',
'init': 'true',
'top':
'if (!value) return result;\n' +
'var className = toString.call(value),\n' +
' length = value.length;\n' +
'if (arrayLikeClasses[className]' +
@@ -1690,10 +1663,15 @@
* // => ['one', 'two', 'three'] (order is not guaranteed)
*/
var keys = !nativeKeys ? shimKeys : function(object) {
var type = typeof object;
// avoid iterating over the `prototype` property
return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype')
? shimKeys(object)
: nativeKeys(object);
if (type == 'function' && propertyIsEnumerable.call(object, 'prototype')) {
return shimKeys(object);
}
return object && objectTypes[type]
? nativeKeys(object)
: [];
};
/**
@@ -1748,7 +1726,7 @@
' result[index] = stackB[stackLength]\n' +
' } else {\n' +
' stackA.push(source);\n' +
' stackB.push(value = (value = result[index]) && isArr\n' +
' stackB.push(value = (value = result[index], isArr)\n' +
' ? (isArray(value) ? value : [])\n' +
' : (isPlainObject(value) ? value : {})\n' +
' );\n' +
@@ -1834,11 +1812,11 @@
var pick = createIterator(omitIteratorOptions, {
'top':
'if (typeof callback != \'function\') {\n' +
' var prop,\n' +
' var index = 0,\n' +
' props = concat.apply(ArrayProto, arguments),\n' +
' length = props.length;\n' +
' for (index = 1; index < length; index++) {\n' +
' prop = props[index];\n' +
' while (++index < length) {\n' +
' var prop = props[index];\n' +
' if (prop in object) result[prop] = object[prop]\n' +
' }\n' +
'} else {\n' +
@@ -1991,7 +1969,7 @@
* // => 2
*/
var find = createIterator(baseIteratorOptions, forEachIteratorOptions, {
'init': '',
'init': 'undefined',
'inLoop': 'if (callback(value, index, collection)) return value'
});
@@ -2110,6 +2088,98 @@
*/
var map = createIterator(baseIteratorOptions, mapIteratorOptions);
/**
* Retrieves the maximum value of an `array`. If `callback` is passed,
* it will be executed for each value in the `array` to generate the
* criterion by which the value is ranked. The `callback` is bound to
* `thisArg` and invoked with three arguments; (value, index, collection).
*
* @static
* @memberOf _
* @category Collections
* @param {Array} collection The collection to iterate over.
* @param {Function} [callback] The function called per iteration.
* @param {Mixed} [thisArg] The `this` binding of `callback`.
* @returns {Mixed} Returns the maximum value.
* @example
*
* var stooges = [
* { 'name': 'moe', 'age': 40 },
* { 'name': 'larry', 'age': 50 },
* { 'name': 'curly', 'age': 60 }
* ];
*
* _.max(stooges, function(stooge) { return stooge.age; });
* // => { 'name': 'curly', 'age': 60 };
*/
function max(collection, callback, thisArg) {
var computed = -Infinity,
index = -1,
length = collection ? collection.length : 0,
result = computed;
if (callback || length !== +length) {
callback = createCallback(callback, thisArg);
forEach(collection, function(value, index, collection) {
var current = callback(value, index, collection);
if (current > computed) {
computed = current;
result = value;
}
});
} else {
while (++index < length) {
if (collection[index] > result) {
result = collection[index];
}
}
}
return result;
}
/**
* Retrieves the minimum value of an `array`. If `callback` is passed,
* it will be executed for each value in the `array` to generate the
* criterion by which the value is ranked. The `callback` is bound to `thisArg`
* and invoked with three arguments; (value, index, collection).
*
* @static
* @memberOf _
* @category Collections
* @param {Array} collection The collection to iterate over.
* @param {Function} [callback] The function called per iteration.
* @param {Mixed} [thisArg] The `this` binding of `callback`.
* @returns {Mixed} Returns the minimum value.
* @example
*
* _.min([10, 5, 100, 2, 1000]);
* // => 2
*/
function min(collection, callback, thisArg) {
var computed = Infinity,
index = -1,
length = collection ? collection.length : 0,
result = computed;
if (callback || length !== +length) {
callback = createCallback(callback, thisArg);
forEach(collection, function(value, index, collection) {
var current = callback(value, index, collection);
if (current < computed) {
computed = current;
result = value;
}
});
} else {
while (++index < length) {
if (collection[index] < result) {
result = collection[index];
}
}
}
return result;
}
/**
* Retrieves the value of a specified property from all elements in
* the `collection`.
@@ -2198,7 +2268,7 @@
*/
function reduceRight(collection, callback, accumulator, thisArg) {
var iteratee = collection,
length = collection.length,
length = collection ? collection.length : 0,
noaccum = arguments.length < 3;
if (length !== +length) {
@@ -2237,6 +2307,32 @@
'inLoop': '!' + filterIteratorOptions.inLoop
});
/**
* Creates an array of shuffled `array` values, using a version of the
* Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
*
* @static
* @memberOf _
* @category Collections
* @param {Array} collection The collection to shuffle.
* @returns {Array} Returns a new shuffled collection.
* @example
*
* _.shuffle([1, 2, 3, 4, 5, 6]);
* // => [4, 1, 6, 3, 5, 2]
*/
function shuffle(collection) {
var index = -1,
result = Array(collection ? collection.length : 0);
forEach(collection, function(value) {
var rand = floor(nativeRandom() * (++index + 1));
result[index] = result[rand];
result[rand] = value;
});
return result;
}
/**
* Gets the size of the `collection` by returning `collection.length` for arrays
* and array-like objects or the number of own enumerable properties for objects.
@@ -2349,7 +2445,10 @@
* // => [2, 3, 4]
*/
function toArray(collection) {
var length = collection ? collection.length : 0;
if (!collection) {
return [];
}
var length = collection.length;
if (length === +length) {
return (noArraySliceOnStrings ? toString.call(collection) == stringClass : typeof collection == 'string')
? collection.split('')
@@ -2386,8 +2485,8 @@
'forIn(properties, function(value, prop) { props.push(prop) });\n' +
'var propsLength = props.length',
'inLoop':
'for (var prop, pass = true, propIndex = 0; propIndex < propsLength; propIndex++) {\n' +
' prop = props[propIndex];\n' +
'for (var pass = true, propIndex = 0; propIndex < propsLength; propIndex++) {\n' +
' var prop = props[propIndex];\n' +
' if (!(pass = value[prop] === properties[prop])) break\n' +
'}\n' +
'pass && result.push(value)'
@@ -2411,12 +2510,13 @@
*/
function compact(array) {
var index = -1,
length = array.length,
length = array ? array.length : 0,
result = [];
while (++index < length) {
if (array[index]) {
result.push(array[index]);
var value = array[index];
if (value) {
result.push(value);
}
}
return result;
@@ -2439,15 +2539,19 @@
* // => [1, 3, 4]
*/
function difference(array) {
var result = [];
if (!array) {
return result;
}
var index = -1,
length = array.length,
flattened = concat.apply(ArrayProto, arguments),
contains = cachedContains(flattened, length),
result = [];
contains = cachedContains(flattened, length);
while (++index < length) {
if (!contains(array[index])) {
result.push(array[index]);
var value = array[index];
if (!contains(value)) {
result.push(value);
}
}
return result;
@@ -2473,7 +2577,9 @@
* // => 5
*/
function first(array, n, guard) {
return (n == null || guard) ? array[0] : slice.call(array, 0, n);
if (array) {
return (n == null || guard) ? array[0] : slice.call(array, 0, n);
}
}
/**
@@ -2495,13 +2601,12 @@
* // => [1, 2, 3, [[4]]];
*/
function flatten(array, shallow) {
var value,
index = -1,
length = array.length,
var index = -1,
length = array ? array.length : 0,
result = [];
while (++index < length) {
value = array[index];
var value = array[index];
// recursively flatten arrays (susceptible to call stack limits)
if (isArray(value)) {
@@ -2516,7 +2621,7 @@
/**
* Gets the index at which the first occurrence of `value` is found using
* strict equality for comparisons, i.e. `===`. If the `array` is already
* sorted, passing `true` for `isSorted` will run a faster binary search.
* sorted, passing `true` for `fromIndex` will run a faster binary search.
*
* @static
* @memberOf _
@@ -2539,15 +2644,13 @@
*/
function indexOf(array, value, fromIndex) {
var index = -1,
length = array.length;
length = array ? array.length : 0;
if (fromIndex) {
if (typeof fromIndex == 'number') {
index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) - 1;
} else {
index = sortedIndex(array, value);
return array[index] === value ? index : -1;
}
if (typeof fromIndex == 'number') {
index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
} else if (fromIndex) {
index = sortedIndex(array, value);
return array[index] === value ? index : -1;
}
while (++index < length) {
if (array[index] === value) {
@@ -2575,7 +2678,9 @@
* // => [3, 2]
*/
function initial(array, n, guard) {
return slice.call(array, 0, -((n == null || guard) ? 1 : n));
return array
? slice.call(array, 0, -((n == null || guard) ? 1 : n))
: [];
}
/**
@@ -2594,15 +2699,14 @@
* // => [1, 2]
*/
function intersection(array) {
var value,
argsLength = arguments.length,
var argsLength = arguments.length,
cache = [],
index = -1,
length = array.length,
length = array ? array.length : 0,
result = [];
array: while (++index < length) {
value = array[index];
var value = array[index];
if (indexOf(result, value) < 0) {
for (var argsIndex = 1; argsIndex < argsLength; argsIndex++) {
if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(arguments[argsIndex])))(value)) {
@@ -2634,8 +2738,10 @@
* // => 1
*/
function last(array, n, guard) {
var length = array.length;
return (n == null || guard) ? array[length - 1] : slice.call(array, -n || length);
if (array) {
var length = array.length;
return (n == null || guard) ? array[length - 1] : slice.call(array, -n || length);
}
}
/**
@@ -2658,8 +2764,8 @@
* // => 1
*/
function lastIndexOf(array, value, fromIndex) {
var index = array.length;
if (fromIndex && typeof fromIndex == 'number') {
var index = array ? array.length : 0;
if (typeof fromIndex == 'number') {
index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
}
while (index--) {
@@ -2670,84 +2776,6 @@
return -1;
}
/**
* Retrieves the maximum value of an `array`. If `callback` is passed,
* it will be executed for each value in the `array` to generate the
* criterion by which the value is ranked. The `callback` is bound to
* `thisArg` and invoked with three arguments; (value, index, array).
*
* @static
* @memberOf _
* @category Arrays
* @param {Array} array The array to iterate over.
* @param {Function} [callback] The function called per iteration.
* @param {Mixed} [thisArg] The `this` binding of `callback`.
* @returns {Mixed} Returns the maximum value.
* @example
*
* var stooges = [
* { 'name': 'moe', 'age': 40 },
* { 'name': 'larry', 'age': 50 },
* { 'name': 'curly', 'age': 60 }
* ];
*
* _.max(stooges, function(stooge) { return stooge.age; });
* // => { 'name': 'curly', 'age': 60 };
*/
function max(array, callback, thisArg) {
var current,
computed = -Infinity,
index = -1,
length = array ? array.length : 0,
result = computed;
callback = createCallback(callback, thisArg);
while (++index < length) {
current = callback(array[index], index, array);
if (current > computed) {
computed = current;
result = array[index];
}
}
return result;
}
/**
* Retrieves the minimum value of an `array`. If `callback` is passed,
* it will be executed for each value in the `array` to generate the
* criterion by which the value is ranked. The `callback` is bound to `thisArg`
* and invoked with three arguments; (value, index, array).
*
* @static
* @memberOf _
* @category Arrays
* @param {Array} array The array to iterate over.
* @param {Function} [callback] The function called per iteration.
* @param {Mixed} [thisArg] The `this` binding of `callback`.
* @returns {Mixed} Returns the minimum value.
* @example
*
* _.min([10, 5, 100, 2, 1000]);
* // => 2
*/
function min(array, callback, thisArg) {
var current,
computed = Infinity,
index = -1,
length = array ? array.length : 0,
result = computed;
callback = createCallback(callback, thisArg);
while (++index < length) {
current = callback(array[index], index, array);
if (current < computed) {
computed = current;
result = array[index];
}
}
return result;
}
/**
* Creates an object composed from arrays of `keys` and `values`. Pass either
* a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
@@ -2767,14 +2795,15 @@
*/
function object(keys, values) {
var index = -1,
length = keys.length,
length = keys ? keys.length : 0,
result = {};
while (++index < length) {
var key = keys[index];
if (values) {
result[keys[index]] = values[index];
result[key] = values[index];
} else {
result[keys[index][0]] = keys[index][1];
result[key[0]] = key[1];
}
}
return result;
@@ -2820,7 +2849,7 @@
// use `Array(length)` so V8 will avoid the slower "dictionary" mode
// http://www.youtube.com/watch?v=XAqIpGU8ZZk#t=16m27s
var index = -1,
length = nativeMax(0, Math.ceil((end - start) / step)),
length = nativeMax(0, ceil((end - start) / step)),
result = Array(length);
while (++index < length) {
@@ -2849,35 +2878,9 @@
* // => [2, 1]
*/
function rest(array, n, guard) {
return slice.call(array, (n == null || guard) ? 1 : n);
}
/**
* Creates an array of shuffled `array` values, using a version of the
* Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
*
* @static
* @memberOf _
* @category Arrays
* @param {Array} array The array to shuffle.
* @returns {Array} Returns a new shuffled array.
* @example
*
* _.shuffle([1, 2, 3, 4, 5, 6]);
* // => [4, 1, 6, 3, 5, 2]
*/
function shuffle(array) {
var rand,
index = -1,
length = array.length,
result = Array(length);
while (++index < length) {
rand = nativeFloor(nativeRandom() * (index + 1));
result[index] = result[rand];
result[rand] = array[index];
}
return result;
return array
? slice.call(array, (n == null || guard) ? 1 : n)
: [];
}
/**
@@ -2921,15 +2924,21 @@
* // => 2
*/
function sortedIndex(array, value, callback, thisArg) {
var mid,
low = 0,
high = array.length;
var low = 0,
high = array ? array.length : low;
callback = createCallback(callback, thisArg);
value = callback(value);
while (low < high) {
mid = (low + high) >>> 1;
callback(array[mid]) < value ? low = mid + 1 : high = mid;
if (callback) {
callback = createCallback(callback, thisArg);
value = callback(value);
while (low < high) {
var mid = (low + high) >>> 1;
callback(array[mid]) < value ? low = mid + 1 : high = mid;
}
} else {
while (low < high) {
var mid = (low + high) >>> 1;
array[mid] < value ? low = mid + 1 : high = mid;
}
}
return low;
}
@@ -2956,8 +2965,9 @@
result = [];
while (++index < length) {
if (indexOf(result, flattened[index]) < 0) {
result.push(flattened[index]);
var value = flattened[index];
if (indexOf(result, value) < 0) {
result.push(value);
}
}
return result;
@@ -2994,9 +3004,8 @@
* // => [1, 2, 3]
*/
function uniq(array, isSorted, callback, thisArg) {
var computed,
index = -1,
length = array.length,
var index = -1,
length = array ? array.length : 0,
result = [],
seen = [];
@@ -3008,7 +3017,7 @@
}
callback = createCallback(callback, thisArg);
while (++index < length) {
computed = callback(array[index], index, array);
var computed = callback(array[index], index, array);
if (isSorted
? !index || seen[seen.length - 1] !== computed
: indexOf(seen, computed) < 0
@@ -3037,13 +3046,14 @@
*/
function without(array) {
var index = -1,
length = array.length,
length = array ? array.length : 0,
contains = cachedContains(arguments, 1, 20),
result = [];
while (++index < length) {
if (!contains(array[index])) {
result.push(array[index]);
var value = array[index];
if (!contains(value)) {
result.push(value);
}
}
return result;
@@ -3067,7 +3077,7 @@
*/
function zip(array) {
var index = -1,
length = max(pluck(arguments, 'length')),
length = array ? max(pluck(arguments, 'length')) : 0,
result = Array(length);
while (++index < length) {
@@ -3166,17 +3176,16 @@
'args': 'object',
'top':
'var funcs = arguments,\n' +
' index = 0,\n' +
' length = funcs.length;\n' +
'if (length > 1) {\n' +
' for (var index = 1; index < length; index++) {\n' +
' while (++index < length) {\n' +
' result[funcs[index]] = bind(result[funcs[index]], result)\n' +
' }\n' +
' return result\n' +
'}',
'inLoop':
'if (isFunction(result[index])) {\n' +
' result[index] = bind(result[index], result)\n' +
'}'
'if (isFunction(value)) result[index] = bind(value, result)'
});
/**
@@ -3459,6 +3468,7 @@
thisArg = this;
if (remain <= 0) {
clearTimeout(timeoutId);
lastCalled = now;
result = func.apply(thisArg, args);
}
@@ -3624,7 +3634,7 @@
max = min;
min = 0;
}
return min + nativeFloor(nativeRandom() * ((+max || 0) - min + 1));
return min + floor(nativeRandom() * ((+max || 0) - min + 1));
}
/**
@@ -3729,6 +3739,7 @@
// http://ejohn.org/blog/javascript-micro-templating/
// and Laura Doktorova's doT.js
// https://github.com/olado/doT
text || (text = '');
options || (options = {});
var isEvaluating,
@@ -3990,7 +4001,7 @@
* @memberOf _
* @type String
*/
lodash.VERSION = '0.8.0';
lodash.VERSION = '0.8.2';
// assign static methods
lodash.after = after;

74
lodash.min.js vendored
View File

@@ -1,39 +1,39 @@
/*!
Lo-Dash 0.8.0 lodash.com/license
Underscore.js 1.4.0 underscorejs.org/LICENSE
Lo-Dash 0.8.2 lodash.com/license
Underscore.js 1.4.2 underscorejs.org/LICENSE
*/
;(function(e,t){function s(e){if(e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||H),s=i?{}:e;if(i)for(var o=t-1;++o<r;)n=e[o]+"",(Q.call(s,n)?s[n]:s[n]=[]).push(e[o]);return function(e){if(i){var n=e+"";return Q.call(s,n)&&-1<x(s[n],e)}return-1<x(s,e,t)}}function u(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function a(e,t,n){function r(){var u=arguments
,a=s?this:t;return i||(e=t[o]),n.length&&(u=u.length?n.concat(Z.call(u)):n),this instanceof r?(p.prototype=e.prototype,a=new p,(u=e.apply(a,u))&&Pt[typeof u]?u:a):e.apply(a,u)}var i=m(e),s=!n,o=e;return s&&(n=t),r}function f(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:A}function l(){for(var e,t,n,s=-1,o=arguments.length,a={e:"",p:"",c:{d:""},l:{d:""}};++s<o;)for(t in e=arguments[s],e)n=(n=e[t])==r?"":n,/d|h/.test(t)?("string"==typeof
n&&(n={b:n,k:n}),a.c[t]=n.b||"",a.l[t]=n.k||""):a[t]=n;e=a.a,t=/^[^,]+/.exec(e)[0],n=a.i,s=a.r,a.f=t,a.g=wt,a.i=n==r?t:n,a.j=Ot,a.m=xt,a.o=J,a.q=a.q!==i,a.r=s==r?Mt:s,a.n==r&&(a.n=Ct);if("d"!=t||!a.c.h)a.c=r;t="",a.r&&(t+="'use strict';"),t+="var j,B,k="+a.f+",u",a.i&&(t+="="+a.i),t+=";"+a.p+";",a.c&&(t+="var l=k.length;j=-1;",a.l&&(t+="if(l===+l){"),a.n&&(t+="if(z.call(k)==x){k=k.split('')}"),t+=a.c.d+";while(++j<l){B=k[j];"+a.c.h+"}",a.l&&(t+="}"));if(a.l){a.c?t+="else {":a.m&&(t+="var l=k.length;j=-1;if(l&&P(k)){while(++j<l){B=k[j+=''];"+
a.l.h+"}}else {"),a.g||(t+="var v=typeof k=='function'&&r.call(k,'prototype');");if(a.j&&a.q)t+="var o=-1,p=Z[typeof k]?m(k):[],l=p.length;"+a.l.d+";while(++o<l){j=p[o];",a.g||(t+="if(!(v&&j=='prototype')){"),t+="B=k[j];"+a.l.h+"",a.g||(t+="}");else{t+=a.l.d+";for(j in k){";if(!a.g||a.q)t+="if(",a.g||(t+="!(v&&j=='prototype')"),!a.g&&a.q&&(t+="&&"),a.q&&(t+="h.call(k,j)"),t+="){";t+="B=k[j];"+a.l.h+";";if(!a.g||a.q)t+="}"}t+="}";if(a.g){t+="var g=k.constructor;";for(n=0;7>n;n++)t+="j='"+a.o[n]+"';if("
,"constructor"==a.o[n]&&(t+="!(g&&g.prototype===k)&&"),t+="h.call(k,j)){B=k[j];"+a.l.h+"}"}if(a.c||a.m)t+="}"}return t+=a.e+";return u",Function("E,F,G,J,e,f,K,h,i,N,P,R,T,U,Y,Z,m,r,w,x,z,A","var H=function("+e+"){"+t+"};return H")(_t,_,L,u,K,f,Zt,Q,A,x,v,Vt,m,$t,vt,Pt,ot,Y,Z,gt,et)}function c(e){return"\\"+Ht[e]}function h(e){return Kt[e]}function p(){}function d(e){return Qt[e]}function v(e){return et.call(e)==lt}function m(e){return"function"==typeof e}function g(e){var t=i;if(!e||"object"!=typeof
e||v(e))return t;var n=e.constructor;return(!kt||"function"==typeof e.toString||"string"!=typeof (e+""))&&(!m(n)||n instanceof n)?St?(Zt(e,function(e,n,r){return t=!Q.call(r,n),i}),t===i):(Zt(e,function(e,n){t=n}),t===i||Q.call(e,t)):t}function y(e,t,s,o,u){if(e==r)return e;s&&(t=i);if(s=Pt[typeof e]){var a=et.call(e);if(!Dt[a]||Tt&&v(e))return e;var f=a==ct,s=f||(a==vt?$t(e):s)}if(!s||!t)return s?f?Z.call(e):Yt({},e):e;s=e.constructor;switch(a){case ht:return new s(e==n);case pt:return new s(+e)
;case dt:case gt:return new s(e);case mt:return s(e.source,U.exec(e))}o||(o=[]),u||(u=[]);for(a=o.length;a--;)if(o[a]==e)return u[a];var l=f?s(a=e.length):{};o.push(e),u.push(l);if(f)for(f=-1;++f<a;)l[f]=y(e[f],t,r,o,u);else en(e,function(e,n){l[n]=y(e,t,r,o,u)});return l}function b(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Pt[typeof e]||Pt[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=et.call(e);if(u!=et.call(t))return i;switch(u){case ht:case pt:return+e==+t
;case dt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case mt:case gt:return e==t+""}var a=_t[u];if(Tt&&!a&&(a=v(e))&&!v(t)||!a&&(u!=vt||kt&&("function"!=typeof e.toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=b(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!m(a)||!(a instanceof
a&&m(f)&&f instanceof f)))return i;for(var c in e)if(Q.call(e,c)&&(l++,!Q.call(t,c)||!b(e[c],t[c],s,o)))return i;for(c in t)if(Q.call(t,c)&&!(l--))return i;if(wt)for(;7>++u;)if(c=J[u],Q.call(e,c)&&(!Q.call(t,c)||!b(e[c],t[c],s,o)))return i;return n}function w(e,t,n,r){var s=e,o=e.length,u=3>arguments.length;if(o!==+o)var a=rn(e),o=a.length;else Ct&&et.call(e)==gt&&(s=e.split(""));return vn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function E(e,t,n){return t==r||n?e[0
]:Z.call(e,0,t)}function S(e,t){for(var n,r=-1,i=e.length,s=[];++r<i;)n=e[r],Vt(n)?G.apply(s,t?n:S(n)):s.push(n);return s}function x(e,t,n){var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=C(e,t),e[r]===t?r:-1;r=(0>n?ut(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function T(e,t,n){for(var r=-Infinity,i=-1,s=e?e.length:0,o=r,t=f(t,n);++i<s;)n=t(e[i],i,e),n>r&&(r=n,o=e[i]);return o}function N(e,t,n){return Z.call(e,t==r||n?1:t)}function C(e,t,n,r){for(var i=0,s=e.length,n=f(n,r),t=
n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function k(e,t,n,r){var s=-1,o=e.length,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=f(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>x(a,r))a.push(r),u.push(e[s]);return u}function L(e,t){return At||tt&&2<arguments.length?tt.call.apply(tt,arguments):a(e,t,Z.call(arguments,2))}function A(e){return e}function O(e){vn(tn(e),function(t){var r=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&G.apply(e
,arguments),e=r.apply(s,e),this.__chain__&&(e=new s(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,M="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),_=Array.prototype,D=Object.prototype,P=0,H=30,B=e._,j=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,F=/&(?:amp|lt|gt|quot|#x27);/g,I=/\b__p\+='';/g,q=/\b(__p\+=)''\+/g,R=/(__e\(.*?\)|\b__t\))\+'';/g,U=/\w*$/,z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,W=RegExp("^"+(D
.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),X=/($^)/,V=/[&<>"']/g,$=/['\n\r\t\u2028\u2029\\]/g,J="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),K=_.concat,Q=D.hasOwnProperty,G=_.push,Y=D.propertyIsEnumerable,Z=_.slice,et=D.toString,tt=W.test(tt=Z.bind)&&tt,nt=Math.floor,rt=W.test(rt=Object.getPrototypeOf)&&rt,it=W.test(it=Array.isArray)&&it,st=e.isFinite,ot=W.test(ot=Object.keys)&&ot,
ut=Math.max,at=Math.min,ft=Math.random,lt="[object Arguments]",ct="[object Array]",ht="[object Boolean]",pt="[object Date]",dt="[object Number]",vt="[object Object]",mt="[object RegExp]",gt="[object String]",yt=e.clearTimeout,bt=e.setTimeout,wt,Et,St,xt=n;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);for(r in arguments)xt=!r;wt=4>(n+"").length,St="x"!=n[0],Et=(n.splice.call(t,0,1),t[0])})(1);var Tt=!v(arguments),Nt="x"!=Z.call("x"
)[0],Ct="xx"!="x"[0]+Object("x")[0];try{var kt=("[object Object]",et.call(e.document||0)==vt)}catch(Lt){}var At=tt&&/\n|Opera/.test(tt+et.call(e.opera)),Ot=ot&&/^.+$|true/.test(ot+!!e.attachEvent),Mt=!At,_t={};_t[ht]=_t[pt]=_t["[object Function]"]=_t[dt]=_t[vt]=_t[mt]=i,_t[lt]=_t[ct]=_t[gt]=n;var Dt={};Dt[lt]=Dt["[object Function]"]=i,Dt[ct]=Dt[ht]=Dt[pt]=Dt[dt]=Dt[vt]=Dt[mt]=Dt[gt]=n;var Pt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Ht={"\\":"\\","'":"'","\n":"n"
,"\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var Bt={a:"d,c,y",i:"d",p:"c=f(c,y)",h:"if(c(B,j,d)===false)return u"},jt={i:"{}",p:"c=f(c,y)",h:"var q=c(B,j,d);(h.call(u,q)?u[q]++:u[q]=1)"},Ft={i:"true",h:"if(!c(B,j,d))return!u"},It={q:i,r:i,a:"n",i:"n",p:"for(var a=1,b=arguments.length;a<b;a++){if(k=arguments[a]){",h:"u[j]=B",e:"}}"},qt={i:"[]",h:"c(B,j,d)&&u.push(B)"},Rt={p
:"c=f(c,y)"},Ut={h:{k:Bt.h}},zt={i:"",d:{b:"u=Array(l)",k:"u="+(Ot?"Array(l)":"[]")},h:{b:"u[j]=c(B,j,d)",k:"u"+(Ot?"[o]=":".push")+"(c(B,j,d))"}},Wt={q:i,a:"n,c,y",i:"{}",p:"var S=typeof c=='function';if(S)c=f(c,y);else var t=e.apply(F,arguments)",h:"if(S?!c(B,j,n):N(t,j)<0)u[j]=B"},Xt=l({a:"n",i:"{}",h:"u[B]=j"});Tt&&(v=function(e){return!!e&&!!Q.call(e,"callee")});var Vt=it||function(e){return et.call(e)==ct};m(/x/)&&(m=function(e){return"[object Function]"==et.call(e)});var $t=rt?function(e){
if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=rt(t))&&rt(n);return n?e==n||rt(e)==n&&!v(e):g(e)}:g,Jt=l({a:"n",i:"[]",p:"if(!(n&&Z[typeof n]))throw TypeError()",h:"u.push(j)"}),Kt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},Qt=Xt(Kt),Gt=l(It,{h:"if(u[j]==null)"+It.h}),Yt=l(It),Zt=l(Bt,Rt,Ut,{q:i}),en=l(Bt,Rt,Ut),tn=l({q:i,a:"n",i:"[]",h:"if(T(B))u.push(j)",e:"u.sort()"}),nn=l({a:"B",i:"true",p:"if(!B)return u;var I=z.call(B),l=B.length;if(E[I]"+(Tt?"||P(B)"
:"")+"||(I==Y&&l===+l&&T(B.splice)))return!l",h:{k:"return false"}}),rn=ot?function(e){return"function"==typeof e&&Y.call(e,"prototype")?Jt(e):ot(e)}:Jt,sn=l(It,{a:"n,ee,O",p:"var Q,D=arguments,a=0;if(O==J){var b=2,ff=D[3],gg=D[4]}else var b=D.length,ff=[],gg=[];while(++a<b){if(k=D[a]){",h:"if((ee=B)&&((Q=R(ee))||U(ee))){var L=false,hh=ff.length;while(hh--)if(L=ff[hh]==ee)break;if(L){u[j]=gg[hh]}else {ff.push(ee);gg.push(B=(B=u[j])&&Q?(R(B)?B:[]):(U(B)?B:{}));u[j]=H(B,ee,J,ff,gg)}}else if(ee!=null)u[j]=ee"
}),on=l(Wt),un=l({a:"n",i:"[]",h:"u"+(Ot?"[o]=":".push")+"([j,B])"}),an=l(Wt,{p:"if(typeof c!='function'){var q,t=e.apply(F,arguments),l=t.length;for(j=1;j<l;j++){q=t[j];if(q in n)u[q]=n[q]}}else {c=f(c,y)",h:"if(c(B,j,n))u[j]=B",e:"}"}),fn=l({a:"n",i:"[]",h:"u.push(B)"}),ln=l({a:"d,ii",i:"false",n:i,d:{b:"if(z.call(d)==x)return d.indexOf(ii)>-1"},h:"if(B===ii)return true"}),cn=l(Bt,jt),hn=l(Bt,Ft),pn=l(Bt,qt),dn=l(Bt,Rt,{i:"",h:"if(c(B,j,d))return B"}),vn=l(Bt,Rt),mn=l(Bt,jt,{h:"var q=c(B,j,d);(h.call(u,q)?u[q]:u[q]=[]).push(B)"
}),gn=l(zt,{a:"d,V",p:"var D=w.call(arguments,2),S=typeof V=='function'",h:{b:"u[j]=(S?V:B[V]).apply(B,D)",k:"u"+(Ot?"[o]=":".push")+"((S?V:B[V]).apply(B,D))"}}),yn=l(Bt,zt),bn=l(zt,{a:"d,cc",h:{b:"u[j]=B[cc]",k:"u"+(Ot?"[o]=":".push")+"(B[cc])"}}),wn=l({a:"d,c,C,y",i:"C",p:"var W=arguments.length<3;c=f(c,y)",d:{b:"if(W)u=k[++j]"},h:{b:"u=c(u,B,j,d)",k:"u=W?(W=false,B):c(u,B,j,d)"}}),En=l(Bt,qt,{h:"!"+qt.h}),Sn=l(Bt,Ft,{i:"false",h:Ft.h.replace("!","")}),xn=l(Bt,jt,zt,{h:{b:"u[j]={a:c(B,j,d),b:j,c:B}"
,k:"u"+(Ot?"[o]=":".push")+"({a:c(B,j,d),b:j,c:B})"},e:"u.sort(J);l=u.length;while(l--)u[l]=u[l].c"}),Tn=l(qt,{a:"d,bb",p:"var t=[];K(bb,function(B,q){t.push(q)});var dd=t.length",h:"for(var q,aa=true,s=0;s<dd;s++){q=t[s];if(!(aa=B[q]===bb[q]))break}aa&&u.push(B)"}),Nn=l({q:i,r:i,a:"n",p:"var M=arguments,l=M.length;if(l>1){for(var j=1;j<l;j++)u[M[j]]=G(u[M[j]],u);return u}",h:"if(T(u[j]))u[j]=G(u[j],u)"});s.VERSION="0.8.0",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this
,arguments)}},s.bind=L,s.bindAll=Nn,s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=y,s.compact=function(e){for(var t=-1,n=e.length,r=[];++t<n;)e[t]&&r.push(e[t]);return r},s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=ln,s.countBy=cn,s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,yt(a),a=bt(i,t),r&&(o=e.apply
(u,s)),o}},s.defaults=Gt,s.defer=function(e){var n=Z.call(arguments,1);return bt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=Z.call(arguments,2);return bt(function(){return e.apply(t,r)},n)},s.difference=function(e){for(var t=-1,n=e.length,r=K.apply(_,arguments),r=o(r,n),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},s.escape=function(e){return e==r?"":(e+"").replace(V,h)},s.every=hn,s.extend=Yt,s.filter=pn,s.find=dn,s.first=E,s.flatten=S,s.forEach=vn,s.forIn=Zt,s.forOwn=en,s.functions=
tn,s.groupBy=mn,s.has=function(e,t){return Q.call(e,t)},s.identity=A,s.indexOf=x,s.initial=function(e,t,n){return Z.call(e,0,-(t==r||n?1:t))},s.intersection=function(e){var t,n=arguments.length,r=[],i=-1,s=e.length,u=[];e:for(;++i<s;)if(t=e[i],0>x(u,t)){for(var a=1;a<n;a++)if(!(r[a]||(r[a]=o(arguments[a])))(t))continue e;u.push(t)}return u},s.invert=Xt,s.invoke=gn,s.isArguments=v,s.isArray=Vt,s.isBoolean=function(e){return e===n||e===i||et.call(e)==ht},s.isDate=function(e){return et.call(e)==pt},
s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=nn,s.isEqual=b,s.isFinite=function(e){return st(e)&&et.call(e)==dt},s.isFunction=m,s.isNaN=function(e){return et.call(e)==dt&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=function(e){return et.call(e)==dt},s.isObject=function(e){return e?Pt[typeof e]:i},s.isPlainObject=$t,s.isRegExp=function(e){return et.call(e)==mt},s.isString=function(e){return et.call(e)==gt},s.isUndefined=function(e){return e===t},s.keys=rn,s.last=function(e
,t,n){var i=e.length;return t==r||n?e[i-1]:Z.call(e,-t||i)},s.lastIndexOf=function(e,t,n){var r=e.length;for(n&&"number"==typeof n&&(r=(0>n?ut(0,r+n):at(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.lateBind=function(e,t){return a(t,e,Z.call(arguments,2))},s.map=yn,s.max=T,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Q.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=sn,s.min=function(e,t,n){for(var r=Infinity,i=-1,s=e?e.length:0,o=
r,t=f(t,n);++i<s;)n=t(e[i],i,e),n<r&&(r=n,o=e[i]);return o},s.mixin=O,s.noConflict=function(){return e._=B,this},s.object=function(e,t){for(var n=-1,r=e.length,i={};++n<r;)t?i[e[n]]=t[n]:i[e[n][0]]=e[n][1];return i},s.omit=on,s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=un,s.partial=function(e){return a(e,Z.call(arguments,1))},s.pick=an,s.pluck=bn,s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+nt(ft()*((+t||0)-
e+1))},s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=ut(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=wn,s.reduceRight=w,s.reject=En,s.rest=N,s.result=function(e,t){var n=e?e[t]:r;return m(n)?e[t]():n},s.shuffle=function(e){for(var t,n=-1,r=e.length,i=Array(r);++n<r;)t=nt(ft()*(n+1)),i[n]=i[t],i[t]=e[n];return i},s.size=function(e){var t=e?e.length:0;return t===+t?t:rn(e).length},s.some=Sn,s.sortBy=xn,s.sortedIndex=C,s.tap=function(e,t){return t(e
),e},s.template=function(e,t,n){n||(n={});var r,i,o=0,u=s.templateSettings,a="__p += '",f=n.variable||u.variable,l=f;e.replace(RegExp((n.escape||u.escape||X).source+"|"+(n.interpolate||u.interpolate||X).source+"|"+(n.evaluate||u.evaluate||X).source+"|$","g"),function(t,n,i,s,u){a+=e.slice(o,u).replace($,c),a+=n?"'+__e("+n+")+'":s?"';"+s+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=s||j.test(n||i)),o=u+t.length}),a+="';",l||(f="obj",r?a="with("+f+"){"+a+"}":(n=RegExp("(\\(\\s*)"+f+"\\."+
f+"\\b","g"),a=a.replace(z,"$&"+f+".").replace(n,"$1__d"))),a=(r?a.replace(I,""):a).replace(q,"$1").replace(R,"$1;"),a="function("+f+"){"+(l?"":f+"||("+f+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(l?"":",__d="+f+"."+f+"||"+f)+";")+a+"return __p}";try{i=Function("_","return "+a)(s)}catch(h){throw h.source=a,h}return t?i(t):(i.source=a,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(
){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(a=r,s=e.apply(o,i)):u||(u=bt(n,f)),s}},s.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},s.toArray=function(e){var t=e?e.length:0;return t===+t?(Nt?et.call(e)==gt:"string"==typeof e)?e.split(""):Z.call(e):fn(e)},s.unescape=function(e){return e==r?"":(e+"").replace(F,d)},s.union=function(){for(var e=-1,t=K.apply(_,arguments),n=t.length,r=[];++e<n;)0>x(r,t[e])&&r.push(t[e]);return r},s.uniq=k,s.uniqueId=
function(e){var t=P++;return e?e+t:t},s.values=fn,s.where=Tn,s.without=function(e){for(var t=-1,n=e.length,r=o(arguments,1,20),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&G.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){for(var t=-1,n=T(bn(arguments,"length")),r=Array(n);++t<n;)r[t]=bn(arguments,t);return r},s.all=hn,s.any=Sn,s.collect=yn,s.detect=dn,s.drop=N,s.each=vn,s.foldl=wn,s.foldr=w,s.head=E,s.include=ln,s.inject=
wn,s.methods=tn,s.select=pn,s.tail=N,s.take=E,s.unique=k,O(s),s.prototype.chain=function(){return this.__chain__=n,this},s.prototype.value=function(){return this.__wrapped__},vn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=_[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Et&&e.length===0&&delete e[0],this.__chain__&&(e=new s(e),e.__chain__=n),e}}),vn(["concat","join","slice"],function(e){var t=_[e];s.prototype[e]=function(){var e=t.apply
(this.__wrapped__,arguments);return this.__chain__&&(e=new s(e),e.__chain__=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):M?"object"==typeof module&&module&&module.exports==M?(module.exports=s)._=s:M._=s:e._=s})(this);
;(function(e,t){function s(e){if(e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||H),s=i?{}:e;if(i)for(n=t-1;++n<r;){var o=e[n]+"";(Z.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(e){if(i){var n=e+"";return Z.call(s,n)&&-1<T(s[n],e)}return-1<T(s,e,t)}}function u(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function a(e,t,n){function r(){var u=arguments
,a=s?this:t;return i||(e=t[o]),n.length&&(u=u.length?n.concat(nt.call(u)):n),this instanceof r?(p.prototype=e.prototype,a=new p,(u=e.apply(a,u))&&Ht[typeof u]?u:a):e.apply(a,u)}var i=m(e),s=!n,o=e;return s&&(n=t),r}function f(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:A}function l(){for(var e={e:"",g:Et,i:"",j:Mt,m:Tt,n:kt,o:J,p:"",q:n,r:_t,c:{d:""},l:{d:""}},t,i=-1;t=arguments[++i];)for(var s in t){var o=t[s];/d|h/.test(s)?("string"==typeof
o&&(o={b:o,k:o}),e.c[s]=o.b,e.l[s]=o.k):e[s]=o}t=e.a;if("d"!=(e.f=/^[^,]+/.exec(t)[0])||!e.c.h)e.c=r;i="",e.r&&(i+="'use strict';"),i+="var i,A,j="+e.f+",t="+(e.i||e.f)+";if(!"+e.f+")return t;"+e.p+";",e.c&&(i+="var k=j.length;i=-1;",e.l&&(i+="if(k===+k){"),e.n&&(i+="if(y.call(j)==w){j=j.split('')}"),i+=e.c.d+";while(++i<k){A=j[i];"+e.c.h+"}",e.l&&(i+="}"));if(e.l){e.c?i+="else {":e.m&&(i+="var k=j.length;i=-1;if(k&&O(j)){while(++i<k){A=j[i+=''];"+e.l.h+"}}else {"),e.g||(i+="var u=typeof j=='function'&&q.call(j,'prototype');"
);if(e.j&&e.q)i+="var n=-1,o=Y[typeof j]?l(j):[],k=o.length;"+e.l.d+";while(++n<k){i=o[n];",e.g||(i+="if(!(u&&i=='prototype')){"),i+="A=j[i];"+e.l.h+"",e.g||(i+="}");else{i+=e.l.d+";for(i in j){";if(!e.g||e.q)i+="if(",e.g||(i+="!(u&&i=='prototype')"),!e.g&&e.q&&(i+="&&"),e.q&&(i+="h.call(j,i)"),i+="){";i+="A=j[i];"+e.l.h+";";if(!e.g||e.q)i+="}"}i+="}";if(e.g){i+="var g=j.constructor;";for(s=0;7>s;s++)i+="i='"+e.o[s]+"';if(","constructor"==e.o[s]&&(i+="!(g&&g.prototype===j)&&"),i+="h.call(j,i)){A=j[i];"+
e.l.h+"}"}if(e.c||e.m)i+="}"}return i+=e.e+";return t",Function("D,E,F,I,e,f,J,h,M,O,Q,S,T,X,Y,l,q,v,w,y,z","var G=function("+t+"){"+i+"};return G")(Dt,_,L,u,Q,f,en,Z,T,v,$t,m,Jt,mt,Ht,ut,tt,nt,yt,rt)}function c(e){return"\\"+Bt[e]}function h(e){return Qt[e]}function p(){}function d(e){return Gt[e]}function v(e){return rt.call(e)==ct}function m(e){return"function"==typeof e}function g(e){var t=i;if(!e||"object"!=typeof e||v(e))return t;var n=e.constructor;return(!Lt||"function"==typeof e.toString||"string"!=typeof
(e+""))&&(!m(n)||n instanceof n)?xt?(en(e,function(e,n,r){return t=!Z.call(r,n),i}),t===i):(en(e,function(e,n){t=n}),t===i||Z.call(e,t)):t}function y(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=Ht[typeof e]){var u=rt.call(e);if(!Pt[u]||Nt&&v(e))return e;var a=u==ht,n=a||(u==mt?Jt(e):n)}if(!n||!t)return n?a?nt.call(e):Zt({},e):e;n=e.constructor;switch(u){case pt:case dt:return new n(+e);case vt:case yt:return new n(e);case gt:return n(e.source,U.exec(e))}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[
u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?mn:tn)(e,function(e,n){f[n]=y(e,t,r,s,o)}),f}function b(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Ht[typeof e]||Ht[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=rt.call(e);if(u!=rt.call(t))return i;switch(u){case pt:case dt:return+e==+t;case vt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case gt:case yt:return e==t+""}var a=Dt[u];if(Nt&&!a&&(a=v(e))&&!v(t)||!a&&(u!=mt||Lt&&("function"!=typeof e.
toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=b(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!m(a)||!(a instanceof a&&m(f)&&f instanceof f)))return i;for(var c in e)if(Z.call(e,c)&&(l++,!Z.call(t,c)||!b(e[c],t[c],s,o)))return i;for(c in t)if(Z.call(t,c)&&!(l--))return i;if(
Et)for(;7>++u;)if(c=J[u],Z.call(e,c)&&(!Z.call(t,c)||!b(e[c],t[c],s,o)))return i;return n}function w(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),mn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function E(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if(o!==+o)var a=sn(e),o=a.length;else kt&&rt.call(e)==yt&&(s=e.split(""));return mn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function S(e,t,n){
if(e)return t==r||n?e[0]:nt.call(e,0,t)}function x(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];$t(s)?et.apply(i,t?s:x(s)):i.push(s)}return i}function T(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?at(0,i+n):n||0)-1;else if(n)return r=C(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function N(e,t,n){return e?nt.call(e,t==r||n?1:t):[]}function C(e,t,n,r){var i=0,s=e?e.length:i;if(n){n=f(n,r);for(t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r}else for(;i<s;)r=i+
s>>>1,e[r]<t?i=r+1:s=r;return i}function k(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=f(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>T(a,r))a.push(r),u.push(e[s]);return u}function L(e,t){return Ot||it&&2<arguments.length?it.call.apply(it,arguments):a(e,t,nt.call(arguments,2))}function A(e){return e}function O(e){mn(nn(e),function(t){var r=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&et.apply(e,arguments)
,e=r.apply(s,e),this.__chain__&&(e=new s(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,M="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),_=Array.prototype,D=Object.prototype,P=0,H=30,B=e._,j=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,F=/&(?:amp|lt|gt|quot|#x27);/g,I=/\b__p\+='';/g,q=/\b(__p\+=)''\+/g,R=/(__e\(.*?\)|\b__t\))\+'';/g,U=/\w*$/,z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,W=RegExp("^"+(D.valueOf+""
).replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),X=/($^)/,V=/[&<>"']/g,$=/['\n\r\t\u2028\u2029\\]/g,J="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),K=Math.ceil,Q=_.concat,G=Math.floor,Y=W.test(Y=Object.getPrototypeOf)&&Y,Z=D.hasOwnProperty,et=_.push,tt=D.propertyIsEnumerable,nt=_.slice,rt=D.toString,it=W.test(it=nt.bind)&&it,st=W.test(st=Array.isArray)&&st,ot=e.isFinite,ut=W.test(ut=Object.keys)&&ut
,at=Math.max,ft=Math.min,lt=Math.random,ct="[object Arguments]",ht="[object Array]",pt="[object Boolean]",dt="[object Date]",vt="[object Number]",mt="[object Object]",gt="[object RegExp]",yt="[object String]",bt=e.clearTimeout,wt=e.setTimeout,Et,St,xt,Tt=n;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);for(r in arguments)Tt=!r;Et=4>(n+"").length,xt="x"!=n[0],St=(n.splice.call(t,0,1),t[0])})(1);var Nt=!v(arguments),Ct="x"!=nt.call("x"
)[0],kt="xx"!="x"[0]+Object("x")[0];try{var Lt=("[object Object]",rt.call(e.document||0)==mt)}catch(At){}var Ot=it&&/\n|Opera/.test(it+rt.call(e.opera)),Mt=ut&&/^.+$|true/.test(ut+!!e.attachEvent),_t=!Ot,Dt={};Dt[pt]=Dt[dt]=Dt["[object Function]"]=Dt[vt]=Dt[mt]=Dt[gt]=i,Dt[ct]=Dt[ht]=Dt[yt]=n;var Pt={};Pt[ct]=Pt["[object Function]"]=i,Pt[ht]=Pt[pt]=Pt[dt]=Pt[vt]=Pt[mt]=Pt[gt]=Pt[yt]=n;var Ht={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Bt={"\\":"\\","'":"'","\n":"n"
,"\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var jt={a:"d,c,x",p:"c=f(c,x)",h:"if(c(A,i,d)===false)return t"},Ft={i:"{}",p:"c=f(c,x)",h:"var p=c(A,i,d);(h.call(t,p)?t[p]++:t[p]=1)"},It={i:"true",h:"if(!c(A,i,d))return!t"},qt={q:i,r:i,a:"m",p:"for(var a=1,b=arguments.length;a<b;a++){if(j=arguments[a]){",h:"t[i]=A",e:"}}"},Rt={i:"[]",h:"c(A,i,d)&&t.push(A)"},Ut={p:"c=f(c,x)"}
,zt={h:{k:jt.h}},Wt={i:"d||[]",d:{b:"t=Array(k)",k:"t="+(Mt?"Array(k)":"[]")},h:{b:"t[i]=c(A,i,d)",k:"t"+(Mt?"[n]=":".push")+"(c(A,i,d))"}},Xt={q:i,a:"m,c,x",i:"{}",p:"var R=typeof c=='function';if(R)c=f(c,x);else var s=e.apply(E,arguments)",h:"if(R?!c(A,i,m):M(s,i)<0)t[i]=A"},Vt=l({a:"m",i:"{}",h:"t[A]=i"});Nt&&(v=function(e){return e?Z.call(e,"callee"):i});var $t=st||function(e){return rt.call(e)==ht};m(/x/)&&(m=function(e){return"[object Function]"==rt.call(e)});var Jt=Y?function(e){if(!e||"object"!=typeof
e)return i;var t=e.valueOf,n="function"==typeof t&&(n=Y(t))&&Y(n);return n?e==n||Y(e)==n&&!v(e):g(e)}:g,Kt=l({a:"m",i:"[]",h:"t.push(i)"}),Qt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},Gt=Vt(Qt),Yt=l(qt,{h:"if(t[i]==null)"+qt.h}),Zt=l(qt),en=l(jt,Ut,zt,{q:i}),tn=l(jt,Ut,zt),nn=l({q:i,a:"m",i:"[]",h:"S(A)&&t.push(i)",e:"t.sort()"}),rn=l({a:"A",i:"true",p:"var H=y.call(A),k=A.length;if(D[H]"+(Nt?"||O(A)":"")+"||(H==X&&k===+k&&S(A.splice)))return!k",h:{k:"return false"}}),sn=ut?function(
e){var t=typeof e;return"function"==t&&tt.call(e,"prototype")?Kt(e):e&&Ht[t]?ut(e):[]}:Kt,on=l(qt,{a:"m,dd,N",p:"var P,C=arguments,a=0;if(N==I){var b=2,ee=C[3],ff=C[4]}else var b=C.length,ee=[],ff=[];while(++a<b){if(j=C[a]){",h:"if((dd=A)&&((P=Q(dd))||T(dd))){var K=false,gg=ee.length;while(gg--)if(K=ee[gg]==dd)break;if(K){t[i]=ff[gg]}else {ee.push(dd);ff.push(A=(A=t[i],P)?(Q(A)?A:[]):(T(A)?A:{}));t[i]=G(A,dd,I,ee,ff)}}else if(dd!=null)t[i]=dd"}),un=l(Xt),an=l({a:"m",i:"[]",h:"t"+(Mt?"[n]=":".push"
)+"([i,A])"}),fn=l(Xt,{p:"if(typeof c!='function'){var i=0,s=e.apply(E,arguments),k=s.length;while(++i<k){var p=s[i];if(p in m)t[p]=m[p]}}else {c=f(c,x)",h:"if(c(A,i,m))t[i]=A",e:"}"}),ln=l({a:"m",i:"[]",h:"t.push(A)"}),cn=l({a:"d,hh",i:"false",n:i,d:{b:"if(y.call(d)==w)return d.indexOf(hh)>-1"},h:"if(A===hh)return true"}),hn=l(jt,Ft),pn=l(jt,It),dn=l(jt,Rt),vn=l(jt,Ut,{i:"z",h:"if(c(A,i,d))return A"}),mn=l(jt,Ut),gn=l(jt,Ft,{h:"var p=c(A,i,d);(h.call(t,p)?t[p]:t[p]=[]).push(A)"}),yn=l(Wt,{a:"d,U"
,p:"var C=v.call(arguments,2),R=typeof U=='function'",h:{b:"t[i]=(R?U:A[U]).apply(A,C)",k:"t"+(Mt?"[n]=":".push")+"((R?U:A[U]).apply(A,C))"}}),bn=l(jt,Wt),wn=l(Wt,{a:"d,bb",h:{b:"t[i]=A[bb]",k:"t"+(Mt?"[n]=":".push")+"(A[bb])"}}),En=l({a:"d,c,B,x",i:"B",p:"var V=arguments.length<3;c=f(c,x)",d:{b:"if(V)t=j[++i]"},h:{b:"t=c(t,A,i,d)",k:"t=V?(V=false,A):c(t,A,i,d)"}}),Sn=l(jt,Rt,{h:"!"+Rt.h}),xn=l(jt,It,{i:"false",h:It.h.replace("!","")}),Tn=l(jt,Ft,Wt,{h:{b:"t[i]={a:c(A,i,d),b:i,c:A}",k:"t"+(Mt?"[n]="
:".push")+"({a:c(A,i,d),b:i,c:A})"},e:"t.sort(I);k=t.length;while(k--)t[k]=t[k].c"}),Nn=l(Rt,{a:"d,aa",p:"var s=[];J(aa,function(A,p){s.push(p)});var cc=s.length",h:"for(var Z=true,r=0;r<cc;r++){var p=s[r];if(!(Z=A[p]===aa[p]))break}Z&&t.push(A)"}),Cn=l({q:i,r:i,a:"m",p:"var L=arguments,i=0,k=L.length;if(k>1){while(++i<k)t[L[i]]=F(t[L[i]],t);return t}",h:"if(S(A))t[i]=F(A,t)"});s.VERSION="0.8.2",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=L,s.bindAll=
Cn,s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=y,s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=cn,s.countBy=hn,s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,bt(a),a=wt(i,t),r&&(o=e.apply(u,s)),o}},s.defaults=
Yt,s.defer=function(e){var n=nt.call(arguments,1);return wt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=nt.call(arguments,2);return wt(function(){return e.apply(t,r)},n)},s.difference=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=Q.apply(_,arguments),i=o(i,r);++n<r;){var s=e[n];i(s)||t.push(s)}return t},s.escape=function(e){return e==r?"":(e+"").replace(V,h)},s.every=pn,s.extend=Zt,s.filter=dn,s.find=vn,s.first=S,s.flatten=x,s.forEach=mn,s.forIn=en,s.forOwn=tn,
s.functions=nn,s.groupBy=gn,s.has=function(e,t){return e?Z.call(e,t):i},s.identity=A,s.indexOf=T,s.initial=function(e,t,n){return e?nt.call(e,0,-(t==r||n?1:t)):[]},s.intersection=function(e){var t=arguments.length,n=[],r=-1,i=e?e.length:0,s=[];e:for(;++r<i;){var u=e[r];if(0>T(s,u)){for(var a=1;a<t;a++)if(!(n[a]||(n[a]=o(arguments[a])))(u))continue e;s.push(u)}}return s},s.invert=Vt,s.invoke=yn,s.isArguments=v,s.isArray=$t,s.isBoolean=function(e){return e===n||e===i||rt.call(e)==pt},s.isDate=function(
e){return rt.call(e)==dt},s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=rn,s.isEqual=b,s.isFinite=function(e){return ot(e)&&rt.call(e)==vt},s.isFunction=m,s.isNaN=function(e){return rt.call(e)==vt&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=function(e){return rt.call(e)==vt},s.isObject=function(e){return e?Ht[typeof e]:i},s.isPlainObject=Jt,s.isRegExp=function(e){return rt.call(e)==gt},s.isString=function(e){return rt.call(e)==yt},s.isUndefined=function(e){return e===t},s
.keys=sn,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:nt.call(e,-t||i)}},s.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?at(0,r+n):ft(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.lateBind=function(e,t){return a(t,e,nt.call(arguments,2))},s.map=bn,s.max=w,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Z.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=on,s.min=function(e,t,n){var r=
Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=f(t,n),mn(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},s.mixin=O,s.noConflict=function(){return e._=B,this},s.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},s.omit=un,s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=an,s.partial=function(e){return a(e,nt.call(arguments,1))},s.pick=fn,s.pluck=
wn,s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+G(lt()*((+t||0)-e+1))},s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=at(0,K((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=En,s.reduceRight=E,s.reject=Sn,s.rest=N,s.result=function(e,t){var n=e?e[t]:r;return m(n)?e[t]():n},s.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return mn(e,function(e){var r=G(lt()*(++t+1));n[t]=n[r],n[r]=e}),n},s.size=function(e){var t=e?e.length:0;return t===+
t?t:sn(e).length},s.some=xn,s.sortBy=Tn,s.sortedIndex=C,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){e||(e=""),n||(n={});var r,i,o=0,u=s.templateSettings,a="__p += '",f=n.variable||u.variable,l=f;e.replace(RegExp((n.escape||u.escape||X).source+"|"+(n.interpolate||u.interpolate||X).source+"|"+(n.evaluate||u.evaluate||X).source+"|$","g"),function(t,n,i,s,u){a+=e.slice(o,u).replace($,c),a+=n?"'+__e("+n+")+'":s?"';"+s+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=s||j.test(
n||i)),o=u+t.length}),a+="';",l||(f="obj",r?a="with("+f+"){"+a+"}":(n=RegExp("(\\(\\s*)"+f+"\\."+f+"\\b","g"),a=a.replace(z,"$&"+f+".").replace(n,"$1__d"))),a=(r?a.replace(I,""):a).replace(q,"$1").replace(R,"$1;"),a="function("+f+"){"+(l?"":f+"||("+f+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(l?"":",__d="+f+"."+f+"||"+f)+";")+a+"return __p}";try{i=Function("_","return "+a)(s)}catch(h){throw h.source=a,h}return t?i(t):(i.source=
a,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(bt(u),a=r,s=e.apply(o,i)):u||(u=wt(n,f)),s}},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},s.toArray=function(e){if(!e)return[];var t=e.length;return t===+t?(Ct?rt.call(e)==yt:"string"==typeof e)?e.split(""):nt.call(e):ln(e)},s.unescape=function(e){return e==r?"":(e+"").replace(F,d)},s.union=
function(){for(var e=-1,t=Q.apply(_,arguments),n=t.length,r=[];++e<n;){var i=t[e];0>T(r,i)&&r.push(i)}return r},s.uniq=k,s.uniqueId=function(e){var t=P++;return e?e+t:t},s.values=ln,s.where=Nn,s.without=function(e){for(var t=-1,n=e?e.length:0,r=o(arguments,1,20),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&et.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){for(var t=-1,n=e?w(wn(arguments,"length")):0,r=Array(n);++
t<n;)r[t]=wn(arguments,t);return r},s.all=pn,s.any=xn,s.collect=bn,s.detect=vn,s.drop=N,s.each=mn,s.foldl=En,s.foldr=E,s.head=S,s.include=cn,s.inject=En,s.methods=nn,s.select=dn,s.tail=N,s.take=S,s.unique=k,O(s),s.prototype.chain=function(){return this.__chain__=n,this},s.prototype.value=function(){return this.__wrapped__},mn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=_[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),St&&e.length===0&&delete
e[0],this.__chain__&&(e=new s(e),e.__chain__=n),e}}),mn(["concat","join","slice"],function(e){var t=_[e];s.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new s(e),e.__chain__=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):M?"object"==typeof module&&module&&module.exports==M?(module.exports=s)._=s:M._=s:e._=s})(this);

View File

@@ -1,35 +1,36 @@
/*!
Lo-Dash 0.8.0 lodash.com/license
Underscore.js 1.4.0 underscorejs.org/LICENSE
Lo-Dash 0.8.2 lodash.com/license
Underscore.js 1.4.2 underscorejs.org/LICENSE
*/
;(function(e,t){function s(e,t,r){var s,t=T(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],t(s,r,e))return n}else for(r in e)if(st.call(e,r)&&(s=e[r],t(s,r,e)))return n;return i}function o(e,t,n,r){var s,o,u=n,a=3>arguments.length,t=T(t,r),f=e.length;s=-1;if(f===+f)for(a&&(u=e[++s]);++s<f;)o=e[s],u=t(u,o,s,e);else for(s in e)st.call(e,s)&&(o=e[s],u=a?(a=i,o):t(u,o,s,e));return u}function u(e,t){var n,r,i,s=e.length;n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]=r[t];else for(n in i=[],e)st
.call(e,n)&&(r=e[n],i.push(r[t]));return i}function a(e,t,n){var r,i,t=T(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]=t(r,n,e);else for(n in i=[],e)st.call(e,n)&&(r=e[n],i.push(t(r,n,e)));return i}function f(e,t,n){var r,t=T(t,n),i=e.length,n=-1;if(i===+i)for(;++n<i;)r=e[n],t(r,n,e);else for(n in e)st.call(e,n)&&(r=e[n],t(r,n,e));return e}function l(e,t,n){var r,t=T(t,n),i=e.length,n=-1;if(i===+i){for(;++n<i;)if(r=e[n],t(r,n,e))return r}else for(n in e)if(st.call(e,n)&&(r=e[n]
,t(r,n,e)))return r}function c(e,t,n){var r,i=[],t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],t(r,n,e)&&i.push(r);else for(n in e)st.call(e,n)&&(r=e[n],t(r,n,e)&&i.push(r));return i}function h(e,t,r){var s,t=T(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],!t(s,r,e))return i}else for(r in e)if(st.call(e,r)&&(s=e[r],!t(s,r,e)))return i;return n}function p(e,t){var r,s,o=e.length;r=-1;if(o===+o){if(ft.call(e)==Tt)return-1<e.indexOf(t);for(;++r<o;)if(s=e[r],s===t)return n}else for(r in
e)if(st.call(e,r)&&(s=e[r],s===t))return n;return i}function d(e){var t,n,r=[];for(t in e)st.call(e,t)&&(n=e[t],r.push(n));return r}function v(e){var t,n,r=[];for(t in e)n=e[t],A(n)&&r.push(t);return r.sort(),r}function m(e,t,n){var r,t=T(t,n);for(r in e)n=e[r],t(n,r,e);return e}function g(e){for(var t,n,r=e,i=1,s=arguments.length;i<s;i++)if(r=arguments[i])for(t in r)n=r[t],e[t]=n;return e}function y(e){var t,n=[];if(!e||!Lt[typeof e])throw TypeError();for(t in e)st.call(e,t)&&n.push(t);return n}
function b(e){var t,n,r={};for(t in e)st.call(e,t)&&(n=e[t],r[n]=t);return r}function w(e){if(e&&e.__wrapped__)return e;if(!(this instanceof w))return new w(e);this.__wrapped__=e}function E(e,t){return function(n){return-1<H(e,n,t||0)}}function S(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function x(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(at.call(i)):n),this instanceof r?(k.prototype=e.prototype,s=new
k,(i=e.apply(s,i))&&Lt[typeof i]?i:s):e.apply(s,i)}return r}function T(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:R}function N(e){return"\\"+At[e]}function C(e){return Mt[e]}function k(){}function L(e){return _t[e]}function A(e){return"function"==typeof e}function O(e){var t=i;if(!e||"object"!=typeof e||isArguments(e))return t;var n=e.constructor;return!A(n)||n instanceof n?(m(e,function(e,n){t=n}),t===i||st.call(e,t)):t}function M(
e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Lt[typeof e]||Lt[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=ft.call(e);if(u!=ft.call(t))return i;switch(u){case bt:case wt:return+e==+t;case Et:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case xt:case Tt:return e==t+""}var a=Ot(e);if(!a&&u!=St)return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var f=n,u=0;s.push(e),o.push(t);if(a){u=e.length;if(f=u==t.length)for(;u--&&(f=M(e[u],t[u],s,o)););return f
}a=e.constructor,f=t.constructor;if(a!=f&&(!A(a)||!(a instanceof a&&A(f)&&f instanceof f)))return i;for(var l in e)if(st.call(e,l)&&(u++,!st.call(t,l)||!M(e[l],t[l],s,o)))return i;for(l in t)if(st.call(t,l)&&!(u--))return i;return n}function _(e,t,n,r){var s=e.length,o=3>arguments.length;if(s!==+s)var u=Dt(e),s=u.length;return f(e,function(a,f,l){f=u?u[--s]:--s,n=o?(o=i,e[f]):t.call(r,n,e[f],f,l)}),n}function D(e,t,n){return t==r||n?e[0]:at.call(e,0,t)}function P(e,t){for(var n,r=-1,i=e.length,s=
[];++r<i;)n=e[r],Ot(n)?ot.apply(s,t?n:P(n)):s.push(n);return s}function H(e,t,n){var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=F(e,t),e[r]===t?r:-1;r=(0>n?mt(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function B(e,t,n){for(var r=-Infinity,i=-1,s=e?e.length:0,o=r,t=T(t,n);++i<s;)n=t(e[i],i,e),n>r&&(r=n,o=e[i]);return o}function j(e,t,n){return at.call(e,t==r||n?1:t)}function F(e,t,n,r){for(var i=0,s=e.length,n=T(n,r),t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function I
(e,t,n,r){var s=-1,o=e.length,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=T(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>H(a,r))a.push(r),u.push(e[s]);return u}function q(e,t){return kt||lt&&2<arguments.length?lt.call.apply(lt,arguments):x(e,t,at.call(arguments,2))}function R(e){return e}function U(e){f(v(e),function(t){var r=w[t]=e[t];w.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&ot.apply(e,arguments),e=r.apply(w,e),this.__chain__&&(e=new w(e),e.__chain__=
n),e}})}var n=!0,r=null,i=!1,z="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),W=Array.prototype,X=Object.prototype,V=0,$=e._,J=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,K=/&(?:amp|lt|gt|quot|#x27);/g,Q=/\b__p\+='';/g,G=/\b(__p\+=)''\+/g,Y=/(__e\(.*?\)|\b__t\))\+'';/g,Z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,et=RegExp("^"+(X.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g
,".+?")+"$"),tt=/($^)/,nt=/[&<>"']/g,rt=/['\n\r\t\u2028\u2029\\]/g,it=W.concat,st=X.hasOwnProperty,ot=W.push,ut=X.propertyIsEnumerable,at=W.slice,ft=X.toString,lt=et.test(lt=at.bind)&&lt,ct=Math.floor,ht=et.test(ht=Object.getPrototypeOf)&&ht,pt=et.test(pt=Array.isArray)&&pt,dt=e.isFinite,vt=et.test(vt=Object.keys)&&vt,mt=Math.max,gt=Math.min,yt=Math.random,bt="[object Boolean]",wt="[object Date]",Et="[object Number]",St="[object Object]",xt="[object RegExp]",Tt="[object String]",Nt=e.clearTimeout
,Ct=e.setTimeout,kt=lt&&/\n|Opera/.test(lt+ft.call(e.opera)),Lt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},At={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};w.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},w.isArguments=function(e){return"[object Arguments]"==ft.call(e)},w.isArguments(arguments)||(w.isArguments=function(e){return!!e&&!!st.call(e,"callee")});var Ot=
pt||function(e){return"[object Array]"==ft.call(e)};A(/x/)&&(A=function(e){return"[object Function]"==ft.call(e)});var X=ht?function(e){if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=ht(t))&&ht(n);return n?e==n||ht(e)==n&&!isArguments(e):O(e)}:O,Mt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},_t=b(Mt),Dt=vt?function(e){return"function"==typeof e&&ut.call(e,"prototype")?y(e):vt(e)}:y;w.VERSION="0.8.0",w.after=function(e,t){return 1>e?t():function(){if(1>--
e)return t.apply(this,arguments)}},w.bind=q,w.bindAll=function(e){var t,n=e,r=e,i=arguments,s=i.length;if(1<s){for(t=1;t<s;t++)r[i[t]]=q(r[i[t]],r);return r}for(t in n)A(r[t])&&(r[t]=q(r[t],r));return r},w.chain=function(e){return e=new w(e),e.__chain__=n,e},w.clone=function(e){return e&&Lt[typeof e]?Ot(e)?at.call(e):g({},e):e},w.compact=function(e){for(var t=-1,n=e.length,r=[];++t<n;)e[t]&&r.push(e[t]);return r},w.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length
;n--;)t=[e[n].apply(this,t)];return t[0]}},w.contains=p,w.countBy=function(e,t,n){var r,i={},t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],r=t(r,n,e),st.call(i,r)?i[r]++:i[r]=1;else for(n in e)st.call(e,n)&&(r=e[n],r=t(r,n,e),st.call(i,r)?i[r]++:i[r]=1);return i},w.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,Nt(a),a=Ct(i,t),r&&(o=e.apply(u,s)),o}},w.defaults=function(e){for(var t,n,i=e,s=1,o=arguments.length
;s<o;s++)if(i=arguments[s])for(t in i)n=i[t],e[t]==r&&(e[t]=n);return e},w.defer=function(e){var n=at.call(arguments,1);return Ct(function(){return e.apply(t,n)},1)},w.delay=function(e,n){var r=at.call(arguments,2);return Ct(function(){return e.apply(t,r)},n)},w.difference=function(e){for(var t=-1,n=e.length,r=it.apply(W,arguments),r=E(r,n),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},w.escape=function(e){return e==r?"":(e+"").replace(nt,C)},w.every=h,w.extend=g,w.filter=c,w.find=l,w.first=D,w.flatten=
P,w.forEach=f,w.forIn=m,w.forOwn=function(e,t,n){var r,t=T(t,n);for(r in e)st.call(e,r)&&(n=e[r],t(n,r,e));return e},w.functions=v,w.groupBy=function(e,t,n){var r,i={},t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;){r=e[n];var o=t(r,n,e);(st.call(i,o)?i[o]:i[o]=[]).push(r)}else for(n in e)st.call(e,n)&&(r=e[n],o=t(r,n,e),(st.call(i,o)?i[o]:i[o]=[]).push(r));return i},w.has=function(e,t){return st.call(e,t)},w.identity=R,w.indexOf=H,w.initial=function(e,t,n){return at.call(e,0,-(t==r||n?1:t))},w.intersection=
function(e){var t,n=arguments.length,r=[],i=-1,s=e.length,o=[];e:for(;++i<s;)if(t=e[i],0>H(o,t)){for(var u=1;u<n;u++)if(!(r[u]||(r[u]=E(arguments[u])))(t))continue e;o.push(t)}return o},w.invert=b,w.invoke=function(e,t){var n,r,i=e,s,o=at.call(arguments,2),u="function"==typeof t,a=i.length;n=-1;if(a===+a)for(s=Array(a);++n<a;)r=i[n],s[n]=(u?t:r[t]).apply(r,o);else for(n in s=[],i)st.call(i,n)&&(r=i[n],s.push((u?t:r[t]).apply(r,o)));return s},w.isArray=Ot,w.isBoolean=function(e){return e===n||e===
i||ft.call(e)==bt},w.isDate=function(e){return ft.call(e)==wt},w.isElement=function(e){return e?1===e.nodeType:i},w.isEmpty=function(e){var t;if(!e)return n;var r=ft.call(e),s=e.length;if(Ot(e)||r==Tt||r==St&&s===+s&&A(e.splice))return!s;for(t in e)if(st.call(e,t))return i;return n},w.isEqual=M,w.isFinite=function(e){return dt(e)&&ft.call(e)==Et},w.isFunction=A,w.isNaN=function(e){return ft.call(e)==Et&&e!=+e},w.isNull=function(e){return e===r},w.isNumber=function(e){return ft.call(e)==Et},w.isObject=
function(e){return e?Lt[typeof e]:i},w.isPlainObject=X,w.isRegExp=function(e){return ft.call(e)==xt},w.isString=function(e){return ft.call(e)==Tt},w.isUndefined=function(e){return e===t},w.keys=Dt,w.last=function(e,t,n){var i=e.length;return t==r||n?e[i-1]:at.call(e,-t||i)},w.lastIndexOf=function(e,t,n){var r=e.length;for(n&&"number"==typeof n&&(r=(0>n?mt(0,r+n):gt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},w.map=a,w.max=B,w.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this
,arguments):arguments[0];return st.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},w.min=function(e,t,n){for(var r=Infinity,i=-1,s=e?e.length:0,o=r,t=T(t,n);++i<s;)n=t(e[i],i,e),n<r&&(r=n,o=e[i]);return o},w.mixin=U,w.noConflict=function(){return e._=$,this},w.object=function(e,t){for(var n=-1,r=e.length,i={};++n<r;)t?i[e[n]]=t[n]:i[e[n][0]]=e[n][1];return i},w.omit=function(e,t,n){var r,i,s=e,o={},u="function"==typeof t;if(u)t=T(t,n);else var a=it.apply(W,arguments);for(r in s)if(i=s[r],u?!t(i,r,e
):0>H(a,r))o[r]=i;return o},w.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},w.pairs=function(e){var t,n,r=[];for(t in e)st.call(e,t)&&(n=e[t],r.push([t,n]));return r},w.pick=function(e,t,n){var r,i,s=e,o={};if("function"!=typeof t){var s=it.apply(W,arguments),u=s.length;for(r=1;r<u;r++)i=s[r],i in e&&(o[i]=e[i])}else for(r in t=T(t,n),s)i=s[r],t(i,r,e)&&(o[r]=i);return o},w.pluck=u,w.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e
,e=0),e+ct(yt()*((+t||0)-e+1))},w.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=mt(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},w.reduce=o,w.reduceRight=_,w.reject=function(e,t,n){var r,i=[],t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],!t(r,n,e)&&i.push(r);else for(n in e)st.call(e,n)&&(r=e[n],!t(r,n,e)&&i.push(r));return i},w.rest=j,w.result=function(e,t){var n=e?e[t]:r;return A(n)?e[t]():n},w.shuffle=function(e){for(var t,n=-1,r=e.length,i=Array(
r);++n<r;)t=ct(yt()*(n+1)),i[n]=i[t],i[t]=e[n];return i},w.size=function(e){var t=e?e.length:0;return t===+t?t:Dt(e).length},w.some=s,w.sortBy=function(e,t,n){var r,i,t=T(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]={a:t(r,n,e),b:n,c:r};else for(n in i=[],e)st.call(e,n)&&(r=e[n],i.push({a:t(r,n,e),b:n,c:r}));i.sort(S);for(s=i.length;s--;)i[s]=i[s].c;return i},w.sortedIndex=F,w.tap=function(e,t){return t(e),e},w.template=function(e,t,n){n||(n={});var r,i,s=0,o=w.templateSettings
,u="__p += '",a=n.variable||o.variable,f=a;e.replace(RegExp((n.escape||o.escape||tt).source+"|"+(n.interpolate||o.interpolate||tt).source+"|"+(n.evaluate||o.evaluate||tt).source+"|$","g"),function(t,n,i,o,a){u+=e.slice(s,a).replace(rt,N),u+=n?"'+__e("+n+")+'":o?"';"+o+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=o||J.test(n||i)),s=a+t.length}),u+="';",f||(a="obj",r?u="with("+a+"){"+u+"}":(n=RegExp("(\\(\\s*)"+a+"\\."+a+"\\b","g"),u=u.replace(Z,"$&"+a+".").replace(n,"$1__d"))),u=(r?u.replace
(Q,""):u).replace(G,"$1").replace(Y,"$1;"),u="function("+a+"){"+(f?"":a+"||("+a+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(f?"":",__d="+a+"."+a+"||"+a)+";")+u+"return __p}";try{i=Function("_","return "+u)(w)}catch(l){throw l.source=u,l}return t?i(t):(i.source=u,i)},w.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(a=
r,s=e.apply(o,i)):u||(u=Ct(n,f)),s}},w.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},w.toArray=function(e){var t=e?e.length:0;return t===+t?"string"==typeof e?e.split(""):at.call(e):d(e)},w.unescape=function(e){return e==r?"":(e+"").replace(K,L)},w.union=function(){for(var e=-1,t=it.apply(W,arguments),n=t.length,r=[];++e<n;)0>H(r,t[e])&&r.push(t[e]);return r},w.uniq=I,w.uniqueId=function(e){var t=V++;return e?e+t:t},w.values=d,w.where=function(e,t){var r,
i,s=[],o=[];m(t,function(e,t){o.push(t)});var u=o.length,a=e.length;r=-1;if(a===+a)for(;++r<a;){i=e[r];var f;f=n;for(var l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}else for(r in e)if(st.call(e,r)){i=e[r],f=n;for(l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}return s},w.without=function(e){for(var t=-1,n=e.length,r=E(arguments,1),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},w.wrap=function(e,t){return function(){var n=[e];return arguments.length&&ot.apply(n,arguments),t.apply(this,n)}},w
.zip=function(e){for(var t=-1,n=B(u(arguments,"length")),r=Array(n);++t<n;)r[t]=u(arguments,t);return r},w.all=h,w.any=s,w.collect=a,w.detect=l,w.drop=j,w.each=f,w.foldl=o,w.foldr=_,w.head=D,w.include=p,w.inject=o,w.methods=v,w.select=c,w.tail=j,w.take=D,w.unique=I,U(w),w.prototype.chain=function(){return this.__chain__=n,this},w.prototype.value=function(){return this.__wrapped__},f("pop push reverse shift sort splice unshift".split(" "),function(e){var t=W[e];w.prototype[e]=function(){var e=this
.__wrapped__;return t.apply(e,arguments),this.__chain__&&(e=new w(e),e.__chain__=n),e}}),f(["concat","join","slice"],function(e){var t=W[e];w.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new w(e),e.__chain__=n),e}}),z?"object"==typeof module&&module&&module.exports==z?(module.exports=w)._=w:z._=w:e._=w})(this);
;(function(e,t){function s(e,t,r){var s;if(!e)return i;var t=x(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],t(s,r,e))return n}else for(r in e)if(it.call(e,r)&&(s=e[r],t(s,r,e)))return n;return i}function o(e,t,n,r){var s,o,u=n;if(!e)return u;var a=3>arguments.length,t=x(t,r),f=e.length;s=-1;if(f===+f)for(a&&(u=e[++s]);++s<f;)o=e[s],u=t(u,o,s,e);else for(s in e)it.call(e,s)&&(o=e[s],u=a?(a=i,o):t(u,o,s,e));return u}function u(e,t){var n,r,i=e||[];if(!e)return i;var s=e.length;n=-1;if(s===+
s)for(i=Array(s);++n<s;)r=e[n],i[n]=r[t];else for(n in i=[],e)it.call(e,n)&&(r=e[n],i.push(r[t]));return i}function a(e,t,n){var r,i=e||[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]=t(r,n,e);else for(n in i=[],e)it.call(e,n)&&(r=e[n],i.push(t(r,n,e)));return i}function f(e,t,n){var r;if(!e)return e;var t=x(t,n),i=e.length,n=-1;if(i===+i)for(;++n<i;)r=e[n],t(r,n,e);else for(n in e)it.call(e,n)&&(r=e[n],t(r,n,e));return e}function l(e,n,r){var i,s=t;if(!
e)return s;var n=x(n,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(i=e[r],n(i,r,e))return i}else for(r in e)if(it.call(e,r)&&(i=e[r],n(i,r,e)))return i;return s}function c(e,t,n){var r,i=[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],t(r,n,e)&&i.push(r);else for(n in e)it.call(e,n)&&(r=e[n],t(r,n,e)&&i.push(r));return i}function h(e,t,r){var s;if(!e)return n;var t=x(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],!t(s,r,e))return i}else for(r in e)if(it.call(e,r)&&
(s=e[r],!t(s,r,e)))return i;return n}function p(e,t){var r,s;if(!e)return i;var o=e.length;r=-1;if(o===+o){if(ut.call(e)==wt)return-1<e.indexOf(t);for(;++r<o;)if(s=e[r],s===t)return n}else for(r in e)if(it.call(e,r)&&(s=e[r],s===t))return n;return i}function d(e){var t,n,r=[];if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r.push(n));return r}function v(e){var t,n,r=[];if(!e)return r;for(t in e)n=e[t],L(n)&&r.push(t);return r.sort(),r}function m(e,t,n){var r;if(!e)return e;t=x(t,n);for(r in e)n=e
[r],t(n,r,e);return e}function g(e){var t,n,r=e;if(!e)return e;for(var i=1,s=arguments.length;i<s;i++)if(r=arguments[i])for(t in r)n=r[t],e[t]=n;return e}function y(e){var t,n=[];if(!e)return n;for(t in e)it.call(e,t)&&n.push(t);return n}function b(e){var t,n,r={};if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r[n]=t);return r}function w(e){if(e&&e.__wrapped__)return e;if(!(this instanceof w))return new w(e);this.__wrapped__=e}function E(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1
;if(e<n||n===t)return-1}return r<i?-1:1}function S(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(ot.call(i)):n),this instanceof r?(C.prototype=e.prototype,s=new C,(i=e.apply(s,i))&&Tt[typeof i]?i:s):e.apply(s,i)}return r}function x(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:q}function T(e){return"\\"+Nt[e]}function N(e){return kt[e]}function C(){}function k(e){return Lt[e]}function L(e){return"function"==typeof
e}function A(e){var t=i;if(!e||"object"!=typeof e||isArguments(e))return t;var n=e.constructor;return!L(n)||n instanceof n?(m(e,function(e,n){t=n}),t===i||it.call(e,t)):t}function O(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Tt[typeof e]||Tt[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=ut.call(e);if(u!=ut.call(t))return i;switch(u){case vt:case mt:return+e==+t;case gt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case bt:case wt:return e==t+""}var a=Ct(e);if(!a&&u!=yt
)return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var f=n,u=0;s.push(e),o.push(t);if(a){u=e.length;if(f=u==t.length)for(;u--&&(f=O(e[u],t[u],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!L(a)||!(a instanceof a&&L(f)&&f instanceof f)))return i;for(var l in e)if(it.call(e,l)&&(u++,!it.call(t,l)||!O(e[l],t[l],s,o)))return i;for(l in t)if(it.call(t,l)&&!(u--))return i;return n}function M(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+s)t=x(t,n),f(e,function(
e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function _(e,t,n,r){var s=e?e.length:0,o=3>arguments.length;if(s!==+s)var u=At(e),s=u.length;return f(e,function(a,f,l){f=u?u[--s]:--s,n=o?(o=i,e[f]):t.call(r,n,e[f],f,l)}),n}function D(e,t,n){if(e)return t==r||n?e[0]:ot.call(e,0,t)}function P(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];Ct(s)?st.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("number"==typeof n)r=(0>n?ht(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 e?ot.call(e,t==r||n?1:t):[]}function j(e,t,n,r){var i=0,s=e?e.length:i;if(n){n=x(n,r);for(t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r}else for(;i<s;)r=i+s>>>1,e[r]<t?i=r+1:s=r;return i}function F(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=x(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>H(a,r))a.push(r),u.push(e[s]);return u}function I
(e,t){return xt||at&&2<arguments.length?at.call.apply(at,arguments):S(e,t,ot.call(arguments,2))}function q(e){return e}function R(e){f(v(e),function(t){var r=w[t]=e[t];w.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&st.apply(e,arguments),e=r.apply(w,e),this.__chain__&&(e=new w(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,U="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),z=Array.prototype,W=Object.prototype,
X=0,V=e._,$=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,J=/&(?:amp|lt|gt|quot|#x27);/g,K=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,Q=RegExp("^"+(W.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),G=/($^)/,Y=/[&<>"']/g,Z=/['\n\r\t\u2028\u2029\\]/g,et=Math.ceil,tt=z.concat,nt=Math.floor,rt=Q.test(rt=Object.getPrototypeOf)&&rt,it=W.hasOwnProperty,st=z.push,ot=z.slice,ut=W.toString,at=Q.test(at=ot.bind)&&at,ft=Q.test(ft=Array.isArray
)&&ft,lt=e.isFinite,ct=Q.test(ct=Object.keys)&&ct,ht=Math.max,pt=Math.min,dt=Math.random,vt="[object Boolean]",mt="[object Date]",gt="[object Number]",yt="[object Object]",bt="[object RegExp]",wt="[object String]",Et=e.clearTimeout,St=e.setTimeout,xt=at&&/\n|Opera/.test(at+ut.call(e.opera)),Tt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Nt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};w.templateSettings={escape:/<%-([\s\S]+?)%>/g
,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},w.isArguments=function(e){return"[object Arguments]"==ut.call(e)},w.isArguments(arguments)||(w.isArguments=function(e){return e?it.call(e,"callee"):i});var Ct=ft||function(e){return"[object Array]"==ut.call(e)};L(/x/)&&(L=function(e){return"[object Function]"==ut.call(e)});var W=rt?function(e){if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=rt(t))&&rt(n);return n?e==n||rt(e)==n&&!isArguments(e):A
(e)}:A,kt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},Lt=b(kt),At=ct?function(e){return e&&Tt[typeof e]?ct(e):[]}:y;w.VERSION="0.8.2",w.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},w.bind=I,w.bindAll=function(e){var t,n,r=e,i=e;if(!e)return i;n=arguments,t=0;var s=n.length;if(1<s){for(;++t<s;)i[n[t]]=I(i[n[t]],i);return i}for(t in r)n=r[t],L(n)&&(i[t]=I(n,i));return i},w.chain=function(e){return e=new w(e),e.__chain__=n,e},w.clone=function(
e){return e&&Tt[typeof e]?Ct(e)?ot.call(e):g({},e):e},w.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},w.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},w.contains=p,w.countBy=function(e,t,n){var r,i={};if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],r=t(r,n,e),it.call(i,r)?i[r]++:i[r]=1;else for(n in e)it.call(e,n)&&(r=e[n],r=t(r,n,e),it.call(i,r)?
i[r]++:i[r]=1);return i},w.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,Et(a),a=St(i,t),r&&(o=e.apply(u,s)),o}},w.defaults=function(e){var t,n,i=e;if(!e)return e;for(var s=1,o=arguments.length;s<o;s++)if(i=arguments[s])for(t in i)n=i[t],e[t]==r&&(e[t]=n);return e},w.defer=function(e){var n=ot.call(arguments,1);return St(function(){return e.apply(t,n)},1)},w.delay=function(e,n){var r=ot.call(arguments,2);return St
(function(){return e.apply(t,r)},n)},w.difference=function(e){for(var t=-1,n=e.length,r=tt.apply(z,arguments),i=[];++t<n;){var s=e[t];0>H(r,s,n)&&i.push(s)}return i},w.escape=function(e){return e==r?"":(e+"").replace(Y,N)},w.every=h,w.extend=g,w.filter=c,w.find=l,w.first=D,w.flatten=P,w.forEach=f,w.forIn=m,w.forOwn=function(e,t,n){var r;if(!e)return e;t=x(t,n);for(r in e)it.call(e,r)&&(n=e[r],t(n,r,e));return e},w.functions=v,w.groupBy=function(e,t,n){var r,i={};if(!e)return i;var t=x(t,n),s=e.length
,n=-1;if(s===+s)for(;++n<s;){r=e[n];var o=t(r,n,e);(it.call(i,o)?i[o]:i[o]=[]).push(r)}else for(n in e)it.call(e,n)&&(r=e[n],o=t(r,n,e),(it.call(i,o)?i[o]:i[o]=[]).push(r));return i},w.has=function(e,t){return e?it.call(e,t):i},w.identity=q,w.indexOf=H,w.initial=function(e,t,n){return e?ot.call(e,0,-(t==r||n?1:t)):[]},w.intersection=function(e){var t=arguments.length,n=-1,r=e.length,i=[];e:for(;++n<r;){var s=e[n];if(0>H(i,s)){for(var o=1;o<t;o++)if(0>H(arguments[o],s))continue e;i.push(s)}}return i
},w.invert=b,w.invoke=function(e,t){var n,r,i=e,s=e||[];if(!e)return s;var o=ot.call(arguments,2),u="function"==typeof t,a=i.length;n=-1;if(a===+a)for(s=Array(a);++n<a;)r=i[n],s[n]=(u?t:r[t]).apply(r,o);else for(n in s=[],i)it.call(i,n)&&(r=i[n],s.push((u?t:r[t]).apply(r,o)));return s},w.isArray=Ct,w.isBoolean=function(e){return e===n||e===i||ut.call(e)==vt},w.isDate=function(e){return ut.call(e)==mt},w.isElement=function(e){return e?1===e.nodeType:i},w.isEmpty=function(e){var t;if(!e)return n;var r=
ut.call(e),s=e.length;if(Ct(e)||r==wt||r==yt&&s===+s&&L(e.splice))return!s;for(t in e)if(it.call(e,t))return i;return n},w.isEqual=O,w.isFinite=function(e){return lt(e)&&ut.call(e)==gt},w.isFunction=L,w.isNaN=function(e){return ut.call(e)==gt&&e!=+e},w.isNull=function(e){return e===r},w.isNumber=function(e){return ut.call(e)==gt},w.isObject=function(e){return e?Tt[typeof e]:i},w.isPlainObject=W,w.isRegExp=function(e){return ut.call(e)==bt},w.isString=function(e){return ut.call(e)==wt},w.isUndefined=
function(e){return e===t},w.keys=At,w.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:ot.call(e,-t||i)}},w.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?ht(0,r+n):pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},w.map=a,w.max=M,w.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return it.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},w.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||s!==+
s)t=x(t,n),f(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},w.mixin=R,w.noConflict=function(){return e._=V,this},w.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},w.omit=function(e,t,n){var r,i,s=e,o={};if(!e)return o;var u="function"==typeof t;if(u)t=x(t,n);else var a=tt.apply(z,arguments);for(r in s)if(i=s[r],u?!t(i,r,e):0>H(a,r))o[r]=i;return o},w.once=function(e){var t,s=i;return function(){
return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},w.pairs=function(e){var t,n,r=[];if(!e)return r;for(t in e)it.call(e,t)&&(n=e[t],r.push([t,n]));return r},w.pick=function(e,t,n){var r,i,s=e,o={};if(!e)return o;if("function"!=typeof t){r=0,i=tt.apply(z,arguments);for(s=i.length;++r<s;){var u=i[r];u in e&&(o[u]=e[u])}}else for(r in t=x(t,n),s)i=s[r],t(i,r,e)&&(o[r]=i);return o},w.pluck=u,w.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+nt(dt()*((+t||0)-e+1))},w.range=function(
e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=ht(0,et((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},w.reduce=o,w.reduceRight=_,w.reject=function(e,t,n){var r,i=[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],!t(r,n,e)&&i.push(r);else for(n in e)it.call(e,n)&&(r=e[n],!t(r,n,e)&&i.push(r));return i},w.rest=B,w.result=function(e,t){var n=e?e[t]:r;return L(n)?e[t]():n},w.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return f(e,function(e){var r=nt(dt()*(++
t+1));n[t]=n[r],n[r]=e}),n},w.size=function(e){var t=e?e.length:0;return t===+t?t:At(e).length},w.some=s,w.sortBy=function(e,t,n){var r,i=e||[];if(!e)return i;var t=x(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]={a:t(r,n,e),b:n,c:r};else for(n in i=[],e)it.call(e,n)&&(r=e[n],i.push({a:t(r,n,e),b:n,c:r}));i.sort(E);for(s=i.length;s--;)i[s]=i[s].c;return i},w.sortedIndex=j,w.tap=function(e,t){return t(e),e},w.template=function(e,t,n){e||(e=""),n||(n={});var r,i,s=0,o=w.templateSettings
,u="__p += '",a=n.variable||o.variable,f=a;e.replace(RegExp((n.escape||o.escape||G).source+"|"+(n.interpolate||o.interpolate||G).source+"|"+(n.evaluate||o.evaluate||G).source+"|$","g"),function(t,n,i,o,a){u+=e.slice(s,a).replace(Z,T),u+=n?"'+__e("+n+")+'":o?"';"+o+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=o||$.test(n||i)),s=a+t.length}),u+="';",f||(a="obj",r?u="with("+a+"){"+u+"}":(n=RegExp("(\\(\\s*)"+a+"\\."+a+"\\b","g"),u=u.replace(K,"$&"+a+".").replace(n,"$1__d"))),u="function("+
a+"){"+(f?"":a+"||("+a+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(f?"":",__d="+a+"."+a+"||"+a)+";")+u+"return __p}";try{i=Function("_","return "+u)(w)}catch(l){throw l.source=u,l}return t?i(t):(i.source=u,i)},w.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(Et(u),a=r,s=e.apply(o,i)):u||(u=St(n,f)),s}},w.times=function(
e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},w.toArray=function(e){if(!e)return[];var t=e.length;return t===+t?"string"==typeof e?e.split(""):ot.call(e):d(e)},w.unescape=function(e){return e==r?"":(e+"").replace(J,k)},w.union=function(){for(var e=-1,t=tt.apply(z,arguments),n=t.length,r=[];++e<n;){var i=t[e];0>H(r,i)&&r.push(i)}return r},w.uniq=F,w.uniqueId=function(e){var t=X++;return e?e+t:t},w.values=d,w.where=function(e,t){var r,i,s=[];if(!e)return s;var o=[];m(t,function(
e,t){o.push(t)});var u=o.length,a=e.length;r=-1;if(a===+a)for(;++r<a;){i=e[r];for(var f=n,l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}else for(r in e)if(it.call(e,r)){i=e[r],f=n;for(l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}return s},w.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},w.wrap=function(e,t){return function(){var n=[e];return arguments.length&&st.apply(n,arguments),t.apply(this,n)}},w.zip=function(e){for(var t=-1
,n=e?M(u(arguments,"length")):0,r=Array(n);++t<n;)r[t]=u(arguments,t);return r},w.all=h,w.any=s,w.collect=a,w.detect=l,w.drop=B,w.each=f,w.foldl=o,w.foldr=_,w.head=D,w.include=p,w.inject=o,w.methods=v,w.select=c,w.tail=B,w.take=D,w.unique=F,R(w),w.prototype.chain=function(){return this.__chain__=n,this},w.prototype.value=function(){return this.__wrapped__},f("pop push reverse shift sort splice unshift".split(" "),function(e){var t=z[e];w.prototype[e]=function(){var e=this.__wrapped__;return t.apply
(e,arguments),this.__chain__&&(e=new w(e),e.__chain__=n),e}}),f(["concat","join","slice"],function(e){var t=z[e];w.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new w(e),e.__chain__=n),e}}),U?"object"==typeof module&&module&&module.exports==U?(module.exports=w)._=w:U._=w:e._=w})(this);

View File

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

View File

@@ -69,12 +69,9 @@
'intersection',
'last',
'lastIndexOf',
'max',
'min',
'object',
'range',
'rest',
'shuffle',
'sortedIndex',
'tail',
'take',
@@ -113,11 +110,14 @@
'inject',
'invoke',
'map',
'max',
'min',
'pluck',
'reduce',
'reduceRight',
'reject',
'select',
'shuffle',
'size',
'some',
'sortBy',
@@ -633,6 +633,24 @@
start();
});
});
asyncTest('`lodash underscore plus=clone`', function() {
var start = _.after(2, _.once(QUnit.start));
build(['-s', 'underscore', 'plus=clone'], function(source, filePath) {
var array = [{ 'value': 1 }],
basename = path.basename(filePath, '.js'),
context = createContext();
vm.runInContext(source, context);
var lodash = context._,
clone = lodash.clone(array, true);
deepEqual(array, clone, basename);
notEqual(array, clone, basename);
start();
});
});
}());
/*--------------------------------------------------------------------------*/
@@ -786,7 +804,7 @@
start = _.once(QUnit.start);
minify(source, {
'silent': true,
'isSilent': true,
'workingName': 'underscore.min',
'onComplete': function(result) {
var context = createContext();

View File

@@ -395,7 +395,7 @@
} else {
func(object, { 'a': 1 });
}
} catch(e) {console.log(e);
} catch(e) {
pass = false;
}
ok(pass);
@@ -646,6 +646,15 @@
var array = [1, 2, 3];
deepEqual(_.initial(array, 0), []);
});
test('should allow a falsey `array` argument', function() {
_.each(falsey, function(index, value) {
try {
var actual = index ? _.initial(value) : _.initial();
} catch(e) { }
deepEqual(actual, []);
})
});
}());
/*--------------------------------------------------------------------------*/
@@ -938,6 +947,19 @@
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.max and lodash.min object iteration');
_.each(['max', 'min'], function(methodName) {
var func = _[methodName];
test('lodash.' + methodName + ' should iterate an object', function() {
var actual = func({ 'a': 1, 'b': 2, 'c': 3 });
equal(actual, methodName == 'max' ? 3 : 1);
});
});
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.merge');
(function() {
@@ -982,7 +1004,6 @@
source.bar.b = source.foo.b;
var actual = _.merge(object, source);
ok(actual.bar.b === actual.foo.b && actual.foo.b.foo.c === actual.foo.b.foo.c.foo.b.foo.c);
});
@@ -1291,6 +1312,32 @@
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.rest');
(function() {
test('should allow a falsey `array` argument', function() {
_.each(falsey, function(index, value) {
try {
var actual = index ? _.rest(value) : _.rest();
} catch(e) { }
deepEqual(actual, []);
})
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.shuffle');
(function() {
test('should shuffle an object', function() {
var actual = _.shuffle({ 'a': 1, 'b': 2, 'c': 3 });
deepEqual(actual.sort(), [1, 2, 3]);
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('lodash.size');
(function() {
@@ -1550,6 +1597,31 @@
throttled();
});
asyncTest('should clear timeout when `func` is called', function() {
var now = new Date,
times = [];
var throttled = _.throttle(function() {
times.push(new Date - now);
}, 20);
setTimeout(throttled, 20);
setTimeout(throttled, 20);
setTimeout(throttled, 40);
setTimeout(throttled, 40);
setTimeout(function() {
var actual = _.every(times, function(value, index) {
return index
? (value - times[index - 1]) > 2
: true;
});
ok(actual);
QUnit.start();
}, 120);
});
}());
/*--------------------------------------------------------------------------*/
@@ -1702,11 +1774,67 @@
QUnit.module('lodash methods');
(function() {
test('should allow falsey arguments', function() {
var returnArrays = [
'filter',
'invoke',
'map',
'pluck',
'reject',
'shuffle',
'sortBy',
'toArray',
'where'
];
var funcs = _.without.apply(_, [_.functions(_)].concat([
'_',
'_iteratorTemplate',
'_shimKeys',
'after',
'bind',
'bindAll',
'compose',
'debounce',
'defer',
'delay',
'functions',
'memoize',
'once',
'partial',
'tap',
'throttle',
'wrap'
]));
_.each(funcs, function(methodName) {
var actual = [],
expected = _.times(falsey.length, function() { return []; }),
func = _[methodName],
pass = true;
_.each(falsey, function(value, index) {
try {
actual.push(index ? func(value) : func());
} catch(e) {
pass = false;
}
});
if (_.indexOf(returnArrays, methodName) > -1) {
deepEqual(actual, expected, '_.' + methodName + ' returns an array');
} else {
skipTest(falsey.length);
}
ok(pass, '_.' + methodName + ' allows falsey arguments');
});
});
test('should handle `null` `thisArg` arguments', function() {
var thisArg,
array = ['a'],
callback = function() { thisArg = this; },
useStrict = (function() { return this; }).call(null) === null;
expected = (function() { return this; }).call(null);
var funcs = [
'countBy',
@@ -1748,10 +1876,10 @@
func(array, callback, null);
}
if (useStrict) {
if (expected === null) {
deepEqual(thisArg, null, message);
} else {
equal(thisArg, window, message);
equal(thisArg, expected, message);
}
});
});

View File

@@ -183,22 +183,22 @@
// is automatically generated and assigned for you.
var Model = Backbone.Model = function(attributes, options) {
var defaults;
attributes || (attributes = {});
var attrs = attributes || {};
if (options && options.collection) this.collection = options.collection;
if (options && options.parse) attributes = this.parse(attributes);
if (defaults = _.result(this, 'defaults')) {
attributes = _.extend({}, defaults, attributes);
attrs = _.extend({}, defaults, attrs);
}
this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c');
this.changed = {};
this._silent = {};
this._changes = {};
this._pending = {};
this.set(attributes, {silent: true});
this.set(attrs, {silent: true});
// Reset change tracking.
this.changed = {};
this._silent = {};
this._changes = {};
this._pending = {};
this._previousAttributes = _.clone(this.attributes);
this.initialize.apply(this, arguments);
@@ -210,14 +210,18 @@
// A hash of attributes whose current and previous value differ.
changed: null,
// A hash of attributes that have silently changed since the last time
// `change` was called. Will become pending attributes on the next call.
_silent: null,
// A hash of attributes that have changed since the last time `change`
// was called.
_changes: null,
// A hash of attributes that have changed since the last `'change'` event
// A hash of attributes that have changed since the last `change` event
// began.
_pending: null,
// A hash of attributes with the current model state to determine if
// a `change` should be recorded within a nested `change` block.
_changing : null,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
idAttribute: 'id',
@@ -257,23 +261,22 @@
// Set a hash of model attributes on the object, firing `"change"` unless
// you choose to silence it.
set: function(key, value, options) {
var attrs, attr, val;
set: function(attrs, options) {
var attr, key, val;
if (attrs == null) return this;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (_.isObject(key) || key == null) {
attrs = key;
options = value;
} else {
attrs = {};
attrs[key] = value;
if (!_.isObject(attrs)) {
key = attrs;
(attrs = {})[key] = options;
options = arguments[2];
}
// Extract attributes and options.
options || (options = {});
if (!attrs) return this;
var silent = options && options.silent;
var unset = options && options.unset;
if (attrs instanceof Model) attrs = attrs.attributes;
if (options.unset) for (attr in attrs) attrs[attr] = void 0;
if (unset) for (attr in attrs) attrs[attr] = void 0;
// Run validation.
if (!this._validate(attrs, options)) return false;
@@ -281,7 +284,7 @@
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
var changes = options.changes = {};
var changing = this._changing;
var now = this.attributes;
var escaped = this._escapedAttributes;
var prev = this._previousAttributes || {};
@@ -291,27 +294,30 @@
val = attrs[attr];
// If the new and current value differ, record the change.
if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
if (!_.isEqual(now[attr], val) || (unset && _.has(now, attr))) {
delete escaped[attr];
(options.silent ? this._silent : changes)[attr] = true;
this._changes[attr] = true;
}
// Update or delete the current value.
options.unset ? delete now[attr] : now[attr] = val;
unset ? delete now[attr] : now[attr] = val;
// If the new and previous value differ, record the change. If not,
// then remove changes for this attribute.
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) {
this.changed[attr] = val;
if (!options.silent) this._pending[attr] = true;
if (!silent) this._pending[attr] = true;
} else {
delete this.changed[attr];
delete this._pending[attr];
if (!changing) delete this._changes[attr];
}
if (changing && _.isEqual(now[attr], changing[attr])) delete this._changes[attr];
}
// Fire the `"change"` events.
if (!options.silent) this.change(options);
if (!silent) this.change(options);
return this;
},
@@ -346,16 +352,14 @@
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save: function(key, value, options) {
var attrs, current, done;
save: function(attrs, options) {
var key, current, done;
// Handle both `("key", value)` and `({key: value})` -style calls.
if (_.isObject(key) || key == null) {
attrs = key;
options = value;
} else {
attrs = {};
attrs[key] = value;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (attrs != null && !_.isObject(attrs)) {
key = attrs;
(attrs = {})[key] = options;
options = arguments[2];
}
options = options ? _.clone(options) : {};
@@ -372,7 +376,7 @@
}
// Do not persist invalid models.
if (!attrs && !this.isValid()) return false;
if (!attrs && !this._validate(null, options)) return false;
// After a successful server-side save, the client is (optionally)
// updated with the server-side state.
@@ -455,18 +459,25 @@
// a `"change:attribute"` event for each changed attribute.
// Calling this will cause all objects observing the model to update.
change: function(options) {
options || (options = {});
var changing = this._changing;
this._changing = true;
var current = this._changing = {};
// Silent changes become pending changes.
for (var attr in this._silent) this._pending[attr] = true;
for (var attr in this._changes) this._pending[attr] = true;
// Silent changes are triggered.
var changes = _.extend({}, options.changes, this._silent);
this._silent = {};
// Trigger 'change:attr' for any new or silent changes.
var changes = this._changes;
this._changes = {};
// Set the correct state for this._changing values
var triggers = [];
for (var attr in changes) {
this.trigger('change:' + attr, this, this.get(attr), options);
current[attr] = this.get(attr);
triggers.push(attr);
}
for (var i=0, l=triggers.length; i < l; i++) {
this.trigger('change:' + triggers[i], this, current[triggers[i]], options);
}
if (changing) return this;
@@ -476,13 +487,13 @@
this.trigger('change', this, options);
// Pending and silent changes still remain.
for (var attr in this.changed) {
if (this._pending[attr] || this._silent[attr]) continue;
if (this._pending[attr] || this._changes[attr]) continue;
delete this.changed[attr];
}
this._previousAttributes = _.clone(this.attributes);
}
this._changing = false;
this._changing = null;
return this;
},
@@ -532,7 +543,7 @@
// returning `true` if all is well. If a specific `error` callback has
// been passed, call that instead of firing the general `"error"` event.
_validate: function(attrs, options) {
if (options.silent || !this.validate) return true;
if (options && options.silent || !this.validate) return true;
attrs = _.extend({}, this.attributes, attrs);
var error = this.validate(attrs, options);
if (!error) return true;
@@ -894,9 +905,10 @@
// Cached regular expressions for matching named param parts and splatted
// parts of route strings.
var optionalParam = /\((.*?)\)/g;
var namedParam = /:\w+/g;
var splatParam = /\*\w+/g;
var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
var escapeRegExp = /[-{}[\]+?.,\\^$|#\s]/g;
// Set up all inheritable **Backbone.Router** properties and methods.
_.extend(Router.prototype, Events, {
@@ -947,6 +959,7 @@
// against the current location hash.
_routeToRegExp: function(route) {
route = route.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, '([^\/]+)')
.replace(splatParam, '(.*?)');
return new RegExp('^' + route + '$');
@@ -1059,7 +1072,7 @@
// opened by a non-pushState browser.
this.fragment = fragment;
var loc = this.location;
var atRoot = (loc.pathname.replace(/[^/]$/, '$&/') === this.root) && !loc.search;
var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
// If we've started off with a route from a `pushState`-enabled browser,
// but we're currently in a browser that doesn't support it...
@@ -1073,7 +1086,7 @@
// in a browser where it could be `pushState`-based instead...
} else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
this.fragment = this.getHash().replace(routeStripper, '');
this.history.replaceState({}, document.title, this.root + this.fragment);
this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
}
if (!this.options.silent) return this.loadUrl();
@@ -1221,8 +1234,8 @@
// memory leaks.
dispose: function() {
this.undelegateEvents();
if (this.model) this.model.off(null, null, this);
if (this.collection) this.collection.off(null, null, this);
if (this.model && this.model.off) this.model.off(null, null, this);
if (this.collection && this.collection.off) this.collection.off(null, null, this);
return this;
},
@@ -1320,7 +1333,7 @@
if (this.className) attrs['class'] = _.result(this, 'className');
this.setElement(this.make(_.result(this, 'tagName'), attrs), false);
} else {
this.setElement(this.el, false);
this.setElement(_.result(this, 'el'), false);
}
}
@@ -1435,9 +1448,12 @@
child = function(){ parent.apply(this, arguments); };
}
// Add static properties to the constructor function, if supplied.
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
function Surrogate(){ this.constructor = child; };
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;
@@ -1445,9 +1461,6 @@
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Add static properties to the constructor function, if supplied.
_.extend(child, parent, staticProps);
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;

View File

@@ -740,9 +740,9 @@ $(document).ready(function() {
model.set({b: 2}, {silent: true});
});
model.set({b: 0});
deepEqual(changes, [0, 1, 1]);
deepEqual(changes, [0, 1]);
model.change();
deepEqual(changes, [0, 1, 1, 2, 1]);
deepEqual(changes, [0, 1, 2, 1]);
});
test("nested set multiple times", 1, function() {
@@ -816,4 +816,66 @@ $(document).ready(function() {
strictEqual(model.save(), false);
});
test("#1377 - Save without attrs triggers 'error'.", 1, function() {
var Model = Backbone.Model.extend({
url: '/test/',
sync: function(method, model, options){ options.success(); },
validate: function(){ return 'invalid'; }
});
var model = new Model({id: 1});
model.on('error', function(){ ok(true); });
model.save();
});
test("#1545 - `undefined` can be passed to a model constructor without coersion", function() {
var Model = Backbone.Model.extend({
defaults: { one: 1 },
initialize : function(attrs, opts) {
equal(attrs, undefined);
}
});
var emptyattrs = new Model();
var undefinedattrs = new Model(undefined);
});
asyncTest("#1478 - Model `save` does not trigger change on unchanged attributes", 0, function() {
var Model = Backbone.Model.extend({
sync: function(method, model, options) {
setTimeout(function(){
options.success();
start();
}, 0);
}
});
new Model({x: true})
.on('change:x', function(){ ok(false); })
.save(null, {wait: true});
});
test("#1664 - Changing from one value, silently to another, back to original does not trigger change.", 0, function() {
var model = new Backbone.Model({x:1});
model.on('change:x', function() { ok(false); });
model.set({x:2},{silent:true});
model.set({x:3},{silent:true});
model.set({x:1});
});
test("#1664 - multiple silent changes nested inside a change event", 2, function() {
var changes = [];
var model = new Backbone.Model();
model.on('change', 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']);
});
});

View File

@@ -69,6 +69,7 @@ $(document).ready(function() {
"contacts": "contacts",
"contacts/new": "newContact",
"contacts/:id": "loadContact",
"optional(/:item)": "optionalItem",
"splat/*args/end": "splat",
"*first/complex-:part/*rest": "complex",
":entity?*args": "query",
@@ -105,6 +106,10 @@ $(document).ready(function() {
this.contact = 'load';
},
optionalItem: function(arg){
this.arg = arg !== undefined ? arg : null;
},
splat : function(args) {
this.args = args;
},
@@ -199,6 +204,15 @@ $(document).ready(function() {
equal(router.args, 'long-list/of/splatted_99args');
});
test("routes (optional)", 2, function() {
location.replace('http://example.com#optional');
Backbone.history.checkUrl();
equal(router.arg, null);
location.replace('http://example.com#optional/thing');
Backbone.history.checkUrl();
equal(router.arg, 'thing');
});
test("routes (complex)", 3, function() {
location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
Backbone.history.checkUrl();
@@ -449,4 +463,22 @@ $(document).ready(function() {
});
});
test("#1695 - hashChange to pushState with search.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root?a=b#x/y');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(state, title, url){
strictEqual(url, '/root/x/y?a=b');
}
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
});

View File

@@ -305,6 +305,11 @@ $(document).ready(function() {
view.$el.click();
});
test("dispose with non Backbone objects", 0, function() {
var view = new Backbone.View({model: {}, collection: {}});
view.dispose();
});
test("view#remove calls dispose.", 1, function() {
var view = new Backbone.View();
@@ -312,4 +317,15 @@ $(document).ready(function() {
view.remove();
});
test("Provide function for el.", 1, function() {
var View = Backbone.View.extend({
el: function() {
return "<p><a></a></p>";
}
});
var view = new View;
ok(view.$el.is('p:has(a)'));
});
});

View File

@@ -8,7 +8,7 @@ require(dirname(__FILE__) . '/src/DocDown/Generator.php');
/**
* Generates Markdown from JSDoc entries in a given file.
*
*
* @param {Array} [$options=array()] The options array.
* @returns {String} The generated Markdown.
* @example

View File

@@ -22,10 +22,11 @@ class Alias {
* @param {String} $name The alias name.
* @param {Object} $owner The alias owner.
*/
public function __construct($name, $owner) {
public function __construct( $name, $owner ) {
$this->owner = $owner;
$this->_name = $name;
$this->_call = $owner->getCall();
$this->_category = $owner->getCategory();
$this->_desc = $owner->getDesc();
$this->_example = $owner->getExample();
$this->_lineNumber = $owner->getLineNumber();
@@ -65,6 +66,16 @@ class Alias {
return $this->_call;
}
/**
* Extracts the owner entry's `category` data.
*
* @memberOf Alias
* @returns {String} The owner entry's `category` data.
*/
public function getCategory() {
return $this->_category;
}
/**
* Extracts the owner entry's description.
*

View File

@@ -152,6 +152,27 @@ class Entry {
return $this->_call;
}
/**
* Extracts the entry's `category` data.
*
* @memberOf Entry
* @returns {String} The entry's `category` data.
*/
public function getCategory() {
if (isset($this->_category)) {
return $this->_category;
}
preg_match('#\* *@category\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = $this->getType() == 'Function' ? 'Methods' : 'Properties';
}
$this->_category = $result;
return $result;
}
/**
* Extracts the entry's description.
*

View File

@@ -7,6 +7,15 @@ require(dirname(__FILE__) . "/Entry.php");
*/
class Generator {
/**
* The HTML for the close tag.
*
* @static
* @memberOf Generator
* @type String
*/
public $closeTag = "\n<!-- /div -->\n";
/**
* An array of JSDoc entries.
*
@@ -15,6 +24,15 @@ class Generator {
*/
public $entries = array();
/**
* The HTML for the open tag.
*
* @static
* @memberOf Generator
* @type String
*/
public $openTag = "\n<!-- div -->\n";
/**
* An options array used to configure the generator.
*
@@ -24,7 +42,7 @@ class Generator {
public $options = array();
/**
* The entire file's source code.
* The file's source code.
*
* @memberOf Generator
* @type String
@@ -65,6 +83,9 @@ class Generator {
if (!isset($options['lang'])) {
$options['lang'] = 'js';
}
if (!isset($options['toc'])) {
$options['toc'] = 'properties';
}
$this->options = $options;
$this->source = str_replace(PHP_EOL, "\n", $options['source']);
@@ -86,7 +107,7 @@ class Generator {
* @param {String} $string The string to format.
* @returns {String} The formatted string.
*/
private static function format($string) {
private static function format( $string ) {
$counter = 0;
// tokenize inline code snippets
@@ -121,7 +142,7 @@ class Generator {
* @param {Array|Object} $object The template object.
* @returns {String} The modified string.
*/
private static function interpolate($string, $object) {
private static function interpolate( $string, $object ) {
preg_match_all('/#\{([^}]+)\}/', $string, $tokens);
$tokens = array_unique(array_pop($tokens));
@@ -149,6 +170,63 @@ class Generator {
/*--------------------------------------------------------------------------*/
/**
* Adds the given `$entries` to the `$result` array.
*
* @private
* @memberOf Generator
* @param {Array} $result The result array to modify.
* @param {Array} $entries The entries to add to the `$result`.
*/
private function addEntries( &$result, $entries ) {
foreach ($entries as $entry) {
// skip aliases
if ($entry->isAlias()) {
continue;
}
// name and description
array_push(
$result,
$this->openTag,
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [&#x24C8;](#{href} \"View in source\") [&#x24C9;][1]\n\n#{desc}", $entry)
);
// @alias
if (count($aliases = $entry->getAliases())) {
array_push($result, '', '#### Aliases');
foreach ($aliases as $index => $alias) {
$aliases[$index] = $alias->getName();
}
$result[] = '*' . implode(', ', $aliases) . '*';
}
// @param
if (count($params = $entry->getParams())) {
array_push($result, '', '#### Arguments');
foreach ($params as $index => $param) {
$result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
'desc' => $param[2],
'name' => $param[1],
'num' => $index + 1,
'type' => $param[0]
));
}
}
// @returns
if (count($returns = $entry->getReturns())) {
array_push(
$result, '',
'#### Returns',
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0]))
);
}
// @example
if ($example = $entry->getExample()) {
array_push($result, '', '#### Example', $example);
}
array_push($result, "\n* * *", $this->closeTag);
}
}
/**
* Resolves the entry's hash used to navigate the documentation.
*
@@ -204,9 +282,11 @@ class Generator {
*/
public function generate() {
$api = array();
$byCategory = $this->options['toc'] == 'categories';
$categories = array();
$closeTag = $this->closeTag;
$compiling = false;
$openTag = "\n<!-- div -->\n";
$closeTag = "\n<!-- /div -->\n";
$openTag = $this->openTag;
$result = array('# ' . $this->options['title']);
$toc = 'toc';
@@ -223,14 +303,14 @@ class Generator {
foreach ($members as $member) {
// create api category arrays
if (!isset($api[$member]) && $member) {
if ($member && !isset($api[$member])) {
// create temporary entry to be replaced later
$api[$member] = new Entry('', '', $entry->lang);
$api[$member] = new stdClass;
$api[$member]->static = array();
$api[$member]->plugin = array();
}
// append entry to api category
// append entry to api member
if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
!preg_match('/[=:]\s*(?:null|undefined)\s*[,;]?$/', $entry->entry))) {
@@ -261,6 +341,26 @@ class Generator {
}
}
// add properties to each entry
foreach ($api as $entry) {
$entry->hash = $this->getHash($entry);
$entry->href = $this->getLineUrl($entry);
$member = $entry->getMembers(0);
$member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $entry->getName();
$entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member);
// add properties to static and plugin sub-entries
foreach (array('static', 'plugin') as $kind) {
foreach ($entry->{$kind} as $subentry) {
$subentry->hash = $this->getHash($subentry);
$subentry->href = $this->getLineUrl($subentry);
$subentry->member = $member;
$subentry->separator = $this->getSeparator($subentry);
}
}
}
/*------------------------------------------------------------------------*/
// custom sort for root level entries
@@ -268,19 +368,19 @@ class Generator {
function sortCompare($a, $b) {
$score = array( 'a' => 0, 'b' => 0);
foreach (array( 'a' => $a, 'b' => $b) as $key => $value) {
// capitalized keys that represent constructor properties are last
// capitalized properties are last
if (preg_match('/[#.][A-Z]/', $value)) {
$score[$key] = 0;
}
// lowercase keys with prototype properties are next to last
// lowercase prototype properties are next to last
else if (preg_match('/#[a-z]/', $value)) {
$score[$key] = 1;
}
// lowercase keys with static properties next to first
// lowercase static properties next to first
else if (preg_match('/\.[a-z]/', $value)) {
$score[$key] = 2;
}
// lowercase keys with no properties are first
// root properties are first
else if (preg_match('/^[^#.]+$/', $value)) {
$score[$key] = 3;
}
@@ -310,48 +410,90 @@ class Generator {
/*------------------------------------------------------------------------*/
// add categories
foreach ($api as $entry) {
$categories[$entry->getCategory()][] = $entry;
foreach (array('static', 'plugin') as $kind) {
foreach ($entry->{$kind} as $subentry) {
$categories[$subentry->getCategory()][] = $subentry;
}
}
}
// sort categories
ksort($categories);
foreach(array('Methods', 'Properties') as $category) {
if (isset($categories[$category])) {
$entries = $categories[$category];
unset($categories[$category]);
$categories[$category] = $entries;
}
}
/*------------------------------------------------------------------------*/
// compile TOC
$result[] = $openTag;
foreach ($api as $key => $entry) {
$entry->hash = $this->getHash($entry);
$entry->href = $this->getLineUrl($entry);
$member = $entry->getMembers(0);
$member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $entry->getName();
$entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member);
$compiling = $compiling ? ($result[] = $closeTag) : true;
// assign TOC hash
if (count($result) == 2) {
$toc = $member;
}
// add root entry
array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
Generator::interpolate('* [`' . $member . '`](##{hash})', $entry)
);
// add static and plugin sub-entries
foreach (array('static', 'plugin') as $kind) {
if ($kind == 'plugin' && count($entry->plugin)) {
array_push(
$result,
$closeTag,
$openTag,
'## `' . $member . ($entry->isCtor() ? '.prototype`' : '`')
);
// compile TOC by categories
if ($byCategory) {
foreach ($categories as $category => $entries) {
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
foreach ($entry->{$kind} as $subentry) {
$subentry->hash = $this->getHash($subentry);
$subentry->href = $this->getLineUrl($subentry);
$subentry->member = $member;
$subentry->separator = $this->getSeparator($subentry);
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry);
// assign TOC hash
if (count($result) == 2) {
$toc = $category;
}
// add category
array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $category . '`'
);
// add entries
foreach ($entries as $entry) {
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $entry);
}
}
}
// compile TOC by namespace
else {
foreach ($api as $entry) {
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
$member = $entry->member . $entry->getName();
// assign TOC hash
if (count($result) == 2) {
$toc = $member;
}
// add root entry
array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
Generator::interpolate('* [`' . $member . '`](##{hash})', $entry)
);
// add static and plugin sub-entries
foreach (array('static', 'plugin') as $kind) {
if ($kind == 'plugin' && count($entry->plugin)) {
array_push(
$result,
$closeTag,
$openTag,
'## `' . $member . ($entry->isCtor() ? '.prototype`' : '`')
);
}
foreach ($entry->{$kind} as $subentry) {
$subentry->member = $member;
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry);
}
}
}
}
@@ -364,81 +506,51 @@ class Generator {
$compiling = false;
$result[] = $openTag;
foreach ($api as $entry) {
// skip aliases
if ($entry->isAlias()) {
continue;
}
// add root entry
$member = $entry->member . $entry->getName();
$compiling = $compiling ? ($result[] = $closeTag) : true;
array_push($result, $openTag, '## `' . $member . '`');
foreach (array($entry, 'static', 'plugin') as $kind) {
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
// title
if ($kind != 'static' && $entry->getType() != 'Object' &&
count($subentries) && $subentries[0] != $kind) {
if ($kind == 'plugin') {
$result[] = $closeTag;
}
array_push(
$result,
$openTag,
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
);
if ($byCategory) {
foreach ($categories as $category => $entries) {
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
if ($category != 'Methods' && $category != 'Properties') {
$category = '“' . $category . '” Methods';
}
array_push($result, $openTag, '## `' . $category . '`');
$this->addEntries($result, $entries);
}
}
else {
foreach ($api as $entry) {
// skip aliases
if ($entry->isAlias()) {
continue;
}
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
// add root entry name
$member = $entry->member . $entry->getName();
array_push($result, $openTag, '## `' . $member . '`');
// body
foreach ($subentries as $subentry) {
// skip aliases
if ($subentry->isAlias()) {
continue;
}
foreach (array($entry, 'static', 'plugin') as $kind) {
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
// description
array_push(
$result,
$openTag,
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [&#x24C8;](#{href} \"View in source\") [&#x24C9;][1]\n\n#{desc}", $subentry)
);
// @alias
if (count($aliases = $subentry->getAliases())) {
array_push($result, '', '#### Aliases');
foreach ($aliases as $index => $alias) {
$aliases[$index] = $alias->getName();
// add sub-entry name
if ($kind != 'static' && $entry->getType() != 'Object' &&
count($subentries) && $subentries[0] != $kind) {
if ($kind == 'plugin') {
$result[] = $closeTag;
}
$result[] = '*' . implode(', ', $aliases) . '*';
}
// @param
if (count($params = $subentry->getParams())) {
array_push($result, '', '#### Arguments');
foreach ($params as $index => $param) {
$result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
'desc' => $param[2],
'name' => $param[1],
'num' => $index + 1,
'type' => $param[0]
));
}
}
// @returns
if (count($returns = $subentry->getReturns())) {
array_push(
$result, '',
'#### Returns',
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0]))
$result,
$openTag,
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
);
}
// @example
if ($example = $subentry->getExample()) {
array_push($result, '', '#### Example', $example);
}
array_push($result, "\n* * *", $closeTag);
$this->addEntries($result, $subentries);
}
}
}

View File

@@ -1,4 +1,4 @@
[QUnit](http://qunitjs.com) - A JavaScript Unit Testing framework.
[QUnit](http://docs.jquery.com/QUnit) - A JavaScript Unit Testing framework.
================================
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
@@ -35,8 +35,7 @@ the change, run `grunt` to lint and test it, then commit, push and create a pull
Include some background for the change in the commit message and `Fixes #nnn`, referring
to the issue number you're addressing.
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. That gives you a global
grunt binary. For additional grunt tasks, also run `npm install`.
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`.
Releases
--------
@@ -48,12 +47,3 @@ 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):
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
Then update /var/www/html/code.jquery.com/index.html and purge it with:
curl -s http://code.origin.jquery.com/?reload

View File

@@ -1,11 +1,11 @@
/**
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
* QUnit v1.9.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
* http://docs.jquery.com/QUnit
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
/** Font Family and Sizes */
@@ -20,7 +20,7 @@
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
margin: 0;
padding: 0;
}
@@ -67,7 +67,6 @@
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
overflow: hidden;
}
#qunit-userAgent {
@@ -77,9 +76,6 @@
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
#qunit-modulefilter-container {
float: right;
}
/** Tests: Pass/Fail */

View File

@@ -1,11 +1,11 @@
/**
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
* QUnit v1.9.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
* http://docs.jquery.com/QUnit
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
(function( window ) {
@@ -17,8 +17,6 @@ var QUnit,
fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty,
// Keep a local reference to Date (GH-283)
Date = window.Date,
defined = {
setTimeout: typeof window.setTimeout !== "undefined",
sessionStorage: (function() {
@@ -306,8 +304,7 @@ QUnit = {
// call on start of module test to prepend name to all tests
module: function( name, testEnvironment ) {
config.currentModule = name;
config.currentModuleTestEnvironment = testEnvironment;
config.modules[name] = true;
config.currentModuleTestEnviroment = testEnvironment;
},
asyncTest: function( testName, expected, callback ) {
@@ -339,7 +336,7 @@ QUnit = {
async: async,
callback: callback,
module: config.currentModule,
moduleTestEnvironment: config.currentModuleTestEnvironment,
moduleTestEnvironment: config.currentModuleTestEnviroment,
stack: sourceFromStacktrace( 2 )
});
@@ -352,11 +349,7 @@ QUnit = {
// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
expect: function( asserts ) {
if (arguments.length === 1) {
config.current.expected = asserts;
} else {
return config.current.expected;
}
config.current.expected = asserts;
},
start: function( count ) {
@@ -422,8 +415,6 @@ QUnit.assert = {
var source,
details = {
module: config.current.module,
name: config.current.testName,
result: result,
message: msg
};
@@ -609,9 +600,6 @@ config = {
}
],
// Set of all modules.
modules: {},
// logging callback queues
begin: [],
done: [],
@@ -722,10 +710,17 @@ extend( QUnit, {
},
// Resets the test setup. Useful for tests that modify the DOM.
// If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
reset: function() {
var fixture = id( "qunit-fixture" );
if ( fixture ) {
fixture.innerHTML = config.fixture;
var fixture;
if ( window.jQuery ) {
jQuery( "#qunit-fixture" ).html( config.fixture );
} else {
fixture = id( "qunit-fixture" );
if ( fixture ) {
fixture.innerHTML = config.fixture;
}
}
},
@@ -786,8 +781,6 @@ extend( QUnit, {
var output, source,
details = {
module: config.current.module,
name: config.current.testName,
result: result,
message: message,
actual: actual,
@@ -833,8 +826,6 @@ extend( QUnit, {
var output,
details = {
module: config.current.module,
name: config.current.testName,
result: false,
message: message
};
@@ -925,9 +916,7 @@ 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, urlConfigCheckboxes,
urlConfigHtml = "",
oldconfig = extend( {}, config );
@@ -951,15 +940,6 @@ QUnit.load = function() {
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>";
}
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + ( config.module === undefined ? "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 += "</select>";
// `userAgent` initialized at top of scope
userAgent = id( "qunit-userAgent" );
if ( userAgent ) {
@@ -1022,19 +1002,6 @@ QUnit.load = function() {
window.location = QUnit.url( params );
});
toolbar.appendChild( urlConfigCheckboxes );
if (numModules > 1) {
moduleFilter = document.createElement( 'span' );
moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
moduleFilter.innerHTML = moduleFilterHtml;
addEvent( moduleFilter, "change", function() {
var selectBox = moduleFilter.getElementsByTagName("select")[0],
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
});
toolbar.appendChild(moduleFilter);
}
}
// `main` initialized at top of scope
@@ -1072,9 +1039,9 @@ window.onerror = function ( error, filePath, linerNr ) {
}
QUnit.pushFailure( error, filePath + ":" + linerNr );
} else {
QUnit.test( "global failure", extend( function() {
QUnit.test( "global failure", function() {
QUnit.pushFailure( error, filePath + ":" + linerNr );
}, { validTest: validTest } ) );
});
}
return false;
}
@@ -1141,11 +1108,6 @@ function done() {
}
}
// scroll back to top to show results
if ( window.scrollTo ) {
window.scrollTo(0, 0);
}
runLoggingCallbacks( "done", QUnit, {
failed: config.stats.bad,
passed: passed,
@@ -1161,12 +1123,6 @@ function validTest( test ) {
module = config.module && config.module.toLowerCase(),
fullName = (test.module + ": " + test.testName).toLowerCase();
// Internally-generated tests are always valid
if ( test.callback && test.callback.validTest === validTest ) {
delete test.callback.validTest;
return true;
}
if ( config.testNumber ) {
return test.testNumber === config.testNumber;
}
@@ -1448,8 +1404,7 @@ QUnit.equiv = (function() {
a.global === b.global &&
// (gmi) ...
a.ignoreCase === b.ignoreCase &&
a.multiline === b.multiline &&
a.sticky === b.sticky;
a.multiline === b.multiline;
},
// - skip when the property is a method of an instance (OOP)

View File

@@ -1,5 +1,5 @@
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.0.6 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* @license RequireJS 2.1.0 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
*/
@@ -12,7 +12,7 @@ var requirejs, require, define;
(function (global) {
var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.0.6',
version = '2.1.0',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/,
@@ -147,41 +147,6 @@ var requirejs, require, define;
return g;
}
function makeContextModuleFunc(func, relMap, enableBuildCallback) {
return function () {
//A version of a require function that passes a moduleName
//value for items that may need to
//look up paths relative to the moduleName
var args = aps.call(arguments, 0), lastArg;
if (enableBuildCallback &&
isFunction((lastArg = args[args.length - 1]))) {
lastArg.__requireJsBuild = true;
}
args.push(relMap);
return func.apply(null, args);
};
}
function addRequireMethods(req, context, relMap) {
each([
['toUrl'],
['undef'],
['defined', 'requireDefined'],
['specified', 'requireSpecified']
], function (item) {
var prop = item[1] || item[0];
req[item[0]] = context ? makeContextModuleFunc(context[prop], relMap) :
//If no context, then use default context. Reference from
//contexts instead of early binding to default context, so
//that during builds, the latest instance of the default
//context with its config gets used.
function () {
var ctx = contexts[defContextName];
return ctx[prop].apply(ctx, arguments);
};
});
}
/**
* Constructs an error with a pointer to an URL with more information.
* @param {String} id the error ID that maps to an ID on a web page.
@@ -238,12 +203,7 @@ var requirejs, require, define;
defined = {},
urlFetched = {},
requireCounter = 1,
unnormalizedCounter = 1,
//Used to track the order in which modules
//should be executed, by the order they
//load. Important for consistent cycle resolution
//behavior.
waitAry = [];
unnormalizedCounter = 1;
/**
* Trims the . and .. from an array of path segments.
@@ -405,12 +365,25 @@ var requirejs, require, define;
//Pop off the first array value, since it failed, and
//retry
pathConfig.shift();
context.undef(id);
context.require.undef(id);
context.require([id]);
return true;
}
}
//Turns a plugin!resource to [plugin, resource]
//with the plugin being undefined if the name
//did not have a plugin prefix.
function splitPrefix(name) {
var prefix,
index = name ? name.indexOf('!') : -1;
if (index > -1) {
prefix = name.substring(0, index);
name = name.substring(index + 1, name.length);
}
return [prefix, name];
}
/**
* Creates a module mapping that includes plugin prefix, module
* name, and path. If parentModuleMap is provided it will
@@ -427,8 +400,7 @@ var requirejs, require, define;
* @returns {Object}
*/
function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
var url, pluginModule, suffix,
index = name ? name.indexOf('!') : -1,
var url, pluginModule, suffix, nameParts,
prefix = null,
parentName = parentModuleMap ? parentModuleMap.name : null,
originalName = name,
@@ -442,10 +414,9 @@ var requirejs, require, define;
name = '_@r' + (requireCounter += 1);
}
if (index !== -1) {
prefix = name.substring(0, index);
name = name.substring(index + 1, name.length);
}
nameParts = splitPrefix(name);
prefix = nameParts[0];
name = nameParts[1];
if (prefix) {
prefix = normalize(prefix, parentName, applyMap);
@@ -466,6 +437,15 @@ var requirejs, require, define;
} else {
//A regular module.
normalizedName = normalize(name, parentName, applyMap);
//Normalized name may be a plugin ID due to map config
//application in normalize. The map config values must
//already be normalized, so do not need to redo that part.
nameParts = splitPrefix(normalizedName);
prefix = nameParts[0];
normalizedName = nameParts[1];
isNormalized = true;
url = context.nameToUrl(normalizedName);
}
}
@@ -557,148 +537,71 @@ var requirejs, require, define;
}
}
/**
* Helper function that creates a require function object to give to
* modules that ask for it as a dependency. It needs to be specific
* per module because of the implication of path mappings that may
* need to be relative to the module name.
*/
function makeRequire(mod, enableBuildCallback, altRequire) {
var relMap = mod && mod.map,
modRequire = makeContextModuleFunc(altRequire || context.require,
relMap,
enableBuildCallback);
addRequireMethods(modRequire, context, relMap);
modRequire.isBrowser = isBrowser;
return modRequire;
}
handlers = {
'require': function (mod) {
return makeRequire(mod);
if (mod.require) {
return mod.require;
} else {
return (mod.require = context.makeRequire(mod.map));
}
},
'exports': function (mod) {
mod.usingExports = true;
if (mod.map.isDefine) {
return (mod.exports = defined[mod.map.id] = {});
if (mod.exports) {
return mod.exports;
} else {
return (mod.exports = defined[mod.map.id] = {});
}
}
},
'module': function (mod) {
return (mod.module = {
id: mod.map.id,
uri: mod.map.url,
config: function () {
return (config.config && config.config[mod.map.id]) || {};
},
exports: defined[mod.map.id]
});
if (mod.module) {
return mod.module;
} else {
return (mod.module = {
id: mod.map.id,
uri: mod.map.url,
config: function () {
return (config.config && config.config[mod.map.id]) || {};
},
exports: defined[mod.map.id]
});
}
}
};
function removeWaiting(id) {
function cleanRegistry(id) {
//Clean up machinery used for waiting modules.
delete registry[id];
each(waitAry, function (mod, i) {
if (mod.map.id === id) {
waitAry.splice(i, 1);
if (!mod.defined) {
context.waitCount -= 1;
}
return true;
}
});
}
function findCycle(mod, traced, processed) {
var id = mod.map.id,
depArray = mod.depMaps,
foundModule;
function breakCycle(mod, traced, processed) {
var id = mod.map.id;
//Do not bother with unitialized modules or not yet enabled
//modules.
if (!mod.inited) {
return;
}
if (mod.error) {
mod.emit('error', mod.error);
} else {
traced[id] = true;
each(mod.depMaps, function (depMap, i) {
var depId = depMap.id,
dep = registry[depId];
//Found the cycle.
if (traced[id]) {
return mod;
}
traced[id] = true;
//Trace through the dependencies.
each(depArray, function (depMap) {
var depId = depMap.id,
depMod = registry[depId];
if (!depMod || processed[depId] ||
!depMod.inited || !depMod.enabled) {
return;
}
return (foundModule = findCycle(depMod, traced, processed));
});
processed[id] = true;
return foundModule;
}
function forceExec(mod, traced, uninited) {
var id = mod.map.id,
depArray = mod.depMaps;
if (!mod.inited || !mod.map.isDefine) {
return;
}
if (traced[id]) {
return defined[id];
}
traced[id] = mod;
each(depArray, function (depMap) {
var depId = depMap.id,
depMod = registry[depId],
value;
if (handlers[depId]) {
return;
}
if (depMod) {
if (!depMod.inited || !depMod.enabled) {
//Dependency is not inited,
//so this module cannot be
//given a forced value yet.
uninited[id] = true;
return;
//Only force things that have not completed
//being defined, so still in the registry,
//and only if it has not been matched up
//in the module already.
if (dep && !mod.depMatched[i] && !processed[depId]) {
if (traced[depId]) {
mod.defineDep(i, defined[depId]);
mod.check(); //pass false?
} else {
breakCycle(dep, traced, processed);
}
}
//Get the value for the current dependency
value = forceExec(depMod, traced, uninited);
//Even with forcing it may not be done,
//in particular if the module is waiting
//on a plugin resource.
if (!uninited[depId]) {
mod.defineDepById(depId, value);
}
}
});
mod.check(true);
return defined[id];
}
function modCheck(mod) {
mod.check();
});
processed[id] = true;
}
}
function checkLoaded() {
@@ -707,6 +610,7 @@ var requirejs, require, define;
//It is possible to disable the wait interval by using waitSeconds of 0.
expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
noLoads = [],
reqCalls = [],
stillLoading = false,
needCycleCheck = true;
@@ -727,6 +631,10 @@ var requirejs, require, define;
return;
}
if (!map.isDefine) {
reqCalls.push(mod);
}
if (!mod.error) {
//If the module should be executed, and it has not
//been inited and time is up, remember it.
@@ -761,31 +669,9 @@ var requirejs, require, define;
//Not expired, check for a cycle.
if (needCycleCheck) {
each(waitAry, function (mod) {
if (mod.defined) {
return;
}
var cycleMod = findCycle(mod, {}, {}),
traced = {};
if (cycleMod) {
forceExec(cycleMod, traced, {});
//traced modules may have been
//removed from the registry, but
//their listeners still need to
//be called.
eachProp(traced, modCheck);
}
each(reqCalls, function (mod) {
breakCycle(mod, {}, {});
});
//Now that dependencies have
//been satisfied, trigger the
//completion check that then
//notifies listeners.
eachProp(registry, modCheck);
}
//If still waiting on loads, and the waiting load is something
@@ -851,7 +737,6 @@ var requirejs, require, define;
//doing a direct modification of the depMaps array
//would affect that config.
this.depMaps = depMaps && depMaps.slice(0);
this.depMaps.rjsSkipMap = depMaps.rjsSkipMap;
this.errback = errback;
@@ -873,20 +758,6 @@ var requirejs, require, define;
}
},
defineDepById: function (id, depExports) {
var i;
//Find the index for this dependency.
each(this.depMaps, function (map, index) {
if (map.id === id) {
i = index;
return true;
}
});
return this.defineDep(i, depExports);
},
defineDep: function (i, depExports) {
//Because of cycles, defined callback for a given
//export can be called more than once.
@@ -910,7 +781,9 @@ var requirejs, require, define;
//If the manager is for a plugin managed resource,
//ask the plugin to load it now.
if (this.shim) {
makeRequire(this, true)(this.shim.deps || [], bind(this, function () {
context.makeRequire(this.map, {
enableBuildCallback: true
})(this.shim.deps || [], bind(this, function () {
return map.prefix ? this.callPlugin() : this.load();
}));
} else {
@@ -931,11 +804,9 @@ var requirejs, require, define;
/**
* Checks is the module is ready to define itself, and if so,
* define it. If the silent argument is true, then it will just
* define, but not notify listeners, and not ask for a context-wide
* check of all loaded modules. That is useful for cycle breaking.
* define it.
*/
check: function (silent) {
check: function () {
if (!this.enabled || this.enabling) {
return;
}
@@ -1013,11 +884,6 @@ var requirejs, require, define;
delete registry[id];
this.defined = true;
context.waitCount -= 1;
if (context.waitCount === 0) {
//Clear the wait array used for cycles.
waitAry = [];
}
}
//Finished the define stage. Allow calling check again
@@ -1025,25 +891,33 @@ var requirejs, require, define;
//cycle.
this.defining = false;
if (!silent) {
if (this.defined && !this.defineEmitted) {
this.defineEmitted = true;
this.emit('defined', this.exports);
this.defineEmitComplete = true;
}
if (this.defined && !this.defineEmitted) {
this.defineEmitted = true;
this.emit('defined', this.exports);
this.defineEmitComplete = true;
}
}
},
callPlugin: function () {
var map = this.map,
id = map.id,
pluginMap = makeModuleMap(map.prefix, null, false, true);
//Map already normalized the prefix.
pluginMap = makeModuleMap(map.prefix);
//Mark this as a dependency for this plugin, so it
//can be traced for cycles.
this.depMaps.push(pluginMap);
on(pluginMap, 'defined', bind(this, function (plugin) {
var load, normalizedMap, normalizedMod,
name = this.map.name,
parentName = this.map.parentMap ? this.map.parentMap.name : null;
parentName = this.map.parentMap ? this.map.parentMap.name : null,
localRequire = context.makeRequire(map.parentMap, {
enableBuildCallback: true,
skipMap: true
});
//If current map is not normalized, wait for that
//normalized name to load instead of continuing.
@@ -1055,10 +929,10 @@ var requirejs, require, define;
}) || '';
}
//prefix and name should already be normalized, no need
//for applying map config again either.
normalizedMap = makeModuleMap(map.prefix + '!' + name,
this.map.parentMap,
false,
true);
this.map.parentMap);
on(normalizedMap,
'defined', bind(this, function (value) {
this.init([], function () { return value; }, null, {
@@ -1066,8 +940,13 @@ var requirejs, require, define;
ignore: true
});
}));
normalizedMod = registry[normalizedMap.id];
if (normalizedMod) {
//Mark this as a dependency for this plugin, so it
//can be traced for cycles.
this.depMaps.push(normalizedMap);
if (this.events.error) {
normalizedMod.on('error', bind(this, function (err) {
this.emit('error', err);
@@ -1094,7 +973,7 @@ var requirejs, require, define;
//since they will never be resolved otherwise now.
eachProp(registry, function (mod) {
if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
removeWaiting(mod.map.id);
cleanRegistry(mod.map.id);
}
});
@@ -1103,9 +982,19 @@ var requirejs, require, define;
//Allow plugins to load other code without having to know the
//context or how to 'complete' the load.
load.fromText = function (moduleName, text) {
load.fromText = bind(this, function (text, textAlt) {
/*jslint evil: true */
var hasInteractive = useInteractive;
var moduleName = map.name,
moduleMap = makeModuleMap(moduleName),
hasInteractive = useInteractive;
//As of 2.1.0, support just passing the text, to reinforce
//fromText only being called once per resource. Still
//support old style of passing moduleName but discard
//that moduleName in favor of the internal ref.
if (textAlt) {
text = textAlt;
}
//Turn off interactive script matching for IE for any define
//calls in the text, then turn it back on at the end.
@@ -1115,25 +1004,35 @@ var requirejs, require, define;
//Prime the system by creating a module instance for
//it.
getModule(makeModuleMap(moduleName));
getModule(moduleMap);
req.exec(text);
try {
req.exec(text);
} catch (e) {
throw new Error('fromText eval for ' + moduleName +
' failed: ' + e);
}
if (hasInteractive) {
useInteractive = true;
}
//Mark this as a dependency for the plugin
//resource
this.depMaps.push(moduleMap);
//Support anonymous modules.
context.completeLoad(moduleName);
};
//Bind the value of that module to the value for this
//resource ID.
localRequire([moduleName], load);
});
//Use parentName here since the plugin's name is not reliable,
//could be some weird string with no path that actually wants to
//reference the parentName's path.
plugin.load(map.name, makeRequire(map.parentMap, true, function (deps, cb, er) {
deps.rjsSkipMap = true;
return context.require(deps, cb, er);
}), load, config);
plugin.load(map.name, localRequire, load, config);
}));
context.enable(pluginMap, this);
@@ -1143,12 +1042,6 @@ var requirejs, require, define;
enable: function () {
this.enabled = true;
if (!this.waitPushed) {
waitAry.push(this);
context.waitCount += 1;
this.waitPushed = true;
}
//Set flag mentioning that the module is enabling,
//so that immediate calls to the defined callbacks
//for dependencies do not trigger inadvertent load
@@ -1165,7 +1058,7 @@ var requirejs, require, define;
depMap = makeModuleMap(depMap,
(this.map.isDefine ? this.map : this.map.parentMap),
false,
!this.depMaps.rjsSkipMap);
!this.skipMap);
this.depMaps[i] = depMap;
handler = handlers[depMap.id];
@@ -1227,7 +1120,7 @@ var requirejs, require, define;
if (name === 'error') {
//Now that the error handler was triggered, remove
//the listeners, since this broken Module instance
//can stay around for a while in the registry/waitAry.
//can stay around for a while in the registry.
delete this.events[name];
}
}
@@ -1274,16 +1167,16 @@ var requirejs, require, define;
};
}
return (context = {
context = {
config: config,
contextName: contextName,
registry: registry,
defined: defined,
urlFetched: urlFetched,
waitCount: 0,
defQueue: defQueue,
Module: Module,
makeModuleMap: makeModuleMap,
nextTick: req.nextTick,
/**
* Set a configuration for the context.
@@ -1325,8 +1218,8 @@ var requirejs, require, define;
deps: value
};
}
if (value.exports && !value.exports.__buildReady) {
value.exports = context.makeShimExports(value.exports);
if (value.exports && !value.exportsFn) {
value.exportsFn = context.makeShimExports(value);
}
shim[id] = value;
});
@@ -1381,125 +1274,152 @@ var requirejs, require, define;
}
},
makeShimExports: function (exports) {
var func;
if (typeof exports === 'string') {
func = function () {
return getGlobal(exports);
};
//Save the exports for use in nodefine checking.
func.exports = exports;
return func;
} else {
return function () {
return exports.apply(global, arguments);
};
makeShimExports: function (value) {
function fn() {
var ret;
if (value.init) {
ret = value.init.apply(global, arguments);
}
return ret || getGlobal(value.exports);
}
return fn;
},
requireDefined: function (id, relMap) {
return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
},
makeRequire: function (relMap, options) {
options = options || {};
requireSpecified: function (id, relMap) {
id = makeModuleMap(id, relMap, false, true).id;
return hasProp(defined, id) || hasProp(registry, id);
},
function require(deps, callback, errback) {
var id, map, requireMod, args;
require: function (deps, callback, errback, relMap) {
var moduleName, id, map, requireMod, args;
if (typeof deps === 'string') {
if (isFunction(callback)) {
//Invalid call
return onError(makeError('requireargs', 'Invalid require call'), errback);
if (options.enableBuildCallback && callback && isFunction(callback)) {
callback.__requireJsBuild = true;
}
//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
//In this case deps is the moduleName and callback is
//the relMap
if (req.get) {
return req.get(context, deps, callback);
if (typeof deps === 'string') {
if (isFunction(callback)) {
//Invalid call
return onError(makeError('requireargs', 'Invalid require call'), errback);
}
//If require|exports|module are requested, get the
//value for them from the special handlers. Caveat:
//this only works while module is being defined.
if (relMap && handlers[deps]) {
return handlers[deps](registry[relMap.id]);
}
//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
if (req.get) {
return req.get(context, deps, relMap);
}
//Normalize module name, if it contains . or ..
map = makeModuleMap(deps, relMap, false, true);
id = map.id;
if (!hasProp(defined, id)) {
return onError(makeError('notloaded', 'Module name "' +
id +
'" has not been loaded yet for context: ' +
contextName +
(relMap ? '' : '. Use require([])')));
}
return defined[id];
}
//Just return the module wanted. In this scenario, the
//second arg (if passed) is just the relMap.
moduleName = deps;
relMap = callback;
//Any defined modules in the global queue, intake them now.
takeGlobalQueue();
//Normalize module name, if it contains . or ..
map = makeModuleMap(moduleName, relMap, false, true);
id = map.id;
if (!hasProp(defined, id)) {
return onError(makeError('notloaded', 'Module name "' +
id +
'" has not been loaded yet for context: ' +
contextName));
//Make sure any remaining defQueue items get properly processed.
while (defQueue.length) {
args = defQueue.shift();
if (args[0] === null) {
return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
} else {
//args are id, deps, factory. Should be normalized by the
//define() function.
callGetModule(args);
}
}
return defined[id];
//Mark all the dependencies as needing to be loaded.
context.nextTick(function () {
requireMod = getModule(makeModuleMap(null, relMap));
//Store if map config should be applied to this require
//call for dependencies.
requireMod.skipMap = options.skipMap;
requireMod.init(deps, callback, errback, {
enabled: true
});
checkLoaded();
});
return require;
}
//Callback require. Normalize args. if callback or errback is
//not a function, it means it is a relMap. Test errback first.
if (errback && !isFunction(errback)) {
relMap = errback;
errback = undefined;
}
if (callback && !isFunction(callback)) {
relMap = callback;
callback = undefined;
}
mixin(require, {
isBrowser: isBrowser,
//Any defined modules in the global queue, intake them now.
takeGlobalQueue();
/**
* Converts a module name + .extension into an URL path.
* *Requires* the use of a module name. It does not support using
* plain URLs like nameToUrl.
*/
toUrl: function (moduleNamePlusExt) {
var index = moduleNamePlusExt.lastIndexOf('.'),
ext = null;
//Make sure any remaining defQueue items get properly processed.
while (defQueue.length) {
args = defQueue.shift();
if (args[0] === null) {
return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
} else {
//args are id, deps, factory. Should be normalized by the
//define() function.
callGetModule(args);
if (index !== -1) {
ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
}
return context.nameToUrl(normalize(moduleNamePlusExt,
relMap && relMap.id, true), ext);
},
defined: function (id) {
return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
},
specified: function (id) {
id = makeModuleMap(id, relMap, false, true).id;
return hasProp(defined, id) || hasProp(registry, id);
}
}
//Mark all the dependencies as needing to be loaded.
requireMod = getModule(makeModuleMap(null, relMap));
requireMod.init(deps, callback, errback, {
enabled: true
});
checkLoaded();
//Only allow undef on top level require calls
if (!relMap) {
require.undef = function (id) {
//Bind any waiting define() calls to this context,
//fix for #408
takeGlobalQueue();
return context.require;
},
var map = makeModuleMap(id, relMap, true),
mod = registry[id];
undef: function (id) {
//Bind any waiting define() calls to this context,
//fix for #408
takeGlobalQueue();
delete defined[id];
delete urlFetched[map.url];
delete undefEvents[id];
var map = makeModuleMap(id, null, true),
mod = registry[id];
if (mod) {
//Hold on to listeners in case the
//module will be attempted to be reloaded
//using a different config.
if (mod.events.defined) {
undefEvents[id] = mod.events;
}
delete defined[id];
delete urlFetched[map.url];
delete undefEvents[id];
if (mod) {
//Hold on to listeners in case the
//module will be attempted to be reloaded
//using a different config.
if (mod.events.defined) {
undefEvents[id] = mod.events;
}
removeWaiting(id);
cleanRegistry(id);
}
};
}
return require;
},
/**
@@ -1523,7 +1443,7 @@ var requirejs, require, define;
completeLoad: function (moduleName) {
var found, args, mod,
shim = config.shim[moduleName] || {},
shExports = shim.exports && shim.exports.exports;
shExports = shim.exports;
takeGlobalQueue();
@@ -1563,31 +1483,13 @@ var requirejs, require, define;
} else {
//A script that does not call define(), so just simulate
//the call for it.
callGetModule([moduleName, (shim.deps || []), shim.exports]);
callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
}
}
checkLoaded();
},
/**
* Converts a module name + .extension into an URL path.
* *Requires* the use of a module name. It does not support using
* plain URLs like nameToUrl.
*/
toUrl: function (moduleNamePlusExt, relModuleMap) {
var index = moduleNamePlusExt.lastIndexOf('.'),
ext = null;
if (index !== -1) {
ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
}
return context.nameToUrl(normalize(moduleNamePlusExt, relModuleMap && relModuleMap.id, true),
ext);
},
/**
* Converts a module name to a file path. Supports cases where
* moduleName may actually be just an URL.
@@ -1701,7 +1603,10 @@ var requirejs, require, define;
return onError(makeError('scripterror', 'Script error', evt, [data.id]));
}
}
});
};
context.require = context.makeRequire();
return context;
}
/**
@@ -1762,6 +1667,16 @@ var requirejs, require, define;
return req(config);
};
/**
* Execute something after the current tick
* of the event loop. Override for other envs
* that have a better solution than setTimeout.
* @param {Function} fn function to execute later.
*/
req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
setTimeout(fn, 4);
} : function (fn) { fn(); };
/**
* Export require as a global, but only if it does not already exist.
*/
@@ -1782,9 +1697,21 @@ var requirejs, require, define;
//Create default context.
req({});
//Exports some context-sensitive methods on global require, using
//default context if no context specified.
addRequireMethods(req);
//Exports some context-sensitive methods on global require.
each([
'toUrl',
'undef',
'defined',
'specified'
], function (prop) {
//Reference from contexts instead of early binding to default context,
//so that during builds, the latest instance of the default context
//with its config gets used.
req[prop] = function () {
var ctx = contexts[defContextName];
return ctx.require[prop].apply(ctx, arguments);
};
});
if (isBrowser) {
head = s.head = document.getElementsByTagName('head')[0];
@@ -1962,7 +1889,7 @@ var requirejs, require, define;
define = function (name, deps, callback) {
var node, context;
//Allow for anonymous functions
//Allow for anonymous modules
if (typeof name !== 'string') {
//Adjust args appropriately
callback = deps;

View File

@@ -14,6 +14,8 @@ $(document).ready(function() {
equal(result.join(','), '1,1', 'works well with _.map');
result = (function() { return _.take([1,2,3], 2); })();
equal(result.join(','), '1,2', 'aliased as take');
equal(_.first(null), undefined, 'handles nulls');
});
test("rest", function() {
@@ -47,6 +49,8 @@ $(document).ready(function() {
equal(result, 4, 'works on an arguments object');
result = _.map([[1,2,3],[1,2,3]], _.last);
equal(result.join(','), '3,3', 'works well with _.map');
equal(_.last(null), undefined, 'handles nulls');
});
test("compact", function() {
@@ -136,6 +140,8 @@ $(document).ready(function() {
var stooges = {moe: 30, larry: 40, curly: 50};
ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object');
ok(_.isEqual(_.object(null), {}), 'handles nulls');
});
test("indexOf", function() {
@@ -144,6 +150,7 @@ $(document).ready(function() {
equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function');
var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3);
equal(result, 1, 'works on an arguments object');
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
var numbers = [10, 20, 30, 40, 50], num = 35;
var index = _.indexOf(numbers, num, true);
@@ -172,6 +179,7 @@ $(document).ready(function() {
equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0);
equal(result, 5, 'works on an arguments object');
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
index = _.lastIndexOf(numbers, 2, 2);

View File

@@ -25,6 +25,10 @@ $(document).ready(function() {
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');
answers = 0;
_.each(null, function(){ ++answers; });
equal(answers, 0, 'handles a null properly');
});
test('map', function() {
@@ -50,6 +54,9 @@ $(document).ready(function() {
var ids = _.map(document.images, function(n){ return n.id; });
ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections');
var ifnull = _.map(null, function(){});
ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly');
});
test('reduce', function() {
@@ -69,6 +76,15 @@ $(document).ready(function() {
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; });
equal(sum, 6, 'default initial value');
var ifnull;
try {
_.reduce(null, function(){});
} catch (ex) {
ifnull = ex;
}
ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly');
ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
});
@@ -83,9 +99,19 @@ $(document).ready(function() {
var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; });
equal(list, 'bazbarfoo', 'default initial value');
var ifnull;
try {
_.reduceRight(null, function(){});
} catch (ex) {
ifnull = ex;
}
ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly');
var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; });
equal(sum, 6, 'default initial value on object');
ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
@@ -385,6 +411,8 @@ $(document).ready(function() {
equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object');
equal(_.size('hello'), 5, 'can compute the size of a string');
equal(_.size(null), 0, 'handles nulls');
});
});

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
// Underscore.js 1.4.0
// Underscore.js 1.4.2
// http://underscorejs.org
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore may be freely distributed under the MIT license.
@@ -65,7 +65,7 @@
}
// Current version.
_.VERSION = '1.4.0';
_.VERSION = '1.4.2';
// Collection Functions
// --------------------
@@ -74,6 +74,7 @@
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
@@ -93,6 +94,7 @@
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results[results.length] = iterator.call(context, value, index, list);
@@ -104,6 +106,7 @@
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
@@ -124,6 +127,7 @@
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
@@ -163,6 +167,7 @@
// Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
@@ -173,6 +178,7 @@
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
each(obj, function(value, index, list) {
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
@@ -185,6 +191,7 @@
_.every = _.all = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
@@ -198,6 +205,7 @@
var any = _.some = _.any = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
@@ -209,6 +217,7 @@
// Aliased as `include`.
_.contains = _.include = function(obj, target) {
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) {
return value === target;
@@ -360,6 +369,7 @@
// Return the number of elements in an object.
_.size = function(obj) {
if (obj == null) return 0;
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
};
@@ -370,6 +380,7 @@
// values in the array. Aliased as `head` and `take`. The **guard** check
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
@@ -384,6 +395,7 @@
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0));
} else {
@@ -482,6 +494,7 @@
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values.
_.object = function(list, values) {
if (list == null) return {};
var result = {};
for (var i = 0, l = list.length; i < l; i++) {
if (values) {
@@ -500,6 +513,7 @@
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i = 0, l = array.length;
if (isSorted) {
if (typeof isSorted == 'number') {
@@ -516,6 +530,7 @@
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item, from) {
if (array == null) return -1;
var hasIndex = from != null;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
@@ -607,25 +622,25 @@
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var context, args, timeout, throttling, more, result;
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
var context, args, timeout, result;
var previous = 0;
var later = function() {
previous = new Date;
timeout = null;
result = func.apply(context, args);
};
return function() {
context = this; args = arguments;
var later = function() {
timeout = null;
if (more) {
result = func.apply(context, args);
}
whenDone();
};
if (!timeout) timeout = setTimeout(later, wait);
if (throttling) {
more = true;
} else {
throttling = true;
var now = new Date;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
previous = now;
result = func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
whenDone();
return result;
};
};