From 568f9578cc2fa432496abb8c7d1809e95c28bc1f Mon Sep 17 00:00:00 2001 From: Tim Oxley Date: Tue, 17 Jul 2012 20:49:12 +1000 Subject: [PATCH] Remove node_modules from repo. That's what `npm install` is for. Trust in npm. --- .gitignore | 1 + .../UnderscoreMatchersForJasmine/README.md | 197 -- .../lib/UnderscoreMatchersForJasmine.coffee | 54 - .../lib/UnderscoreMatchersForJasmine.js | 93 - .../UnderscoreMatchersForJasmine/license.txt | 19 - .../UnderscoreMatchersForJasmine/package.json | 22 - .../spec/underscore_matchers_spec.coffee | 234 -- node_modules/underscore/.npmignore | 3 - node_modules/underscore/CNAME | 1 - node_modules/underscore/LICENSE | 22 - node_modules/underscore/README.md | 19 - node_modules/underscore/favicon.ico | Bin 1406 -> 0 bytes node_modules/underscore/index.html | 2109 ----------------- node_modules/underscore/index.js | 1 - node_modules/underscore/package.json | 10 - node_modules/underscore/raw/underscore.psd | Bin 215540 -> 0 bytes node_modules/underscore/underscore-min.js | 32 - node_modules/underscore/underscore.js | 1059 --------- 18 files changed, 1 insertion(+), 3875 deletions(-) create mode 100644 .gitignore delete mode 100644 node_modules/UnderscoreMatchersForJasmine/README.md delete mode 100644 node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.coffee delete mode 100644 node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.js delete mode 100644 node_modules/UnderscoreMatchersForJasmine/license.txt delete mode 100644 node_modules/UnderscoreMatchersForJasmine/package.json delete mode 100644 node_modules/UnderscoreMatchersForJasmine/spec/underscore_matchers_spec.coffee delete mode 100644 node_modules/underscore/.npmignore delete mode 100644 node_modules/underscore/CNAME delete mode 100644 node_modules/underscore/LICENSE delete mode 100644 node_modules/underscore/README.md delete mode 100755 node_modules/underscore/favicon.ico delete mode 100644 node_modules/underscore/index.html delete mode 100644 node_modules/underscore/index.js delete mode 100644 node_modules/underscore/package.json delete mode 100644 node_modules/underscore/raw/underscore.psd delete mode 100644 node_modules/underscore/underscore-min.js delete mode 100644 node_modules/underscore/underscore.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/UnderscoreMatchersForJasmine/README.md b/node_modules/UnderscoreMatchersForJasmine/README.md deleted file mode 100644 index 67f1461..0000000 --- a/node_modules/UnderscoreMatchersForJasmine/README.md +++ /dev/null @@ -1,197 +0,0 @@ -Underscore Matchers for Jasmine -=== - -UnderscoreMatchersForJasmine adds a series of matchers for [Jasmine][1]-based Javascript/[Coffeescript][2] testing based on [Underscore][_] methods. Example: - - expect(snafu).toInclude('s', 'n', 'a') - - // if snafu is an array, this is equivalent to: - expect( - _(snafu).include('s') && _(snafu).include('n') && _(snafu).include('a') - ).toBeTruthy() - - // if snafu is a Backbone.js collection, this is equivalent to: - expect( - snafu.include('s') && snafu.include('n') && snafu.include('a') - ).toBeTruthy() - -[1]: https://github.com/pivotal/jasmine -[2]: https://github.com/jashkenas/coffee-script -[_]: http://documentcloud.github.com/underscore/ - -That makes your tests easy to read, for example: - - $ -> - describe 'States and StateMachines', -> - it 'should associate states with a state machine and the state machine with its states', -> - engine_status = new StateMachine() - running = engine_status.new_state() - idling = engine_status.new_state() - - expect(running).toRepondTo('state_machine') - expect(engine_status.states()).toInclude(running, idling) - - it 'should generate states with rpm', -> - engine_status = new StateMachine() - running = engine_status.new_state() - - expect(running).toBeA(State) - expect(running).toHave('rpm') - -Is it any good? ---- - -[Yes][y]. - -[y]: http://news.ycombinator.com/item?id=3067434 - -*Why* is it any good? ---- - -Let's take it point by point: - -1. Underscore is a utility-belt library for Javascript. If you're using [Backbone.js][b], you are already using [Underscore][_]. If you aren't using either, you are excused from class, this library does not apply to your project. -2. Jasmine is a [Test-Driven Development][tdd] testing framework for Javascript. You can run tests in a pretty browser window, you can run tests on the command line with Node.js, you can run tests in the console. If you are writing Javascript and/or Coffeescript, you should be using Jasmine. -3. If you are using Underscore or Backbone and you are using Jasmine, your tests will be cleaner and more readable with these Underscore matchers for the same reason that your code is cleaner and more readable with Underscore. - -[tdd]: http://en.wikipedia.org/wiki/Test_Driven_Development -[b]: http://documentcloud.github.com/backbone/ - -Which matchers are included? ---- - -Read the code in [Coffeescript][5] or [Javascript][6]. - -Or, here's the "tl;dr:" - - # collections: - - expect([...]).toBeEmpty() or expect(new Backbone.Collection(...)).toBeEmpty() - expect([...]).toInclude(foo, bar) or expect(new Backbone.Collection(...)).toInclude(foo, bar) - expect([...]).toIncludeAny(blitz) or expect(new Backbone.Collection(...)).toIncludeAny(blitz) - expect([...]).toBeCompact() or expect(new Backbone.Collection(...)).toBeCompact() - expect([...]).toBeUnique() or expect(new Backbone.Collection(...)).toBeUnique() - - # object methods - - expect(foo).toRespondTo('push', 'pop') - expect(foo).toRespondToAny('push', 'isEmpty') - - # object properties - - expect(foo).toHave('length', 'arity') - expect(foo).toHaveAny('length', 'size') - - # OO and is-a (all synonymous) - - expect(new Foo()).toBeAnInstanceOf(Foo) - expect(new Foo()).toBeA(Foo) - expect(new Foo()).toBeAn(Foo) - -[5]: https://github.com/raganwald/Underscore-Matchers-for-Jasmine/blob/master/lib/UnderscoreMatchersForJasmine.coffee -[6]: https://github.com/raganwald/Underscore-Matchers-for-Jasmine/blob/master/lib/UnderscoreMatchersForJasmine.js - -Are there any more? ---- - -This is what I happen to need right now for my actual code. **As I write more matchers, I'll add them**. So, if you're interested, watch the library. I suppose I could go through and make a matcher for every function in Underscore, but I'd rather let it grow organically. If there's a matcher you need that isn't here, well, **we're all in the same boat**: - -* If you're a *passenger*, send me a message describing the matcher you want. If it seems useful, I'll add it. -* If you're a *sailor*, fork this project, add the matcher, and send me a pull request. -* If you're the *captain of your own ship*, and you've already written some matchers like this, run up some signal flags and I'll include links to your project right here. -* And if you're a *pirate*, take this code and/or just the idea and make your own library. I'm cool with that. - -I use jasmine-node. Can I install it with npm? ---- - -Yes: - - npm install UnderscoreMatchersForJasmine - -Can I install it in other kinds of projects? ---- - -If you're using Coffeescript, put `underscore_matchers.coffee` in your project. If you're using plain Javascript, it should therefore follow that you want to put `underscore_matchers.js` in your project. You can also put `underscore_matchers_spec.coffee` or `underscore_matchers_spec.js` in your project if you want to see these matchers test themselves. It's also handy documentation for how the matchers behave! - -Is it free? ---- - -[Yes][4]. - -[4]: https://github.com/raganwald/Underscore-Matchers-for-Jasmine/blob/master/license.txt - -Other Random Observations ---- - -**Who's Using This?** - -I am. - -**Is there a gem?** - -No. This is a Coffeescript and Javascript include file, not a ruby library. Coffeescript and Javascript files work everywhere, and you can read the source any time you want. - -**Any gotchas?** - -Some matchers, such as `toInclude(...)` and `toRespondTo(...)` can take multiple arguments. When they do, they have "all" semantics. For example: - - expect([1,2,3,4,5]).toRespondTo('push', 'pop') - // => succeeds because arrays respond to .push and .pop - - expect([1,2,3,4,5]).toInclude(2,3,4,5,6) - // => fails because 6 is not included. - -Now what if you want to test the opposite? - - expect([1,2,3,4,5]).not.toInclude(2,3,4,5,6) - // succeeds because it doesn't include 2, 3, 4, 5, AND 6. - -If that's what you want, fine. But if what you really want is to test whether it doesn't include ANY of the arguments, you need a slightly different matcher: - - expect([1,2,3,4,5]).toRespondToAny('push', 'select_sql', 'diagonalize') - // => succeeds because arrays respond to at least one of the three methods given - - expect([1,2,3,4,5]).toIncludeAny(2,3,4,5,6) - // => succeeds because it includes at least one of the arguments - -The opposite of an "any" matcher is a "none" matcher: - - expect([1,2,3,4,5]).not.toIncludeAny(3, 6, 9) - // => fails because [1,2,3,4,5] includes a 3 - - expect([1,2,3,4,5]).not.toIncludeAny(6, 9, 12) - // => succeeds because [1,2,3,4,5] does not include ANY of the aarguments - - -**Is this just for underscore stuff?** - -No. I also sneak in some Backbone stuff here and there, but the code works just fine even if you don't use Backbone.js. For example: - - $ -> - describe 'States', -> - it 'should permit cards to be added and removed', -> - state = new State() - card = new Card() - expect(state.cards()).toBeEmpty() - state.cards().add(card) - expect(state.cards()).not.toBeEmpty() - state.cards().remove(card) - expect(state.cards()).toBeEmpty() - -`toBeEmpty` is more than just a wrapper for `_.isEmpty`: - - expect( - _([]).isEmpty() - ).toBeTruthy() // => succeeds - - expect( - _(new Backbone.Collection()).isEmpty() - ).toBeTruthy() // => fails, wtf!? - - expect([]).toBeEmpty() - // => succeeds - - expect(new Backbone.Collection()).toBeEmpty() - // => succeeds - -The same goes for collection tests like `.toInclude`. You can pass it a backbone collection or an array as you see fit. If you don't want that behaviour, Jasmine includes a `contains()` matcher that expects an array. \ No newline at end of file diff --git a/node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.coffee b/node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.coffee deleted file mode 100644 index d1f4b99..0000000 --- a/node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.coffee +++ /dev/null @@ -1,54 +0,0 @@ -_ = require('underscore') unless _? - -invoke = (method_name, args...) -> - if _.isFunction(@actual[method_name]) - @actual[method_name].apply(@actual, args) - else - args.unshift(@actual) - _[method_name].apply(@actual, args) - -beforeEach -> - @addMatchers - toBeEmpty: -> - invoke.call(this, 'isEmpty') - - toInclude: (items...) -> - _(items).all (item) => - invoke.call(this, 'include', item) - - toIncludeAny: (items...) -> - _(items).any (item) => - invoke.call(this, 'include', item) - - toBeCompact: -> - elements = invoke.call(this, 'map', _.identity) - _.isEqual elements, _.compact(elements) - - toBeUnique: -> - elements = invoke.call(this, 'map', _.identity) - _.isEqual elements, _.uniq(elements) - - toRespondTo: (methods...)-> - _.all methods, (method) => - _.isFunction(@actual[method]) - - toRespondToAny: (methods...)-> - _.any methods, (method) => - _.isFunction(@actual[method]) - - toHave: (attrs...) -> - _.all attrs, (attr) => - @actual.has(attr) - - toHaveAny: (attrs...) -> - _.any attrs, (attr) => - @actual.has(attr) - - toBeAnInstanceOf: (clazz) -> - @actual instanceof clazz - - toBeA: (clazz) -> - @actual instanceof clazz - - toBeAn: (clazz) -> - @actual instanceof clazz diff --git a/node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.js b/node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.js deleted file mode 100644 index cf190fb..0000000 --- a/node_modules/UnderscoreMatchersForJasmine/lib/UnderscoreMatchersForJasmine.js +++ /dev/null @@ -1,93 +0,0 @@ -(function() { - var invoke, _; - var __slice = Array.prototype.slice; - - if (typeof _ === "undefined" || _ === null) _ = require('underscore'); - - invoke = function() { - var args, method_name; - method_name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - if (_.isFunction(this.actual[method_name])) { - return this.actual[method_name].apply(this.actual, args); - } else { - args.unshift(this.actual); - return _[method_name].apply(this.actual, args); - } - }; - - beforeEach(function() { - this.addMatchers({ - toBeEmpty: function() { - return invoke.call(this, 'isEmpty'); - }, - toInclude: function() { - var items; - var _this = this; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _(items).all(function(item) { - return invoke.call(_this, 'include', item); - }); - }, - toIncludeAny: function() { - var items; - var _this = this; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _(items).any(function(item) { - return invoke.call(_this, 'include', item); - }); - }, - toBeCompact: function() { - var elements; - elements = invoke.call(this, 'map', _.identity); - return _.isEqual(elements, _.compact(elements)); - }, - toBeUnique: function() { - var elements; - elements = invoke.call(this, 'map', _.identity); - return _.isEqual(elements, _.uniq(elements)); - }, - toRespondTo: function() { - var methods; - var _this = this; - methods = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _.all(methods, function(method) { - return _.isFunction(_this.actual[method]); - }); - }, - toRespondToAny: function() { - var methods; - var _this = this; - methods = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _.any(methods, function(method) { - return _.isFunction(_this.actual[method]); - }); - }, - toHave: function() { - var attrs; - var _this = this; - attrs = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _.all(attrs, function(attr) { - return _this.actual.has(attr); - }); - }, - toHaveAny: function() { - var attrs; - var _this = this; - attrs = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return _.any(attrs, function(attr) { - return _this.actual.has(attr); - }); - }, - toBeAnInstanceOf: function(clazz) { - return this.actual instanceof clazz; - }, - toBeA: function(clazz) { - return this.actual instanceof clazz; - }, - toBeAn: function(clazz) { - return this.actual instanceof clazz; - } - }); - }); - -}).call(this); diff --git a/node_modules/UnderscoreMatchersForJasmine/license.txt b/node_modules/UnderscoreMatchersForJasmine/license.txt deleted file mode 100644 index 72b1ec8..0000000 --- a/node_modules/UnderscoreMatchersForJasmine/license.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Reginald Braithwaite - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/node_modules/UnderscoreMatchersForJasmine/package.json b/node_modules/UnderscoreMatchersForJasmine/package.json deleted file mode 100644 index 93840e1..0000000 --- a/node_modules/UnderscoreMatchersForJasmine/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "author": "Reg Braithwaite (http://reginald.braythwayt.com)", - "name": "UnderscoreMatchersForJasmine", - "description": "Underscore and backbone Matchers for Jasmine-Node", - "version": "0.0.5", - "homepage": "https://github.com/raganwald/Underscore-Matchers-for-Jasmine", - "repository": { - "type": "git", - "url": "git@github.com:raganwald/Underscore-Matchers-for-Jasmine.git" - }, - "main": "lib/UnderscoreMatchersForJasmine.js", - "scripts": { - "test": "jasmine-node --coffee --verbose spec" - }, - "engines": { - "node": "" - }, - "dependencies": { - "underscore": ">=1.2.2" - }, - "devDependencies": {} -} diff --git a/node_modules/UnderscoreMatchersForJasmine/spec/underscore_matchers_spec.coffee b/node_modules/UnderscoreMatchersForJasmine/spec/underscore_matchers_spec.coffee deleted file mode 100644 index 0b737f1..0000000 --- a/node_modules/UnderscoreMatchersForJasmine/spec/underscore_matchers_spec.coffee +++ /dev/null @@ -1,234 +0,0 @@ -require './../lib/UnderscoreMatchersForJasmine' - -describe "toBeEmpty", -> - - it 'should work for arrays', -> - - expect([]).toBeEmpty() - expect([1]).not.toBeEmpty() - - if Backbone? - - it 'should work for backbone collections', -> - c = new Backbone.Collection() - expect(c).toBeEmpty() - c.add - foo: 'bar' - - expect(c).not.toBeEmpty() - - -describe "toInclude", -> - - it 'should work for arrays', -> - - expect([]).not.toInclude('s') - expect(['s', 'n', 'a', 'f', 'u']).toInclude('f', 'a', 'n') - expect(['s', 'n', 'a', 'f', 'u']).not.toInclude('p', 'a', 'n') - expect(['s', 'n', 'a', 'f', 'u']).not.toInclude('f', 'a', 'x') - - if Backbone? - - it 'should work for backbone collections', -> - c = new Backbone.Collection() - [s, n, a, f, u, p, x] = [new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model()] - expect(c).not.toInclude(s) - - c.add [s, n, a, f, u] - - expect(c).toInclude f, a, n - expect(c).not.toInclude p, a, n - expect(c).not.toInclude f, a, x - - -describe "toIncludeAny", -> - - it 'should work for arrays', -> - - expect([]).not.toIncludeAny('s') - expect(['s', 'n', 'a', 'f', 'u']).toIncludeAny('f', 'a', 'n') - expect(['s', 'n', 'a', 'f', 'u']).toIncludeAny('p', 'a', 'n') - expect(['s', 'n', 'a', 'f', 'u']).toIncludeAny('f', 'a', 'x') - expect(['s', 'n', 'a', 'f', 'u']).not.toIncludeAny('p', 'x') - - if Backbone? - - it 'should work for backbone collections', -> - c = new Backbone.Collection() - [s, n, a, f, u, p, x] = [new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model(), new Backbone.Model()] - expect(c).not.toIncludeAny(s) - - c.add [s, n, a, f, u] - - expect(c).toIncludeAny f, a, n - expect(c).toIncludeAny p, a, n - expect(c).toIncludeAny f, a, x - expect(c).not.toIncludeAny p, x - -describe "toBeCompact", -> - - undef = null - ((_) -> undef = _)() - expect(undef).toBeUndefined() - - it 'should work for arrays', -> - - expect([]).toBeCompact() - expect(['s', 'n', 'a', 'f', 'u']).toBeCompact() - expect(['s', 'n', 'a', false, 'u']).not.toBeCompact() - expect(['s', null, 'a', 'f', 'u']).not.toBeCompact() - expect(['s', 'n', 'a', 'f', undef]).not.toBeCompact() - -describe "toBeUnique", -> - - undef = null - ((_) -> undef = _)() - expect(undef).toBeUndefined() - - it 'should work for arrays', -> - - expect([]).toBeUnique() - expect(['s', 'n', 'a', 'f', 'u']).toBeUnique() - expect(['s', 'n', 'a', 'a', 'u']).not.toBeUnique() - expect(['s', 'f', 'u', 'f', 'u']).not.toBeUnique() - -describe 'toRespondTo', -> - - it 'should work for a single function', -> - - expect([]).toRespondTo('push') - expect([]).toRespondTo('pop') - expect([]).not.toRespondTo('pizzle') - - it 'should have all semantics for multiple functions', -> - - expect([]).toRespondTo('push','pop') - expect([]).not.toRespondTo('push','pop','pizzle') - -describe 'toRespondToAny', -> - - it 'should work for a single function', -> - - expect([]).toRespondToAny('push') - expect([]).toRespondToAny('pop') - expect([]).not.toRespondToAny('pizzle') - - it 'should have any semantics for multiple functions', -> - - expect([]).toRespondToAny('push','pop', 'pizzle') - expect([]).not.toRespondTo('pasta','salad','pizzle') - - -describe 'toBeAnInstanceOf', -> - - it 'should work with basic JS objects', -> - C = () -> - D = () -> - - c = new C() - expect(c).toBeAnInstanceOf(Object) - expect(c).toBeAnInstanceOf(C) - expect(c).not.toBeAnInstanceOf(D) - - expect(c).toBeA(Object) - expect(c).toBeA(C) - expect(c).not.toBeA(D) - - expect(c).toBeAn(Object) - expect(c).toBeAn(C) - expect(c).not.toBeAn(D) - - if Backbone? - - it 'should work with Backbone classes as well', -> - B = Backbone.Model.extend() - C = B.extend() - D = Backbone.Model.extend() - - c = new C() - expect(c).toBeAnInstanceOf(B) - expect(c).toBeAnInstanceOf(C) - expect(c).not.toBeAnInstanceOf(D) - - expect(c).toBeA(B) - expect(c).toBeA(C) - expect(c).not.toBeA(D) - - expect(c).toBeAn(B) - expect(c).toBeAn(C) - expect(c).not.toBeAn(D) - -if Backbone? - - describe 'toHave', -> - - it 'should report whether a property is set with something truthy', -> - model = new Backbone.Model - foo: 'fu' - expect(model).toHave('foo') - expect(model).not.toHave('bar') - - it 'should have the same semantics as .has for falsy-ish values', -> - model = new Backbone.Model - false: false - null: null - zero: 0 - empty_array: [] - empty_string: '' - undefined: undefined - _.each model.attributes, (value, key) -> - if model.has(key) - expect(model).toHave(key) - else - expect(model).not.toHave(key) - - it 'should be compatible with unset', -> - model = new Backbone.Model - foo: 'fu' - expect(model).toHave('foo') - model.unset('foo') - expect(model).not.toHave('foo') - - it 'should have all semantics', -> - model = new Backbone.Model - foo: 'fu' - bar: 'bar' - expect(model).toHave('foo', 'bar') - expect(model).not.toHave('snafu', 'bar') - - describe 'toHaveAny', -> - - it 'should report whether a property is set with something truthy', -> - model = new Backbone.Model - foo: 'fu' - expect(model).toHaveAny('foo') - expect(model).not.toHaveAny('bar') - - it 'should have the same semantics as .has for falsy-ish values', -> - model = new Backbone.Model - false: false - null: null - zero: 0 - empty_array: [] - empty_string: '' - undefined: undefined - _.each model.attributes, (value, key) -> - if model.has(key) - expect(model).toHaveAny(key) - else - expect(model).not.toHaveAny(key) - - it 'should be compatible with unset', -> - model = new Backbone.Model - foo: 'fu' - expect(model).toHaveAny('foo') - model.unset('foo') - expect(model).not.toHaveAny('foo') - - it 'should have any semantics', -> - model = new Backbone.Model - foo: 'fu' - bar: 'bar' - expect(model).toHaveAny('foo', 'bar') - expect(model).toHaveAny('snafu', 'bar') - expect(model).not.toHaveAny('snafu', 'fubar') diff --git a/node_modules/underscore/.npmignore b/node_modules/underscore/.npmignore deleted file mode 100644 index 2ce2684..0000000 --- a/node_modules/underscore/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -test/ -Rakefile -docs/ \ No newline at end of file diff --git a/node_modules/underscore/CNAME b/node_modules/underscore/CNAME deleted file mode 100644 index a007e65..0000000 --- a/node_modules/underscore/CNAME +++ /dev/null @@ -1 +0,0 @@ -underscorejs.org diff --git a/node_modules/underscore/LICENSE b/node_modules/underscore/LICENSE deleted file mode 100644 index 61d28c0..0000000 --- a/node_modules/underscore/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/underscore/README.md b/node_modules/underscore/README.md deleted file mode 100644 index a6564a2..0000000 --- a/node_modules/underscore/README.md +++ /dev/null @@ -1,19 +0,0 @@ - __ - /\ \ __ - __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ - /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ - \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ - \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ - \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ - \ \____/ - \/___/ - -Underscore.js is a utility-belt library for JavaScript that provides -support for the usual functional suspects (each, map, reduce, filter...) -without extending any core JavaScript objects. - -For Docs, License, Tests, and pre-packed downloads, see: -http://documentcloud.github.com/underscore/ - -Many thanks to our contributors: -https://github.com/documentcloud/underscore/contributors diff --git a/node_modules/underscore/favicon.ico b/node_modules/underscore/favicon.ico deleted file mode 100755 index 03049683875ee7207b4ee62241fc6977956723c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1406 zcmZQzU<5(|0R|w+!H~hqz#zuJz@P!dKp_SNAO?x!16vCj7#y|msTh?T4S~@R7;Yi( a|NnmmMkru{0(Aax^D{300E2>o91H*{%ptM> diff --git a/node_modules/underscore/index.html b/node_modules/underscore/index.html deleted file mode 100644 index 01c18ac..0000000 --- a/node_modules/underscore/index.html +++ /dev/null @@ -1,2109 +0,0 @@ - - - - - - - Underscore.js - - - - - - -
- -

- Underscore.js -

- -

- Underscore is a - utility-belt library for JavaScript that provides a lot of the - functional programming support that you would expect in - Prototype.js - (or Ruby), - but without extending any of the built-in JavaScript objects. It's the - tie to go along with jQuery's tux, - and Backbone.js's suspenders. -

- -

- Underscore provides 60-odd functions that support both the usual - functional suspects: map, select, invoke — - as well as more specialized helpers: function binding, javascript - templating, deep equality testing, and so on. It delegates to built-in - functions, if present, so modern browsers will use the - native implementations of forEach, map, reduce, - filter, every, some and indexOf. -

- -

- A complete Test & Benchmark Suite - is included for your perusal. -

- -

- You may also read through the annotated source code. -

- -

- The project is - hosted on GitHub. - You can report bugs and discuss features on the - issues page, - on Freenode in the #documentcloud channel, - or send tweets to @documentcloud. -

- -

- Underscore is an open-source component of DocumentCloud. -

- -

Downloads (Right-click, and use "Save As")

- - - - - - - - - - -
Development Version (1.3.3)37kb, Uncompressed with Plentiful Comments
Production Version (1.3.3)4kb, Minified and Gzipped
- -
Upgrade warning: versions 1.3.0 and higher remove AMD (RequireJS) support.
- -
- -

Collection Functions (Arrays or Objects)

- -

- each_.each(list, iterator, [context]) - Alias: forEach -
- Iterates over a list of elements, yielding each in turn to an iterator - function. The iterator is bound to the context object, if one is - passed. Each invocation of iterator is called with three arguments: - (element, index, list). If list is a JavaScript object, iterator's - arguments will be (value, key, list). Delegates to the native - forEach function if it exists. -

-
-_.each([1, 2, 3], function(num){ alert(num); });
-=> alerts each number in turn...
-_.each({one : 1, two : 2, three : 3}, function(num, key){ alert(num); });
-=> alerts each number in turn...
- -

- map_.map(list, iterator, [context]) - Alias: collect -
- Produces a new array of values by mapping each value in list - through a transformation function (iterator). If the native map method - exists, it will be used instead. If list is a JavaScript object, - iterator's arguments will be (value, key, list). -

-
-_.map([1, 2, 3], function(num){ return num * 3; });
-=> [3, 6, 9]
-_.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; });
-=> [3, 6, 9]
- -

- reduce_.reduce(list, iterator, memo, [context]) - Aliases: inject, foldl -
- Also known as inject and foldl, reduce boils down a - list of values into a single value. Memo is the initial state - of the reduction, and each successive step of it should be returned by - iterator. -

-
-var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
-=> 6
-
- -

- reduceRight_.reduceRight(list, iterator, memo, [context]) - Alias: foldr -
- The right-associative version of reduce. Delegates to the - JavaScript 1.8 version of reduceRight, if it exists. Foldr - is not as useful in JavaScript as it would be in a language with lazy - evaluation. -

-
-var list = [[0, 1], [2, 3], [4, 5]];
-var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-=> [4, 5, 2, 3, 0, 1]
-
- -

- find_.find(list, iterator, [context]) - Alias: detect -
- Looks through each value in the list, returning the first one that - passes a truth test (iterator). The function returns as - soon as it finds an acceptable element, and doesn't traverse the - entire list. -

-
-var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
-=> 2
-
- -

- filter_.filter(list, iterator, [context]) - Alias: select -
- Looks through each value in the list, returning an array of all - the values that pass a truth test (iterator). Delegates to the - native filter method, if it exists. -

-
-var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
-=> [2, 4, 6]
-
- -

- reject_.reject(list, iterator, [context]) -
- Returns the values in list without the elements that the truth - test (iterator) passes. The opposite of filter. -

-
-var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
-=> [1, 3, 5]
-
- -

- all_.all(list, iterator, [context]) - Alias: every -
- Returns true if all of the values in the list pass the iterator - truth test. Delegates to the native method every, if present. -

-
-_.all([true, 1, null, 'yes'], _.identity);
-=> false
-
- -

- any_.any(list, [iterator], [context]) - Alias: some -
- Returns true if any of the values in the list pass the - iterator truth test. Short-circuits and stops traversing the list - if a true element is found. Delegates to the native method some, - if present. -

-
-_.any([null, 0, 'yes', false]);
-=> true
-
- -

- include_.include(list, value) - Alias: contains -
- Returns true if the value is present in the list, using - === to test equality. Uses indexOf internally, if list - is an Array. -

-
-_.include([1, 2, 3], 3);
-=> true
-
- -

- invoke_.invoke(list, methodName, [*arguments]) -
- Calls the method named by methodName on each value in the list. - Any extra arguments passed to invoke will be forwarded on to the - method invocation. -

-
-_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-=> [[1, 5, 7], [1, 2, 3]]
-
- -

- pluck_.pluck(list, propertyName) -
- A convenient version of what is perhaps the most common use-case for - map: extracting a list of property values. -

-
-var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
-_.pluck(stooges, 'name');
-=> ["moe", "larry", "curly"]
-
- -

- max_.max(list, [iterator], [context]) -
- Returns the maximum value in list. If iterator is passed, - it will be used on each value to generate the criterion by which the - value is ranked. -

-
-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};
-
- -

- min_.min(list, [iterator], [context]) -
- Returns the minimum value in list. If iterator is passed, - it will be used on each value to generate the criterion by which the - value is ranked. -

-
-var numbers = [10, 5, 100, 2, 1000];
-_.min(numbers);
-=> 2
-
- -

- sortBy_.sortBy(list, iterator, [context]) -
- Returns a sorted copy of list, ranked in ascending order by the - results of running each value through iterator. Iterator may - also be the string name of the property to sort by (eg. length). -

-
-_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
-=> [5, 4, 6, 3, 1, 2]
-
- -

- groupBy_.groupBy(list, iterator) -
- Splits a collection into sets, grouped by the result of running each - value through iterator. If iterator is a string instead of - a function, groups by the property named by iterator on each of - the values. -

-
-_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
-=> {1: [1.3], 2: [2.1, 2.4]}
-
-_.groupBy(['one', 'two', 'three'], 'length');
-=> {3: ["one", "two"], 5: ["three"]}
-
- -

- sortedIndex_.sortedIndex(list, value, [iterator]) -
- Uses a binary search to determine the index at which the value - should be inserted into the list in order to maintain the list's - sorted order. If an iterator is passed, it will be used to compute - the sort ranking of each value. -

-
-_.sortedIndex([10, 20, 30, 40, 50], 35);
-=> 3
-
- -

- shuffle_.shuffle(list) -
- Returns a shuffled copy of the list, using a version of the - Fisher-Yates shuffle. -

-
-_.shuffle([1, 2, 3, 4, 5, 6]);
-=> [4, 1, 6, 3, 5, 2]
-
- -

- toArray_.toArray(list) -
- Converts the list (anything that can be iterated over), into a - real Array. Useful for transmuting the arguments object. -

-
-(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-=> [2, 3, 4]
-
- -

- size_.size(list) -
- Return the number of values in the list. -

-
-_.size({one : 1, two : 2, three : 3});
-=> 3
-
- -

Array Functions

- -

- Note: All array functions will also work on the arguments object. -

- -

- first_.first(array, [n]) - Alias: head -
- Returns the first element of an array. Passing n will - return the first n elements of the array. -

-
-_.first([5, 4, 3, 2, 1]);
-=> 5
-
- -

- initial_.initial(array, [n]) -
- Returns everything but the last entry of the array. Especially useful on - the arguments object. Pass n to exclude the last n elements - from the result. -

-
-_.initial([5, 4, 3, 2, 1]);
-=> [5, 4, 3, 2]
-
- -

- last_.last(array, [n]) -
- Returns the last element of an array. Passing n will return - the last n elements of the array. -

-
-_.last([5, 4, 3, 2, 1]);
-=> 1
-
- -

- rest_.rest(array, [index]) - Alias: tail -
- Returns the rest of the elements in an array. Pass an index - to return the values of the array from that index onward. -

-
-_.rest([5, 4, 3, 2, 1]);
-=> [4, 3, 2, 1]
-
- -

- compact_.compact(array) -
- Returns a copy of the array with all falsy values removed. - In JavaScript, false, null, 0, "", - undefined and NaN are all falsy. -

-
-_.compact([0, 1, false, 2, '', 3]);
-=> [1, 2, 3]
-
- -

- flatten_.flatten(array, [shallow]) -
- Flattens a nested array (the nesting can be to any depth). If you - pass shallow, the array will only be flattened a single level. -

-
-_.flatten([1, [2], [3, [[4]]]]);
-=> [1, 2, 3, 4];
-
-_.flatten([1, [2], [3, [[4]]]], true);
-=> [1, 2, 3, [[4]]];
-
- -

- without_.without(array, [*values]) -
- Returns a copy of the array with all instances of the values - removed. === is used for the equality test. -

-
-_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
-=> [2, 3, 4]
-
- -

- union_.union(*arrays) -
- Computes the union of the passed-in arrays: the list of unique items, - in order, that are present in one or more of the arrays. -

-
-_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
-=> [1, 2, 3, 101, 10]
-
- -

- intersection_.intersection(*arrays) -
- Computes the list of values that are the intersection of all the arrays. - Each value in the result is present in each of the arrays. -

-
-_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
-=> [1, 2]
-
- -

- difference_.difference(array, *others) -
- Similar to without, but returns the values from array that - are not present in the other arrays. -

-
-_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-=> [1, 3, 4]
-
- -

- uniq_.uniq(array, [isSorted], [iterator]) - Alias: unique -
- Produces a duplicate-free version of the array, using === to test - object equality. If you know in advance that the array is sorted, - passing true for isSorted will run a much faster algorithm. - If you want to compute unique items based on a transformation, pass an - iterator function. -

-
-_.uniq([1, 2, 1, 3, 1, 4]);
-=> [1, 2, 3, 4]
-
- -

- zip_.zip(*arrays) -
- Merges together the values of each of the arrays with the - values at the corresponding position. Useful when you have separate - data sources that are coordinated through matching array indexes. - If you're working with a matrix of nested arrays, zip.apply - can transpose the matrix in a similar fashion. -

-
-_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
-=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
-
- -

- indexOf_.indexOf(array, value, [isSorted]) -
- Returns the index at which value can be found in the array, - or -1 if value is not present in the array. Uses the native - indexOf function unless it's missing. If you're working with a - large array, and you know that the array is already sorted, pass true - for isSorted to use a faster binary search. -

-
-_.indexOf([1, 2, 3], 2);
-=> 1
-
- -

- lastIndexOf_.lastIndexOf(array, value) -
- Returns the index of the last occurrence of value in the array, - or -1 if value is not present. Uses the native lastIndexOf - function if possible. -

-
-_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-=> 4
-
- -

- range_.range([start], stop, [step]) -
- A function to create flexibly-numbered lists of integers, handy for - each and map loops. start, if omitted, defaults - to 0; step defaults to 1. Returns a list of integers - from start to stop, incremented (or decremented) by step, - exclusive. -

-
-_.range(10);
-=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-_.range(1, 11);
-=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-_.range(0, 30, 5);
-=> [0, 5, 10, 15, 20, 25]
-_.range(0, -10, -1);
-=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
-_.range(0);
-=> []
-
- -

Function (uh, ahem) Functions

- -

- bind_.bind(function, object, [*arguments]) -
- Bind a function to an object, meaning that whenever - the function is called, the value of this will be the object. - Optionally, bind arguments to the function to pre-fill them, - also known as partial application. -

-
-var func = function(greeting){ return greeting + ': ' + this.name };
-func = _.bind(func, {name : 'moe'}, 'hi');
-func();
-=> 'hi: moe'
-
- -

- bindAll_.bindAll(object, [*methodNames]) -
- Binds a number of methods on the object, specified by - methodNames, to be run in the context of that object whenever they - are invoked. Very handy for binding functions that are going to be used - as event handlers, which would otherwise be invoked with a fairly useless - this. If no methodNames are provided, all of the object's - function properties will be bound to it. -

-
-var buttonView = {
-  label   : 'underscore',
-  onClick : function(){ alert('clicked: ' + this.label); },
-  onHover : function(){ console.log('hovering: ' + this.label); }
-};
-_.bindAll(buttonView);
-jQuery('#underscore_button').bind('click', buttonView.onClick);
-=> When the button is clicked, this.label will have the correct value...
-
- -

- memoize_.memoize(function, [hashFunction]) -
- Memoizes a given function by caching the computed result. Useful - for speeding up slow-running computations. If passed an optional - hashFunction, it will be used to compute the hash key for storing - the result, based on the arguments to the original function. The default - hashFunction just uses the first argument to the memoized function - as the key. -

-
-var fibonacci = _.memoize(function(n) {
-  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
-});
-
- -

- delay_.delay(function, wait, [*arguments]) -
- Much like setTimeout, invokes function after wait - milliseconds. If you pass the optional arguments, they will be - forwarded on to the function when it is invoked. -

-
-var log = _.bind(console.log, console);
-_.delay(log, 1000, 'logged later');
-=> 'logged later' // Appears after one second.
-
- -

- defer_.defer(function) -
- Defers invoking the function until the current call stack has cleared, - similar to using setTimeout with a delay of 0. Useful for performing - expensive computations or HTML rendering in chunks without blocking the UI thread - from updating. -

-
-_.defer(function(){ alert('deferred'); });
-// Returns from the function before the alert runs.
-
- -

- throttle_.throttle(function, wait) -
- Creates and returns a new, throttled version of the passed function, - that, when invoked repeatedly, will only actually call the original function - at most once per every wait - milliseconds. Useful for rate-limiting events that occur faster than you - can keep up with. -

-
-var throttled = _.throttle(updatePosition, 100);
-$(window).scroll(throttled);
-
- -

- debounce_.debounce(function, wait, [immediate]) -
- Creates and returns a new debounced version of the passed function that - will postpone its execution until after - wait milliseconds have elapsed since the last time it - was invoked. Useful for implementing behavior that should only happen - after the input has stopped arriving. For example: rendering a - preview of a Markdown comment, recalculating a layout after the window - has stopped being resized, and so on. -

- -

- Pass true for the immediate parameter to cause - debounce to trigger the function on the leading intead of the - trailing edge of the wait interval. Useful in circumstances like - preventing accidental double-clicks on a "submit" button from firing a - second time. -

- -
-var lazyLayout = _.debounce(calculateLayout, 300);
-$(window).resize(lazyLayout);
-
- -

- once_.once(function) -
- Creates a version of the function that can only be called one time. - Repeated calls to the modified function will have no effect, returning - the value from the original call. Useful for initialization functions, - instead of having to set a boolean flag and then check it later. -

-
-var initialize = _.once(createApplication);
-initialize();
-initialize();
-// Application is only created once.
-
- -

- after_.after(count, function) -
- Creates a version of the function that will only be run after first - being called count times. Useful for grouping asynchronous responses, - where you want to be sure that all the async calls have finished, before - proceeding. -

-
-var renderNotes = _.after(notes.length, render);
-_.each(notes, function(note) {
-  note.asyncSave({success: renderNotes});
-});
-// renderNotes is run once, after all notes have saved.
-
- -

- wrap_.wrap(function, wrapper) -
- Wraps the first function inside of the wrapper function, - passing it as the first argument. This allows the wrapper to - execute code before and after the function runs, adjust the arguments, - and execute it conditionally. -

-
-var hello = function(name) { return "hello: " + name; };
-hello = _.wrap(hello, function(func) {
-  return "before, " + func("moe") + ", after";
-});
-hello();
-=> 'before, hello: moe, after'
-
- -

- compose_.compose(*functions) -
- Returns the composition of a list of functions, where each function - consumes the return value of the function that follows. In math terms, - composing the functions f(), g(), and h() produces - f(g(h())). -

-
-var greet    = function(name){ return "hi: " + name; };
-var exclaim  = function(statement){ return statement + "!"; };
-var welcome = _.compose(exclaim, greet);
-welcome('moe');
-=> 'hi: moe!'
-
- -

Object Functions

- -

- keys_.keys(object) -
- Retrieve all the names of the object's properties. -

-
-_.keys({one : 1, two : 2, three : 3});
-=> ["one", "two", "three"]
-
- -

- values_.values(object) -
- Return all of the values of the object's properties. -

-
-_.values({one : 1, two : 2, three : 3});
-=> [1, 2, 3]
-
- -

- functions_.functions(object) - Alias: methods -
- Returns a sorted list of the names of every method in an object — - that is to say, the name of every function property of the object. -

-
-_.functions(_);
-=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
-
- -

- extend_.extend(destination, *sources) -
- Copy all of the properties in the source objects over to the - destination object, and return the destination object. - It's in-order, so the last source will override properties of the same - name in previous arguments. -

-
-_.extend({name : 'moe'}, {age : 50});
-=> {name : 'moe', age : 50}
-
- -

- pick_.pick(object, *keys) -
- Return a copy of the object, filtered to only have values for - the whitelisted keys (or array of valid keys). -

-
-_.pick({name : 'moe', age: 50, userid : 'moe1'}, 'name', 'age');
-=> {name : 'moe', age : 50}
-
- -

- defaults_.defaults(object, *defaults) -
- Fill in missing properties in object with default values from the - defaults objects, and return the object. As soon as the - property is filled, further defaults will have no effect. -

-
-var iceCream = {flavor : "chocolate"};
-_.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"});
-=> {flavor : "chocolate", sprinkles : "lots"}
-
- -

- clone_.clone(object) -
- Create a shallow-copied clone of the object. Any nested objects - or arrays will be copied by reference, not duplicated. -

-
-_.clone({name : 'moe'});
-=> {name : 'moe'};
-
- -

- tap_.tap(object, interceptor) -
- Invokes interceptor with the object, and then returns object. - The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. -

-
-_.chain([1,2,3,200])
-  .filter(function(num) { return num % 2 == 0; })
-  .tap(alert)
-  .map(function(num) { return num * num })
-  .value();
-=> // [2, 200] (alerted)
-=> [4, 40000]
-
- -

- has_.has(object, key) -
- Does the object contain the given key? Identical to - object.hasOwnProperty(key), but uses a safe reference to the - hasOwnProperty function, in case it's been - overridden accidentally. -

-
-_.has({a: 1, b: 2, c: 3}, "b");
-=> true
-
- -

- isEqual_.isEqual(object, other) -
- Performs an optimized deep comparison between the two objects, to determine - if they should be considered equal. -

-
-var moe   = {name : 'moe', luckyNumbers : [13, 27, 34]};
-var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
-moe == clone;
-=> false
-_.isEqual(moe, clone);
-=> true
-
- -

- isEmpty_.isEmpty(object) -
- Returns true if object contains no values. -

-
-_.isEmpty([1, 2, 3]);
-=> false
-_.isEmpty({});
-=> true
-
- -

- isElement_.isElement(object) -
- Returns true if object is a DOM element. -

-
-_.isElement(jQuery('body')[0]);
-=> true
-
- -

- isArray_.isArray(object) -
- Returns true if object is an Array. -

-
-(function(){ return _.isArray(arguments); })();
-=> false
-_.isArray([1,2,3]);
-=> true
-
- -

- isObject_.isObject(value) -
- Returns true if value is an Object. -

-
-_.isObject({});
-=> true
-_.isObject(1);
-=> false
-
- -

- isArguments_.isArguments(object) -
- Returns true if object is an Arguments object. -

-
-(function(){ return _.isArguments(arguments); })(1, 2, 3);
-=> true
-_.isArguments([1,2,3]);
-=> false
-
- -

- isFunction_.isFunction(object) -
- Returns true if object is a Function. -

-
-_.isFunction(alert);
-=> true
-
- -

- isString_.isString(object) -
- Returns true if object is a String. -

-
-_.isString("moe");
-=> true
-
- -

- isNumber_.isNumber(object) -
- Returns true if object is a Number (including NaN). -

-
-_.isNumber(8.4 * 5);
-=> true
-
- -

- isFinite_.isFinite(object) -
- Returns true if object is a finite Number. -

-
-_.isFinite(-101);
-=> true
-
-_.isFinite(-Infinity);
-=> false
-
- -

- isBoolean_.isBoolean(object) -
- Returns true if object is either true or false. -

-
-_.isBoolean(null);
-=> false
-
- -

- isDate_.isDate(object) -
- Returns true if object is a Date. -

-
-_.isDate(new Date());
-=> true
-
- -

- isRegExp_.isRegExp(object) -
- Returns true if object is a RegExp. -

-
-_.isRegExp(/moe/);
-=> true
-
- -

- isNaN_.isNaN(object) -
- Returns true if object is NaN.
Note: this is not - the same as the native isNaN function, which will also return - true if the variable is undefined. -

-
-_.isNaN(NaN);
-=> true
-isNaN(undefined);
-=> true
-_.isNaN(undefined);
-=> false
-
- -

- isNull_.isNull(object) -
- Returns true if the value of object is null. -

-
-_.isNull(null);
-=> true
-_.isNull(undefined);
-=> false
-
- -

- isUndefined_.isUndefined(variable) -
- Returns true if variable is undefined. -

-
-_.isUndefined(window.missingVariable);
-=> true
-
- -

Utility Functions

- -

- noConflict_.noConflict() -
- Give control of the "_" variable back to its previous owner. Returns - a reference to the Underscore object. -

-
-var underscore = _.noConflict();
- -

- identity_.identity(value) -
- Returns the same value that is used as the argument. In math: - f(x) = x
- This function looks useless, but is used throughout Underscore as - a default iterator. -

-
-var moe = {name : 'moe'};
-moe === _.identity(moe);
-=> true
- -

- times_.times(n, iterator) -
- Invokes the given iterator function n times. -

-
-_(3).times(function(){ genie.grantWish(); });
- -

- mixin_.mixin(object) -
- Allows you to extend Underscore with your own utility functions. Pass - a hash of {name: function} definitions to have your functions - added to the Underscore object, as well as the OOP wrapper. -

-
-_.mixin({
-  capitalize : function(string) {
-    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
-  }
-});
-_("fabio").capitalize();
-=> "Fabio"
-
- -

- uniqueId_.uniqueId([prefix]) -
- Generate a globally-unique id for client-side models or DOM elements - that need one. If prefix is passed, the id will be appended to it. - Without prefix, returns an integer. -

-
-_.uniqueId('contact_');
-=> 'contact_104'
- -

- escape_.escape(string) -
- Escapes a string for insertion into HTML, replacing - &, <, >, ", ', and / characters. -

-
-_.escape('Curly, Larry & Moe');
-=> "Curly, Larry &amp; Moe"
- -

- result_.result(object, property) -
- If the value of the named property is a function then invoke it; otherwise, return it. -

-
-var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
-_.result(object, 'cheese');
-=> "crumpets"
-_.result(object, 'stuff');
-=> "nonsense"
- -

- template_.template(templateString, [data], [settings]) -
- Compiles JavaScript templates into functions that can be evaluated - for rendering. Useful for rendering complicated bits of HTML from JSON - data sources. Template functions can both interpolate variables, using - <%= … %>, as well as execute arbitrary JavaScript code, with - <% … %>. If you wish to interpolate a value, and have - it be HTML-escaped, use <%- … %> When you evaluate a template function, pass in a - data object that has properties corresponding to the template's free - variables. If you're writing a one-off, you can pass the data - object as the second parameter to template in order to render - immediately instead of returning a template function. The settings argument - should be a hash containing any _.templateSettings that should be overriden. -

- -
-var compiled = _.template("hello: <%= name %>");
-compiled({name : 'moe'});
-=> "hello: moe"
-
-var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
-_.template(list, {people : ['moe', 'curly', 'larry']});
-=> "<li>moe</li><li>curly</li><li>larry</li>"
-
-var template = _.template("<b><%- value %></b>");
-template({value : '<script>'});
-=> "<b>&lt;script&gt;</b>"
- -

- You can also use print from within JavaScript code. This is - sometimes more convenient than using <%= ... %>. -

- -
-var compiled = _.template("<% print('Hello ' + epithet); %>");
-compiled({epithet: "stooge"});
-=> "Hello stooge."
- -

- If ERB-style delimiters aren't your cup of tea, you can change Underscore's - template settings to use different symbols to set off interpolated code. - Define an interpolate regex to match expressions that should be - interpolated verbatim, an escape regex to match expressions that should - be inserted after being HTML escaped, and an evaluate regex to match - expressions that should be evaluated without insertion into the resulting - string. You may define or omit any combination of the three. - For example, to perform - Mustache.js - style templating: -

- -
-_.templateSettings = {
-  interpolate : /\{\{(.+?)\}\}/g
-};
-
-var template = _.template("Hello {{ name }}!");
-template({name : "Mustache"});
-=> "Hello Mustache!"
- -

- By default, template places the values from your data in the local scope - via the with statement. However, you can specify a single variable name - with the variable setting. This can significantly improve the speed - at which a template is able to render. -

- -
-_.template("<%= data.hasWith %>", {hasWith: 'no'}, {variable: 'data'});
-=> "no"
- -

- Precompiling your templates can be a big help when debugging errors you can't - reproduce. This is because precompiled templates can provide line numbers and - a stack trace, something that is not possible when compiling templates on the client. - The source property is available on the compiled template - function for easy precompilation. -

- -
<script>
-  JST.project = <%= _.template(jstText).source %>;
-</script>
- - -

Chaining

- -

- You can use Underscore in either an object-oriented or a functional style, - depending on your preference. The following two lines of code are - identical ways to double a list of numbers. -

- -
-_.map([1, 2, 3], function(n){ return n * 2; });
-_([1, 2, 3]).map(function(n){ return n * 2; });
- -

- Calling chain on a wrapped object will cause all future method calls to - return wrapped objects as well. When you've finished the computation, - use value to retrieve the final value. Here's an example of chaining - together a map/flatten/reduce, in order to get the word count of - every word in a song. -

- -
-var lyrics = [
-  {line : 1, words : "I'm a lumberjack and I'm okay"},
-  {line : 2, words : "I sleep all night and I work all day"},
-  {line : 3, words : "He's a lumberjack and he's okay"},
-  {line : 4, words : "He sleeps all night and he works all day"}
-];
-
-_.chain(lyrics)
-  .map(function(line) { return line.words.split(' '); })
-  .flatten()
-  .reduce(function(counts, word) {
-    counts[word] = (counts[word] || 0) + 1;
-    return counts;
-}, {}).value();
-
-=> {lumberjack : 2, all : 4, night : 2 ... }
- -

- In addition, the - Array prototype's methods - are proxied through the chained Underscore object, so you can slip a - reverse or a push into your chain, and continue to - modify the array. -

- -

- chain_.chain(obj) -
- Returns a wrapped object. Calling methods on this object will continue - to return wrapped objects until value is used. -

-
-var stooges = [{name : 'curly', age : 25}, {name : 'moe', age : 21}, {name : 'larry', age : 23}];
-var youngest = _.chain(stooges)
-  .sortBy(function(stooge){ return stooge.age; })
-  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
-  .first()
-  .value();
-=> "moe is 21"
-
- -

- value_(obj).value() -
- Extracts the value of a wrapped object. -

-
-_([1, 2, 3]).value();
-=> [1, 2, 3]
-
- - - -

- Underscore.lua, - a Lua port of the functions that are applicable in both languages. - Includes OOP-wrapping and chaining. - The source is - available on GitHub. -

- -

- Underscore.php, - a PHP port of the functions that are applicable in both languages. - Includes OOP-wrapping and chaining. - The source is - available on GitHub. -

- -

- Underscore-perl, - a Perl port of many of the Underscore.js functions, - aimed at on Perl hashes and arrays, also - available on GitHub. -

- -

- Underscore.string, - an Underscore extension that adds functions for string-manipulation: - trim, startsWith, contains, capitalize, - reverse, sprintf, and more. -

- -

- Ruby's Enumerable module. -

- -

- Prototype.js, which provides - JavaScript with collection functions in the manner closest to Ruby's Enumerable. -

- -

- Oliver Steele's - Functional JavaScript, - which includes comprehensive higher-order function support as well as string lambdas. -

- -

- Michael Aufreiter's Data.js, - a data manipulation + persistence library for JavaScript. -

- -

- Python's itertools. -

- -

Change Log

- -

- 1.3.3April 10, 2012
-

    -
  • - Many improvements to _.template, which now provides the - source of the template function as a property, for potentially - even more efficient pre-compilation on the server-side. You may now - also set the variable option when creating a template, - which will cause your passed-in data to be made available under the - variable you named, instead of using a with statement — - significantly improving the speed of rendering the template. -
  • -
  • - Added the pick function, which allows you to filter an - object literal with a whitelist of allowed property names. -
  • -
  • - Added the result function, for convenience when working - with APIs that allow either functions or raw properties. -
  • -
  • - Added the isFinite function, because sometimes knowing that - a value is a number just ain't quite enough. -
  • -
  • - The sortBy function may now also be passed the string name - of a property to use as the sort order on each object. -
  • -
  • - Fixed uniq to work with sparse arrays. -
  • -
  • - The difference function now performs a shallow flatten - instead of a deep one when computing array differences. -
  • -
  • - The debounce function now takes an immediate - parameter, which will cause the callback to fire on the leading - instead of the trailing edge. -
  • -
-

- -

- 1.3.1Jan. 23, 2012
-

    -
  • - Added an _.has function, as a safer way to use hasOwnProperty. -
  • -
  • - Added _.collect as an alias for _.map. Smalltalkers, rejoice. -
  • -
  • - Reverted an old change so that _.extend will correctly copy - over keys with undefined values again. -
  • -
  • - Bugfix to stop escaping slashes within interpolations in _.template. -
  • -
-

- -

- 1.3.0Jan. 11, 2012
-

    -
  • - Removed AMD (RequireJS) support from Underscore. If you'd like to use - Underscore with RequireJS, you can load it as a normal script, wrap - or patch your copy, or download a forked version. -
  • -
-

- -

- 1.2.4Jan. 4, 2012
-

    -
  • - You now can (and probably should, as it's simpler) - write _.chain(list) - instead of _(list).chain(). -
  • -
  • - Fix for escaped characters in Underscore templates, and for supporting - customizations of _.templateSettings that only define one or - two of the required regexes. -
  • -
  • - Fix for passing an array as the first argument to an _.wrap'd function. -
  • -
  • - Improved compatibility with ClojureScript, which adds a call - function to String.prototype. -
  • -
-

- -

- 1.2.3Dec. 7, 2011
-

    -
  • - Dynamic scope is now preserved for compiled _.template functions, - so you can use the value of this if you like. -
  • -
  • - Sparse array support of _.indexOf, _.lastIndexOf. -
  • -
  • - Both _.reduce and _.reduceRight can now be passed an - explicitly undefined value. (There's no reason why you'd - want to do this.) -
  • -
-

- -

- 1.2.2Nov. 14, 2011
-

    -
  • - Continued tweaks to _.isEqual semantics. Now JS primitives are - considered equivalent to their wrapped versions, and arrays are compared - by their numeric properties only (#351). -
  • -
  • - _.escape no longer tries to be smart about not double-escaping - already-escaped HTML entities. Now it just escapes regardless (#350). -
  • -
  • - In _.template, you may now leave semicolons out of evaluated - statements if you wish: <% }) %> (#369). -
  • -
  • - _.after(callback, 0) will now trigger the callback immediately, - making "after" easier to use with asynchronous APIs (#366). -
  • -
-

- -

- 1.2.1Oct. 24, 2011
-

    -
  • - Several important bug fixes for _.isEqual, which should now - do better on mutated Arrays, and on non-Array objects with - length properties. (#329) -
  • -
  • - jrburke contributed Underscore exporting for AMD module loaders, - and tonylukasavage for Appcelerator Titanium. - (#335, #338) -
  • -
  • - You can now _.groupBy(list, 'property') as a shortcut for - grouping values by a particular common property. -
  • -
  • - _.throttle'd functions now fire immediately upon invocation, - and are rate-limited thereafter (#170, #266). -
  • -
  • - Most of the _.is[Type] checks no longer ducktype. -
  • -
  • - The _.bind function now also works on constructors, a-la - ES5 ... but you would never want to use _.bind on a - constructor function. -
  • -
  • - _.clone no longer wraps non-object types in Objects. -
  • -
  • - _.find and _.filter are now the preferred names for - _.detect and _.select. -
  • -
-

- -

- 1.2.0Oct. 5, 2011
-

    -
  • - The _.isEqual function now - supports true deep equality comparisons, with checks for cyclic structures, - thanks to Kit Cambridge. -
  • -
  • - Underscore templates now support HTML escaping interpolations, using - <%- ... %> syntax. -
  • -
  • - Ryan Tenney contributed _.shuffle, which uses a modified - Fisher-Yates to give you a shuffled copy of an array. -
  • -
  • - _.uniq can now be passed an optional iterator, to determine by - what criteria an object should be considered unique. -
  • -
  • - _.last now takes an optional argument which will return the last - N elements of the list. -
  • -
  • - A new _.initial function was added, as a mirror of _.rest, - which returns all the initial values of a list (except the last N). -
  • -
-

- -

- 1.1.7July 13, 2011
- Added _.groupBy, which aggregates a collection into groups of like items. - Added _.union and _.difference, to complement the - (re-named) _.intersection. - Various improvements for support of sparse arrays. - _.toArray now returns a clone, if directly passed an array. - _.functions now also returns the names of functions that are present - in the prototype chain. -

- -

- 1.1.6April 18, 2011
- Added _.after, which will return a function that only runs after - first being called a specified number of times. - _.invoke can now take a direct function reference. - _.every now requires an iterator function to be passed, which - mirrors the ECMA5 API. - _.extend no longer copies keys when the value is undefined. - _.bind now errors when trying to bind an undefined value. -

- -

- 1.1.5Mar 20, 2011
- Added an _.defaults function, for use merging together JS objects - representing default options. - Added an _.once function, for manufacturing functions that should - only ever execute a single time. - _.bind now delegates to the native ECMAScript 5 version, - where available. - _.keys now throws an error when used on non-Object values, as in - ECMAScript 5. - Fixed a bug with _.keys when used over sparse arrays. -

- -

- 1.1.4Jan 9, 2011
- Improved compliance with ES5's Array methods when passing null - as a value. _.wrap now correctly sets this for the - wrapped function. _.indexOf now takes an optional flag for - finding the insertion index in an array that is guaranteed to already - be sorted. Avoiding the use of .callee, to allow _.isArray - to work properly in ES5's strict mode. -

- -

- 1.1.3Dec 1, 2010
- In CommonJS, Underscore may now be required with just:
- var _ = require("underscore"). - Added _.throttle and _.debounce functions. - Removed _.breakLoop, in favor of an ECMA5-style un-break-able - each implementation — this removes the try/catch, and you'll now have - better stack traces for exceptions that are thrown within an Underscore iterator. - Improved the isType family of functions for better interoperability - with Internet Explorer host objects. - _.template now correctly escapes backslashes in templates. - Improved _.reduce compatibility with the ECMA5 version: - if you don't pass an initial value, the first item in the collection is used. - _.each no longer returns the iterated collection, for improved - consistency with ES5's forEach. -

- -

- 1.1.2
- Fixed _.contains, which was mistakenly pointing at - _.intersect instead of _.include, like it should - have been. Added _.unique as an alias for _.uniq. -

- -

- 1.1.1
- Improved the speed of _.template, and its handling of multiline - interpolations. Ryan Tenney contributed optimizations to many Underscore - functions. An annotated version of the source code is now available. -

- -

- 1.1.0
- The method signature of _.reduce has been changed to match - the ECMAScript 5 signature, instead of the Ruby/Prototype.js version. - This is a backwards-incompatible change. _.template may now be - called with no arguments, and preserves whitespace. _.contains - is a new alias for _.include. -

- -

- 1.0.4
- Andri Möll contributed the _.memoize - function, which can be used to speed up expensive repeated computations - by caching the results. -

- -

- 1.0.3
- Patch that makes _.isEqual return false if any property - of the compared object has a NaN value. Technically the correct - thing to do, but of questionable semantics. Watch out for NaN comparisons. -

- -

- 1.0.2
- Fixes _.isArguments in recent versions of Opera, which have - arguments objects as real Arrays. -

- -

- 1.0.1
- Bugfix for _.isEqual, when comparing two objects with the same - number of undefined keys, but with different names. -

- -

- 1.0.0
- Things have been stable for many months now, so Underscore is now - considered to be out of beta, at 1.0. Improvements since 0.6 - include _.isBoolean, and the ability to have _.extend - take multiple source objects. -

- -

- 0.6.0
- Major release. Incorporates a number of - Mile Frawley's refactors for - safer duck-typing on collection functions, and cleaner internals. A new - _.mixin method that allows you to extend Underscore with utility - functions of your own. Added _.times, which works the same as in - Ruby or Prototype.js. Native support for ECMAScript 5's Array.isArray, - and Object.keys. -

- -

- 0.5.8
- Fixed Underscore's collection functions to work on - NodeLists and - HTMLCollections - once more, thanks to - Justin Tulloss. -

- -

- 0.5.7
- A safer implementation of _.isArguments, and a - faster _.isNumber,
thanks to - Jed Schmidt. -

- -

- 0.5.6
- Customizable delimiters for _.template, contributed by - Noah Sloan. -

- -

- 0.5.5
- Fix for a bug in MobileSafari's OOP-wrapper, with the arguments object. -

- -

- 0.5.4
- Fix for multiple single quotes within a template string for - _.template. See: - Rick Strahl's blog post. -

- -

- 0.5.2
- New implementations of isArray, isDate, isFunction, - isNumber, isRegExp, and isString, thanks to - a suggestion from - Robert Kieffer. - Instead of doing Object#toString - comparisons, they now check for expected properties, which is less safe, - but more than an order of magnitude faster. Most other Underscore - functions saw minor speed improvements as a result. - Evgeniy Dolzhenko - contributed _.tap, - similar to Ruby 1.9's, - which is handy for injecting side effects (like logging) into chained calls. -

- -

- 0.5.1
- Added an _.isArguments function. Lots of little safety checks - and optimizations contributed by - Noah Sloan and - Andri Möll. -

- -

- 0.5.0
- [API Changes] _.bindAll now takes the context object as - its first parameter. If no method names are passed, all of the context - object's methods are bound to it, enabling chaining and easier binding. - _.functions now takes a single argument and returns the names - of its Function properties. Calling _.functions(_) will get you - the previous behavior. - Added _.isRegExp so that isEqual can now test for RegExp equality. - All of the "is" functions have been shrunk down into a single definition. - Karl Guertin contributed patches. -

- -

- 0.4.7
- Added isDate, isNaN, and isNull, for completeness. - Optimizations for isEqual when checking equality between Arrays - or Dates. _.keys is now 25%–2X faster (depending on your - browser) which speeds up the functions that rely on it, such as _.each. -

- -

- 0.4.6
- Added the range function, a port of the - Python - function of the same name, for generating flexibly-numbered lists - of integers. Original patch contributed by - Kirill Ishanov. -

- -

- 0.4.5
- Added rest for Arrays and arguments objects, and aliased - first as head, and rest as tail, - thanks to Luke Sutton's patches. - Added tests ensuring that all Underscore Array functions also work on - arguments objects. -

- -

- 0.4.4
- Added isString, and isNumber, for consistency. Fixed - _.isEqual(NaN, NaN) to return true (which is debatable). -

- -

- 0.4.3
- Started using the native StopIteration object in browsers that support it. - Fixed Underscore setup for CommonJS environments. -

- -

- 0.4.2
- Renamed the unwrapping function to value, for clarity. -

- -

- 0.4.1
- Chained Underscore objects now support the Array prototype methods, so - that you can perform the full range of operations on a wrapped array - without having to break your chain. Added a breakLoop method - to break in the middle of any Underscore iteration. Added an - isEmpty function that works on arrays and objects. -

- -

- 0.4.0
- All Underscore functions can now be called in an object-oriented style, - like so: _([1, 2, 3]).map(...);. Original patch provided by - Marc-André Cournoyer. - Wrapped objects can be chained through multiple - method invocations. A functions method - was added, providing a sorted list of all the functions in Underscore. -

- -

- 0.3.3
- Added the JavaScript 1.8 function reduceRight. Aliased it - as foldr, and aliased reduce as foldl. -

- -

- 0.3.2
- Now runs on stock Rhino - interpreters with: load("underscore.js"). - Added identity as a utility function. -

- -

- 0.3.1
- All iterators are now passed in the original collection as their third - argument, the same as JavaScript 1.6's forEach. Iterating over - objects is now called with (value, key, collection), for details - see _.each. -

- -

- 0.3.0
- Added Dmitry Baranovskiy's - comprehensive optimizations, merged in - Kris Kowal's patches to make Underscore - CommonJS and - Narwhal compliant. -

- -

- 0.2.0
- Added compose and lastIndexOf, renamed inject to - reduce, added aliases for inject, filter, - every, some, and forEach. -

- -

- 0.1.1
- Added noConflict, so that the "Underscore" object can be assigned to - other variables. -

- -

- 0.1.0
- Initial release of Underscore.js. -

- -

- - A DocumentCloud Project - -

- -
- -
- - - - - - diff --git a/node_modules/underscore/index.js b/node_modules/underscore/index.js deleted file mode 100644 index 2cf0ca5..0000000 --- a/node_modules/underscore/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./underscore'); diff --git a/node_modules/underscore/package.json b/node_modules/underscore/package.json deleted file mode 100644 index c573dae..0000000 --- a/node_modules/underscore/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name" : "underscore", - "description" : "JavaScript's functional programming helper library.", - "homepage" : "http://documentcloud.github.com/underscore/", - "keywords" : ["util", "functional", "server", "client", "browser"], - "author" : "Jeremy Ashkenas ", - "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, - "main" : "underscore.js", - "version" : "1.3.3" -} diff --git a/node_modules/underscore/raw/underscore.psd b/node_modules/underscore/raw/underscore.psd deleted file mode 100644 index 73ad2d7c8eebce69b4f46f31c0a1a8c2d523bc0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215540 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 diff --git a/node_modules/underscore/underscore-min.js b/node_modules/underscore/underscore-min.js deleted file mode 100644 index 5a0cb3b..0000000 --- a/node_modules/underscore/underscore-min.js +++ /dev/null @@ -1,32 +0,0 @@ -// Underscore.js 1.3.3 -// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore is freely distributable under the MIT license. -// Portions of Underscore are inspired or borrowed from Prototype, -// Oliver Steele's Functional, and John Resig's Micro-Templating. -// For all details and documentation: -// http://documentcloud.github.com/underscore -(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== -c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break; -g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a, -c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(A&& -a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a, -c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b, -a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= -function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]}; -j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a= -i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&& -c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty= -function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"}; -b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a, -b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId= -function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape|| -u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c}; -b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d, -this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); diff --git a/node_modules/underscore/underscore.js b/node_modules/underscore/underscore.js deleted file mode 100644 index f6f7e2f..0000000 --- a/node_modules/underscore/underscore.js +++ /dev/null @@ -1,1059 +0,0 @@ -// Underscore.js 1.3.3 -// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore is freely distributable under the MIT license. -// Portions of Underscore are inspired or borrowed from Prototype, -// Oliver Steele's Functional, and John Resig's Micro-Templating. -// For all details and documentation: -// http://documentcloud.github.com/underscore - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `global` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var slice = ArrayProto.slice, - unshift = ArrayProto.unshift, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { return new wrapper(obj); }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root['_'] = _; - } - - // Current version. - _.VERSION = '1.3.3'; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // 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) { - for (var i = 0, l = obj.length; i < l; i++) { - if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - for (var key in obj) { - if (_.has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === breaker) return; - } - } - } - }; - - // Return the results of applying the iterator to each element. - // 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); - }); - if (obj.length === +obj.length) results.length = obj.length; - return results; - }; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // 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); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError('Reduce of empty array with no initial value'); - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - // 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 initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); - } - var reversed = _.toArray(obj).reverse(); - if (context && !initial) iterator = _.bind(iterator, context); - return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator); - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { - var result; - any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // 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; - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - each(obj, function(value, index, list) { - if (!iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - 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; - }); - return !!result; - }; - - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - 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; - }); - return !!result; - }; - - // Determine if a given value is included in the array or object using `===`. - // Aliased as `contains`. - _.include = _.contains = 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; - }); - return found; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - return _.map(obj, function(value) { - return (_.isFunction(method) ? method || value : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); - }; - - // Return the maximum element or (element-based computation). - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.max.apply(Math, obj); - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed >= result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.min.apply(Math, obj); - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Shuffle an array. - _.shuffle = function(obj) { - var shuffled = [], rand; - each(obj, function(value, index, list) { - rand = Math.floor(Math.random() * (index + 1)); - shuffled[index] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; - - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, val, context) { - var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; - return _.pluck(_.map(obj, function(value, index, list) { - return { - value : value, - criteria : iterator.call(context, value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - if (a === void 0) return 1; - if (b === void 0) return -1; - return a < b ? -1 : a > b ? 1 : 0; - }), 'value'); - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = function(obj, val) { - var result = {}; - var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; - each(obj, function(value, index) { - var key = iterator(value, index); - (result[key] || (result[key] = [])).push(value); - }); - return result; - }; - - // Use a comparator function to figure out at what index an object should - // be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iterator) { - iterator || (iterator = _.identity); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >> 1; - iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; - } - return low; - }; - - // Safely convert anything iterable into a real, live array. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (_.isArguments(obj)) return slice.call(obj); - if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray(); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - return _.isArray(obj) ? obj.length : _.keys(obj).length; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // 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) { - return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; - }; - - // Returns everything but the last entry of the array. Especcialy useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); - }; - - // 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 ((n != null) && !guard) { - return slice.call(array, Math.max(array.length - n, 0)); - } else { - return array[array.length - 1]; - } - }; - - // Returns everything but the first entry of the array. Aliased as `tail`. - // Especially useful on the arguments object. Passing an **index** will return - // the rest of the values in the array from that index onward. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = function(array, index, guard) { - return slice.call(array, (index == null) || guard ? 1 : index); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, function(value){ return !!value; }); - }; - - // Return a completely flattened version of an array. - _.flatten = function(array, shallow) { - return _.reduce(array, function(memo, value) { - if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value)); - memo[memo.length] = value; - return memo; - }, []); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iterator) { - var initial = iterator ? _.map(array, iterator) : array; - var results = []; - // The `isSorted` flag is irrelevant if the array only contains two elements. - if (array.length < 3) isSorted = true; - _.reduce(initial, function (memo, value, index) { - if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) { - memo.push(value); - results.push(array[index]); - } - return memo; - }, []); - return results; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(_.flatten(arguments, true)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. (Aliased as "intersect" for back-compat.) - _.intersection = _.intersect = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; - }); - }); - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = _.flatten(slice.call(arguments, 1), true); - return _.filter(array, function(value){ return !_.include(rest, value); }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - var args = slice.call(arguments); - var length = _.max(_.pluck(args, 'length')); - var results = new Array(length); - for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); - return results; - }; - - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // 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, l; - if (isSorted) { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); - for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i; - return -1; - }; - - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item) { - if (array == null) return -1; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); - var i = array.length; - while (i--) if (i in array && array[i] === item) return i; - return -1; - }; - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; - - var len = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(len); - - while(idx < len) { - range[idx++] = start; - start += step; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Reusable constructor function for prototype setting. - var ctor = function(){}; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Binding with arguments is also known as `curry`. - // Delegates to **ECMAScript 5**'s native `Function.bind` if available. - // We check for `func.bind` first, to fail fast when `func` is undefined. - _.bind = function bind(func, context) { - var bound, args; - if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - if (!_.isFunction(func)) throw new TypeError; - args = slice.call(arguments, 2); - return bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - ctor.prototype = func.prototype; - var self = new ctor; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (Object(result) === result) return result; - return self; - }; - }; - - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length == 0) funcs = _.functions(obj); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // 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); - return function() { - context = this; args = arguments; - var later = function() { - timeout = null; - if (more) func.apply(context, args); - whenDone(); - }; - if (!timeout) timeout = setTimeout(later, wait); - if (throttling) { - more = true; - } else { - result = func.apply(context, args); - } - whenDone(); - throttling = true; - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - if (immediate && !timeout) func.apply(context, args); - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - return memo = func.apply(this, arguments); - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return function() { - var args = [func].concat(slice.call(arguments, 0)); - return wrapper.apply(this, args); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - if (times <= 0) return func(); - return function() { - if (--times < 1) { return func.apply(this, arguments); } - }; - }; - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - return _.map(obj, _.identity); - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - each(slice.call(arguments, 1), function(source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - }); - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var result = {}; - each(_.flatten(slice.call(arguments, 1)), function(key) { - if (key in obj) result[key] = obj[key]; - }); - return result; - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - for (var prop in source) { - if (obj[prop] == null) obj[prop] = source[prop]; - } - }); - return obj; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Internal recursive comparison function. - function eq(a, b, stack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. - if (a === b) return a !== 0 || 1 / a == 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a._chain) a = a._wrapped; - if (b._chain) b = b._wrapped; - // Invoke a custom `isEqual` method if one is provided. - if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b); - if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a); - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className != toString.call(b)) return false; - switch (className) { - // Strings, numbers, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a == +b; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; - } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = stack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (stack[length] == a) return true; - } - // Add the first object to the stack of traversed objects. - stack.push(a); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - // Ensure commutative equality for sparse arrays. - if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break; - } - } - } else { - // Objects with different constructors are not equivalent. - if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false; - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } - } - // Remove the first object from the stack of traversed objects. - stack.pop(); - return result; - } - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType == 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - return obj === Object(obj); - }; - - // Is a given variable an arguments object? - _.isArguments = function(obj) { - return toString.call(obj) == '[object Arguments]'; - }; - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; - } - - // Is a given value a function? - _.isFunction = function(obj) { - return toString.call(obj) == '[object Function]'; - }; - - // Is a given value a string? - _.isString = function(obj) { - return toString.call(obj) == '[object String]'; - }; - - // Is a given value a number? - _.isNumber = function(obj) { - return toString.call(obj) == '[object Number]'; - }; - - // Is a given object a finite number? - _.isFinite = function(obj) { - return _.isNumber(obj) && isFinite(obj); - }; - - // Is the given value `NaN`? - _.isNaN = function(obj) { - // `NaN` is the only value for which `===` is not reflexive. - return obj !== obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; - }; - - // Is a given value a date? - _.isDate = function(obj) { - return toString.call(obj) == '[object Date]'; - }; - - // Is the given value a regular expression? - _.isRegExp = function(obj) { - return toString.call(obj) == '[object RegExp]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Has own property? - _.has = function(obj, key) { - return hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iterators. - _.identity = function(value) { - return value; - }; - - // Run a function **n** times. - _.times = function (n, iterator, context) { - for (var i = 0; i < n; i++) iterator.call(context, i); - }; - - // Escape a string for HTML interpolation. - _.escape = function(string) { - return (''+string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); - }; - - // If the value of the named property is a function then invoke it; - // otherwise, return it. - _.result = function(object, property) { - if (object == null) return null; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; - - // Add your own custom functions to the Underscore object, ensuring that - // they're correctly added to the OOP wrapper as well. - _.mixin = function(obj) { - each(_.functions(obj), function(name){ - addToWrapper(name, _[name] = obj[name]); - }); - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = idCounter++; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /.^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - '\\': '\\', - "'": "'", - 'r': '\r', - 'n': '\n', - 't': '\t', - 'u2028': '\u2028', - 'u2029': '\u2029' - }; - - for (var p in escapes) escapes[escapes[p]] = p; - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; - var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g; - - // Within an interpolation, evaluation, or escaping, remove HTML escaping - // that had been previously added. - var unescape = function(code) { - return code.replace(unescaper, function(match, escape) { - return escapes[escape]; - }); - }; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - settings = _.defaults(settings || {}, _.templateSettings); - - // Compile the template source, taking care to escape characters that - // cannot be included in a string literal and then unescape them in code - // blocks. - var source = "__p+='" + text - .replace(escaper, function(match) { - return '\\' + escapes[match]; - }) - .replace(settings.escape || noMatch, function(match, code) { - return "'+\n_.escape(" + unescape(code) + ")+\n'"; - }) - .replace(settings.interpolate || noMatch, function(match, code) { - return "'+\n(" + unescape(code) + ")+\n'"; - }) - .replace(settings.evaluate || noMatch, function(match, code) { - return "';\n" + unescape(code) + "\n;__p+='"; - }) + "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __p='';" + - "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" + - source + "return __p;\n"; - - var render = new Function(settings.variable || 'obj', '_', source); - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled function source as a convenience for build time - // precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + - source + '}'; - - return template; - }; - - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; - - // The OOP Wrapper - // --------------- - - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - var wrapper = function(obj) { this._wrapped = obj; }; - - // Expose `wrapper.prototype` as `_.prototype` - _.prototype = wrapper.prototype; - - // Helper function to continue chaining intermediate results. - var result = function(obj, chain) { - return chain ? _(obj).chain() : obj; - }; - - // A method to easily add functions to the OOP wrapper. - var addToWrapper = function(name, func) { - wrapper.prototype[name] = function() { - var args = slice.call(arguments); - unshift.call(args, this._wrapped); - return result(func.apply(_, args), this._chain); - }; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - wrapper.prototype[name] = function() { - var wrapped = this._wrapped; - method.apply(wrapped, arguments); - var length = wrapped.length; - if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0]; - return result(wrapped, this._chain); - }; - }); - - // Add all accessor Array functions to the wrapper. - each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - wrapper.prototype[name] = function() { - return result(method.apply(this._wrapped, arguments), this._chain); - }; - }); - - // Start chaining a wrapped Underscore object. - wrapper.prototype.chain = function() { - this._chain = true; - return this; - }; - - // Extracts the result from a wrapped and chained object. - wrapper.prototype.value = function() { - return this._wrapped; - }; - -}).call(this);