backbone-relational-hal
Advanced tools
Comparing version 0.1.2 to 0.1.3
/*! | ||
* backbone-relational-hal v0.1.2 | ||
* backbone-relational-hal v0.1.3 | ||
* Copyright (c) 2014 Simon Oulevay | ||
@@ -4,0 +4,0 @@ * Distributed under MIT license |
/*! | ||
* backbone-relational-hal v0.1.2 | ||
* backbone-relational-hal v0.1.3 | ||
* Copyright (c) 2014 Simon Oulevay | ||
@@ -4,0 +4,0 @@ * Distributed under MIT license |
@@ -44,2 +44,14 @@ module.exports = function(grunt) { | ||
copy: { | ||
vendor: { | ||
files: [ | ||
{ nonull: true, src: 'bower_components/underscore/underscore.js', dest: 'vendor/underscore.js' }, | ||
{ nonull: true, src: 'bower_components/jquery/dist/jquery.js', dest: 'vendor/jquery.js' }, | ||
{ nonull: true, src: 'bower_components/uri-templates/uri-templates.js', dest: 'vendor/uri-templates.js' }, | ||
{ nonull: true, src: 'bower_components/backbone/backbone.js', dest: 'vendor/backbone.js' }, | ||
{ nonull: true, src: 'bower_components/backbone-relational/backbone-relational.js', dest: 'vendor/backbone-relational.js' } | ||
] | ||
} | ||
}, | ||
jasmine: { | ||
@@ -76,8 +88,10 @@ standard: { | ||
grunt.loadNpmTasks('grunt-bump'); | ||
grunt.loadNpmTasks('grunt-contrib-concat'); | ||
grunt.loadNpmTasks('grunt-contrib-copy'); | ||
grunt.loadNpmTasks('grunt-contrib-jasmine'); | ||
grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
grunt.loadNpmTasks('grunt-contrib-concat'); | ||
grunt.loadNpmTasks('grunt-contrib-uglify'); | ||
grunt.loadNpmTasks('grunt-contrib-jasmine'); | ||
grunt.registerTask('default', [ 'jshint', 'concat', 'jasmine', 'uglify' ]); | ||
grunt.registerTask('vendor', [ 'copy:vendor' ]); | ||
}; |
{ | ||
"name": "backbone-relational-hal", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"description": "Use HAL+JSON with Backbone.js and Backbone-relational.js.", | ||
@@ -27,8 +27,9 @@ "keywords": [ | ||
"grunt": "~0.4.2", | ||
"grunt-contrib-jshint": "~0.6.3", | ||
"grunt-contrib-uglify": "~0.2.2", | ||
"grunt-bump": "0.0.13", | ||
"grunt-contrib-concat": "~0.3.0", | ||
"grunt-contrib-copy": "^0.5.0", | ||
"grunt-contrib-jasmine": "~0.6.1", | ||
"grunt-contrib-concat": "~0.3.0" | ||
"grunt-contrib-jshint": "~0.6.3", | ||
"grunt-contrib-uglify": "~0.2.2" | ||
} | ||
} |
@@ -10,12 +10,18 @@ # backbone-relational-hal | ||
**backbone-relational-hal** is currently working with the following libraries: | ||
**backbone-relational-hal** is currently tested with the following libraries: | ||
* [Underscore](http://underscorejs.org) v1.6.0 | ||
* [jQuery](http://jquery.com) v2.1.0 | ||
* [uri-templates](https://github.com/geraintluff/uri-templates) v0.1.2 | ||
* [Underscore](http://underscorejs.org) v1.7.0 | ||
* [jQuery](http://jquery.com) v2.1.1 | ||
* [uri-templates](https://github.com/geraintluff/uri-templates) v0.1.5 | ||
* [Backbone.js](http://backbonejs.org) v1.1.2 | ||
* [Backbone-relational.js](http://backbonerelational.org) v0.8.7 | ||
* [Backbone-relational.js](http://backbonerelational.org) v0.8.8 | ||
## Installation | ||
With bower: | ||
bower install --save backbone-relational-hal | ||
Builds: | ||
* Development: [backbone-relational-hal.js](https://raw.github.com/AlphaHydrae/backbone-relational-hal/master/backbone-relational-hal.js) | ||
@@ -22,0 +28,0 @@ * Production: [backbone-relational-hal.min.js](https://raw.github.com/AlphaHydrae/backbone-relational-hal/master/backbone-relational-hal.min.js) |
- make deferred and error/success callbacks behave the same way as in backbone when using fetchHalResource & fetchHalUrl | ||
- update package.json description | ||
- fetch: don't load self multiple times |
@@ -1,2 +0,2 @@ | ||
// Underscore.js 1.6.0 | ||
// Underscore.js 1.7.0 | ||
// http://underscorejs.org | ||
@@ -17,5 +17,2 @@ // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors | ||
// Establish the object that gets returned to break out of a loop iteration. | ||
var breaker = {}; | ||
// Save bytes in the minified (but not gzipped) version: | ||
@@ -35,11 +32,2 @@ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; | ||
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, | ||
@@ -58,4 +46,3 @@ nativeKeys = Object.keys, | ||
// 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. | ||
// the browser, add `_` as a global object. | ||
if (typeof exports !== 'undefined') { | ||
@@ -71,4 +58,38 @@ if (typeof module !== 'undefined' && module.exports) { | ||
// Current version. | ||
_.VERSION = '1.6.0'; | ||
_.VERSION = '1.7.0'; | ||
// Internal function that returns an efficient (for current engines) version | ||
// of the passed-in callback, to be repeatedly applied in other Underscore | ||
// functions. | ||
var createCallback = function(func, context, argCount) { | ||
if (context === void 0) return func; | ||
switch (argCount == null ? 3 : argCount) { | ||
case 1: return function(value) { | ||
return func.call(context, value); | ||
}; | ||
case 2: return function(value, other) { | ||
return func.call(context, value, other); | ||
}; | ||
case 3: return function(value, index, collection) { | ||
return func.call(context, value, index, collection); | ||
}; | ||
case 4: return function(accumulator, value, index, collection) { | ||
return func.call(context, accumulator, value, index, collection); | ||
}; | ||
} | ||
return function() { | ||
return func.apply(context, arguments); | ||
}; | ||
}; | ||
// A mostly-internal function to generate callbacks that can be applied | ||
// to each element in a collection, returning the desired result — either | ||
// identity, an arbitrary callback, a property matcher, or a property accessor. | ||
_.iteratee = function(value, context, argCount) { | ||
if (value == null) return _.identity; | ||
if (_.isFunction(value)) return createCallback(value, context, argCount); | ||
if (_.isObject(value)) return _.matches(value); | ||
return _.property(value); | ||
}; | ||
// Collection Functions | ||
@@ -78,16 +99,16 @@ // -------------------- | ||
// 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) { | ||
// Handles raw objects in addition to array-likes. Treats all | ||
// sparse array-likes as if they were dense. | ||
_.each = _.forEach = function(obj, iteratee, context) { | ||
if (obj == null) return obj; | ||
if (nativeForEach && obj.forEach === nativeForEach) { | ||
obj.forEach(iterator, context); | ||
} else if (obj.length === +obj.length) { | ||
for (var i = 0, length = obj.length; i < length; i++) { | ||
if (iterator.call(context, obj[i], i, obj) === breaker) return; | ||
iteratee = createCallback(iteratee, context); | ||
var i, length = obj.length; | ||
if (length === +length) { | ||
for (i = 0; i < length; i++) { | ||
iteratee(obj[i], i, obj); | ||
} | ||
} else { | ||
var keys = _.keys(obj); | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; | ||
for (i = 0, length = keys.length; i < length; i++) { | ||
iteratee(obj[keys[i]], keys[i], obj); | ||
} | ||
@@ -98,11 +119,14 @@ } | ||
// 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.push(iterator.call(context, value, index, list)); | ||
}); | ||
// Return the results of applying the iteratee to each element. | ||
_.map = _.collect = function(obj, iteratee, context) { | ||
if (obj == null) return []; | ||
iteratee = _.iteratee(iteratee, context); | ||
var keys = obj.length !== +obj.length && _.keys(obj), | ||
length = (keys || obj).length, | ||
results = Array(length), | ||
currentKey; | ||
for (var index = 0; index < length; index++) { | ||
currentKey = keys ? keys[index] : index; | ||
results[index] = iteratee(obj[currentKey], currentKey, obj); | ||
} | ||
return results; | ||
@@ -114,19 +138,17 @@ }; | ||
// **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; | ||
// or `foldl`. | ||
_.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) { | ||
if (obj == null) obj = []; | ||
if (nativeReduce && obj.reduce === nativeReduce) { | ||
if (context) iterator = _.bind(iterator, context); | ||
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); | ||
iteratee = createCallback(iteratee, context, 4); | ||
var keys = obj.length !== +obj.length && _.keys(obj), | ||
length = (keys || obj).length, | ||
index = 0, currentKey; | ||
if (arguments.length < 3) { | ||
if (!length) throw new TypeError(reduceError); | ||
memo = obj[keys ? keys[index++] : index++]; | ||
} | ||
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(reduceError); | ||
for (; index < length; index++) { | ||
currentKey = keys ? keys[index] : index; | ||
memo = iteratee(memo, obj[currentKey], currentKey, obj); | ||
} | ||
return memo; | ||
@@ -136,25 +158,16 @@ }; | ||
// 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; | ||
_.reduceRight = _.foldr = function(obj, iteratee, memo, context) { | ||
if (obj == null) obj = []; | ||
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { | ||
if (context) iterator = _.bind(iterator, context); | ||
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); | ||
iteratee = createCallback(iteratee, context, 4); | ||
var keys = obj.length !== + obj.length && _.keys(obj), | ||
index = (keys || obj).length, | ||
currentKey; | ||
if (arguments.length < 3) { | ||
if (!index) throw new TypeError(reduceError); | ||
memo = obj[keys ? keys[--index] : --index]; | ||
} | ||
var length = obj.length; | ||
if (length !== +length) { | ||
var keys = _.keys(obj); | ||
length = keys.length; | ||
while (index--) { | ||
currentKey = keys ? keys[index] : index; | ||
memo = iteratee(memo, obj[currentKey], currentKey, obj); | ||
} | ||
each(obj, function(value, index, list) { | ||
index = keys ? keys[--length] : --length; | ||
if (!initial) { | ||
memo = obj[index]; | ||
initial = true; | ||
} else { | ||
memo = iterator.call(context, memo, obj[index], index, list); | ||
} | ||
}); | ||
if (!initial) throw new TypeError(reduceError); | ||
return memo; | ||
@@ -166,4 +179,5 @@ }; | ||
var result; | ||
any(obj, function(value, index, list) { | ||
if (predicate.call(context, value, index, list)) { | ||
predicate = _.iteratee(predicate, context); | ||
_.some(obj, function(value, index, list) { | ||
if (predicate(value, index, list)) { | ||
result = value; | ||
@@ -177,3 +191,2 @@ return true; | ||
// Return all the elements that pass a truth test. | ||
// Delegates to **ECMAScript 5**'s native `filter` if available. | ||
// Aliased as `select`. | ||
@@ -183,5 +196,5 @@ _.filter = _.select = function(obj, predicate, context) { | ||
if (obj == null) return results; | ||
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); | ||
each(obj, function(value, index, list) { | ||
if (predicate.call(context, value, index, list)) results.push(value); | ||
predicate = _.iteratee(predicate, context); | ||
_.each(obj, function(value, index, list) { | ||
if (predicate(value, index, list)) results.push(value); | ||
}); | ||
@@ -193,33 +206,33 @@ return results; | ||
_.reject = function(obj, predicate, context) { | ||
return _.filter(obj, function(value, index, list) { | ||
return !predicate.call(context, value, index, list); | ||
}, context); | ||
return _.filter(obj, _.negate(_.iteratee(predicate)), context); | ||
}; | ||
// 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, predicate, context) { | ||
predicate || (predicate = _.identity); | ||
var result = true; | ||
if (obj == null) return result; | ||
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context); | ||
each(obj, function(value, index, list) { | ||
if (!(result = result && predicate.call(context, value, index, list))) return breaker; | ||
}); | ||
return !!result; | ||
if (obj == null) return true; | ||
predicate = _.iteratee(predicate, context); | ||
var keys = obj.length !== +obj.length && _.keys(obj), | ||
length = (keys || obj).length, | ||
index, currentKey; | ||
for (index = 0; index < length; index++) { | ||
currentKey = keys ? keys[index] : index; | ||
if (!predicate(obj[currentKey], currentKey, obj)) return false; | ||
} | ||
return true; | ||
}; | ||
// 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, predicate, context) { | ||
predicate || (predicate = _.identity); | ||
var result = false; | ||
if (obj == null) return result; | ||
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); | ||
each(obj, function(value, index, list) { | ||
if (result || (result = predicate.call(context, value, index, list))) return breaker; | ||
}); | ||
return !!result; | ||
_.some = _.any = function(obj, predicate, context) { | ||
if (obj == null) return false; | ||
predicate = _.iteratee(predicate, context); | ||
var keys = obj.length !== +obj.length && _.keys(obj), | ||
length = (keys || obj).length, | ||
index, currentKey; | ||
for (index = 0; index < length; index++) { | ||
currentKey = keys ? keys[index] : index; | ||
if (predicate(obj[currentKey], currentKey, obj)) return true; | ||
} | ||
return false; | ||
}; | ||
@@ -231,6 +244,4 @@ | ||
if (obj == null) return false; | ||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; | ||
return any(obj, function(value) { | ||
return value === target; | ||
}); | ||
if (obj.length !== +obj.length) obj = _.values(obj); | ||
return _.indexOf(obj, target) >= 0; | ||
}; | ||
@@ -264,17 +275,24 @@ | ||
// Return the maximum element or (element-based computation). | ||
// Can't optimize arrays of integers longer than 65,535 elements. | ||
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797) | ||
_.max = function(obj, iterator, context) { | ||
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { | ||
return Math.max.apply(Math, obj); | ||
// Return the maximum element (or element-based computation). | ||
_.max = function(obj, iteratee, context) { | ||
var result = -Infinity, lastComputed = -Infinity, | ||
value, computed; | ||
if (iteratee == null && obj != null) { | ||
obj = obj.length === +obj.length ? obj : _.values(obj); | ||
for (var i = 0, length = obj.length; i < length; i++) { | ||
value = obj[i]; | ||
if (value > result) { | ||
result = value; | ||
} | ||
} | ||
} else { | ||
iteratee = _.iteratee(iteratee, context); | ||
_.each(obj, function(value, index, list) { | ||
computed = iteratee(value, index, list); | ||
if (computed > lastComputed || computed === -Infinity && result === -Infinity) { | ||
result = value; | ||
lastComputed = computed; | ||
} | ||
}); | ||
} | ||
var result = -Infinity, lastComputed = -Infinity; | ||
each(obj, function(value, index, list) { | ||
var computed = iterator ? iterator.call(context, value, index, list) : value; | ||
if (computed > lastComputed) { | ||
result = value; | ||
lastComputed = computed; | ||
} | ||
}); | ||
return result; | ||
@@ -284,28 +302,37 @@ }; | ||
// Return the minimum element (or element-based computation). | ||
_.min = function(obj, iterator, context) { | ||
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { | ||
return Math.min.apply(Math, obj); | ||
_.min = function(obj, iteratee, context) { | ||
var result = Infinity, lastComputed = Infinity, | ||
value, computed; | ||
if (iteratee == null && obj != null) { | ||
obj = obj.length === +obj.length ? obj : _.values(obj); | ||
for (var i = 0, length = obj.length; i < length; i++) { | ||
value = obj[i]; | ||
if (value < result) { | ||
result = value; | ||
} | ||
} | ||
} else { | ||
iteratee = _.iteratee(iteratee, context); | ||
_.each(obj, function(value, index, list) { | ||
computed = iteratee(value, index, list); | ||
if (computed < lastComputed || computed === Infinity && result === Infinity) { | ||
result = value; | ||
lastComputed = computed; | ||
} | ||
}); | ||
} | ||
var result = Infinity, lastComputed = Infinity; | ||
each(obj, function(value, index, list) { | ||
var computed = iterator ? iterator.call(context, value, index, list) : value; | ||
if (computed < lastComputed) { | ||
result = value; | ||
lastComputed = computed; | ||
} | ||
}); | ||
return result; | ||
}; | ||
// Shuffle an array, using the modern version of the | ||
// Shuffle a collection, using the modern version of the | ||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). | ||
_.shuffle = function(obj) { | ||
var rand; | ||
var index = 0; | ||
var shuffled = []; | ||
each(obj, function(value) { | ||
rand = _.random(index++); | ||
shuffled[index - 1] = shuffled[rand]; | ||
shuffled[rand] = value; | ||
}); | ||
var set = obj && obj.length === +obj.length ? obj : _.values(obj); | ||
var length = set.length; | ||
var shuffled = Array(length); | ||
for (var index = 0, rand; index < length; index++) { | ||
rand = _.random(0, index); | ||
if (rand !== index) shuffled[index] = shuffled[rand]; | ||
shuffled[rand] = set[index]; | ||
} | ||
return shuffled; | ||
@@ -325,12 +352,5 @@ }; | ||
// An internal function to generate lookup iterators. | ||
var lookupIterator = function(value) { | ||
if (value == null) return _.identity; | ||
if (_.isFunction(value)) return value; | ||
return _.property(value); | ||
}; | ||
// Sort the object's values by a criterion produced by an iterator. | ||
_.sortBy = function(obj, iterator, context) { | ||
iterator = lookupIterator(iterator); | ||
// Sort the object's values by a criterion produced by an iteratee. | ||
_.sortBy = function(obj, iteratee, context) { | ||
iteratee = _.iteratee(iteratee, context); | ||
return _.pluck(_.map(obj, function(value, index, list) { | ||
@@ -340,3 +360,3 @@ return { | ||
index: index, | ||
criteria: iterator.call(context, value, index, list) | ||
criteria: iteratee(value, index, list) | ||
}; | ||
@@ -356,8 +376,8 @@ }).sort(function(left, right) { | ||
var group = function(behavior) { | ||
return function(obj, iterator, context) { | ||
return function(obj, iteratee, context) { | ||
var result = {}; | ||
iterator = lookupIterator(iterator); | ||
each(obj, function(value, index) { | ||
var key = iterator.call(context, value, index, obj); | ||
behavior(result, key, value); | ||
iteratee = _.iteratee(iteratee, context); | ||
_.each(obj, function(value, index) { | ||
var key = iteratee(value, index, obj); | ||
behavior(result, value, key); | ||
}); | ||
@@ -370,4 +390,4 @@ return result; | ||
// to group by, or a function that returns the criterion. | ||
_.groupBy = group(function(result, key, value) { | ||
_.has(result, key) ? result[key].push(value) : result[key] = [value]; | ||
_.groupBy = group(function(result, value, key) { | ||
if (_.has(result, key)) result[key].push(value); else result[key] = [value]; | ||
}); | ||
@@ -377,3 +397,3 @@ | ||
// when you know that your index values will be unique. | ||
_.indexBy = group(function(result, key, value) { | ||
_.indexBy = group(function(result, value, key) { | ||
result[key] = value; | ||
@@ -385,4 +405,4 @@ }); | ||
// criterion. | ||
_.countBy = group(function(result, key) { | ||
_.has(result, key) ? result[key]++ : result[key] = 1; | ||
_.countBy = group(function(result, value, key) { | ||
if (_.has(result, key)) result[key]++; else result[key] = 1; | ||
}); | ||
@@ -392,9 +412,9 @@ | ||
// an object should be inserted so as to maintain order. Uses binary search. | ||
_.sortedIndex = function(array, obj, iterator, context) { | ||
iterator = lookupIterator(iterator); | ||
var value = iterator.call(context, obj); | ||
_.sortedIndex = function(array, obj, iteratee, context) { | ||
iteratee = _.iteratee(iteratee, context, 1); | ||
var value = iteratee(obj); | ||
var low = 0, high = array.length; | ||
while (low < high) { | ||
var mid = (low + high) >>> 1; | ||
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; | ||
var mid = low + high >>> 1; | ||
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; | ||
} | ||
@@ -415,5 +435,16 @@ return low; | ||
if (obj == null) return 0; | ||
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; | ||
return obj.length === +obj.length ? obj.length : _.keys(obj).length; | ||
}; | ||
// Split a collection into two arrays: one whose elements all satisfy the given | ||
// predicate, and one whose elements all do not satisfy the predicate. | ||
_.partition = function(obj, predicate, context) { | ||
predicate = _.iteratee(predicate, context); | ||
var pass = [], fail = []; | ||
_.each(obj, function(value, key, obj) { | ||
(predicate(value, key, obj) ? pass : fail).push(value); | ||
}); | ||
return [pass, fail]; | ||
}; | ||
// Array Functions | ||
@@ -427,3 +458,3 @@ // --------------- | ||
if (array == null) return void 0; | ||
if ((n == null) || guard) return array[0]; | ||
if (n == null || guard) return array[0]; | ||
if (n < 0) return []; | ||
@@ -438,3 +469,3 @@ return slice.call(array, 0, n); | ||
_.initial = function(array, n, guard) { | ||
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); | ||
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); | ||
}; | ||
@@ -446,3 +477,3 @@ | ||
if (array == null) return void 0; | ||
if ((n == null) || guard) return array[array.length - 1]; | ||
if (n == null || guard) return array[array.length - 1]; | ||
return slice.call(array, Math.max(array.length - n, 0)); | ||
@@ -456,3 +487,3 @@ }; | ||
_.rest = _.tail = _.drop = function(array, n, guard) { | ||
return slice.call(array, (n == null) || guard ? 1 : n); | ||
return slice.call(array, n == null || guard ? 1 : n); | ||
}; | ||
@@ -466,13 +497,16 @@ | ||
// Internal implementation of a recursive `flatten` function. | ||
var flatten = function(input, shallow, output) { | ||
var flatten = function(input, shallow, strict, output) { | ||
if (shallow && _.every(input, _.isArray)) { | ||
return concat.apply(output, input); | ||
} | ||
each(input, function(value) { | ||
if (_.isArray(value) || _.isArguments(value)) { | ||
shallow ? push.apply(output, value) : flatten(value, shallow, output); | ||
for (var i = 0, length = input.length; i < length; i++) { | ||
var value = input[i]; | ||
if (!_.isArray(value) && !_.isArguments(value)) { | ||
if (!strict) output.push(value); | ||
} else if (shallow) { | ||
push.apply(output, value); | ||
} else { | ||
output.push(value); | ||
flatten(value, shallow, strict, output); | ||
} | ||
}); | ||
} | ||
return output; | ||
@@ -483,3 +517,3 @@ }; | ||
_.flatten = function(array, shallow) { | ||
return flatten(array, shallow, []); | ||
return flatten(array, shallow, false, []); | ||
}; | ||
@@ -492,32 +526,31 @@ | ||
// Split an array into two arrays: one whose elements all satisfy the given | ||
// predicate, and one whose elements all do not satisfy the predicate. | ||
_.partition = function(array, predicate, context) { | ||
predicate = lookupIterator(predicate); | ||
var pass = [], fail = []; | ||
each(array, function(elem) { | ||
(predicate.call(context, elem) ? pass : fail).push(elem); | ||
}); | ||
return [pass, fail]; | ||
}; | ||
// 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, context) { | ||
if (_.isFunction(isSorted)) { | ||
context = iterator; | ||
iterator = isSorted; | ||
_.uniq = _.unique = function(array, isSorted, iteratee, context) { | ||
if (array == null) return []; | ||
if (!_.isBoolean(isSorted)) { | ||
context = iteratee; | ||
iteratee = isSorted; | ||
isSorted = false; | ||
} | ||
var initial = iterator ? _.map(array, iterator, context) : array; | ||
var results = []; | ||
if (iteratee != null) iteratee = _.iteratee(iteratee, context); | ||
var result = []; | ||
var seen = []; | ||
each(initial, function(value, index) { | ||
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { | ||
seen.push(value); | ||
results.push(array[index]); | ||
for (var i = 0, length = array.length; i < length; i++) { | ||
var value = array[i]; | ||
if (isSorted) { | ||
if (!i || seen !== value) result.push(value); | ||
seen = value; | ||
} else if (iteratee) { | ||
var computed = iteratee(value, i, array); | ||
if (_.indexOf(seen, computed) < 0) { | ||
seen.push(computed); | ||
result.push(value); | ||
} | ||
} else if (_.indexOf(result, value) < 0) { | ||
result.push(value); | ||
} | ||
}); | ||
return results; | ||
} | ||
return result; | ||
}; | ||
@@ -528,3 +561,3 @@ | ||
_.union = function() { | ||
return _.uniq(_.flatten(arguments, true)); | ||
return _.uniq(flatten(arguments, true, true, [])); | ||
}; | ||
@@ -535,8 +568,14 @@ | ||
_.intersection = function(array) { | ||
var rest = slice.call(arguments, 1); | ||
return _.filter(_.uniq(array), function(item) { | ||
return _.every(rest, function(other) { | ||
return _.contains(other, item); | ||
}); | ||
}); | ||
if (array == null) return []; | ||
var result = []; | ||
var argsLength = arguments.length; | ||
for (var i = 0, length = array.length; i < length; i++) { | ||
var item = array[i]; | ||
if (_.contains(result, item)) continue; | ||
for (var j = 1; j < argsLength; j++) { | ||
if (!_.contains(arguments[j], item)) break; | ||
} | ||
if (j === argsLength) result.push(item); | ||
} | ||
return result; | ||
}; | ||
@@ -547,4 +586,6 @@ | ||
_.difference = function(array) { | ||
var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); | ||
return _.filter(array, function(value){ return !_.contains(rest, value); }); | ||
var rest = flatten(slice.call(arguments, 1), true, true, []); | ||
return _.filter(array, function(value){ | ||
return !_.contains(rest, value); | ||
}); | ||
}; | ||
@@ -554,7 +595,8 @@ | ||
// an index go together. | ||
_.zip = function() { | ||
var length = _.max(_.pluck(arguments, 'length').concat(0)); | ||
var results = new Array(length); | ||
_.zip = function(array) { | ||
if (array == null) return []; | ||
var length = _.max(arguments, 'length').length; | ||
var results = Array(length); | ||
for (var i = 0; i < length; i++) { | ||
results[i] = _.pluck(arguments, '' + i); | ||
results[i] = _.pluck(arguments, i); | ||
} | ||
@@ -580,6 +622,4 @@ 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. | ||
// Return the position of the first occurrence of an item in an array, | ||
// or -1 if the item is not included in the array. | ||
// If the array is large and already in sort order, pass `true` | ||
@@ -592,3 +632,3 @@ // for **isSorted** to use binary search. | ||
if (typeof isSorted == 'number') { | ||
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted); | ||
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; | ||
} else { | ||
@@ -599,3 +639,2 @@ i = _.sortedIndex(array, item); | ||
} | ||
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); | ||
for (; i < length; i++) if (array[i] === item) return i; | ||
@@ -605,11 +644,9 @@ return -1; | ||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. | ||
_.lastIndexOf = function(array, item, from) { | ||
if (array == null) return -1; | ||
var hasIndex = from != null; | ||
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { | ||
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); | ||
var idx = array.length; | ||
if (typeof from == 'number') { | ||
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1); | ||
} | ||
var i = (hasIndex ? from : array.length); | ||
while (i--) if (array[i] === item) return i; | ||
while (--idx >= 0) if (array[idx] === item) return idx; | ||
return -1; | ||
@@ -626,11 +663,9 @@ }; | ||
} | ||
step = arguments[2] || 1; | ||
step = step || 1; | ||
var length = Math.max(Math.ceil((stop - start) / step), 0); | ||
var idx = 0; | ||
var range = new Array(length); | ||
var range = Array(length); | ||
while(idx < length) { | ||
range[idx++] = start; | ||
start += step; | ||
for (var idx = 0; idx < length; idx++, start += step) { | ||
range[idx] = start; | ||
} | ||
@@ -645,3 +680,3 @@ | ||
// Reusable constructor function for prototype setting. | ||
var ctor = function(){}; | ||
var Ctor = function(){}; | ||
@@ -654,13 +689,14 @@ // Create a function bound to a given object (assigning `this`, and arguments, | ||
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); | ||
if (!_.isFunction(func)) throw new TypeError; | ||
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); | ||
args = slice.call(arguments, 2); | ||
return bound = function() { | ||
bound = function() { | ||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); | ||
ctor.prototype = func.prototype; | ||
var self = new ctor; | ||
ctor.prototype = null; | ||
Ctor.prototype = func.prototype; | ||
var self = new Ctor; | ||
Ctor.prototype = null; | ||
var result = func.apply(self, args.concat(slice.call(arguments))); | ||
if (Object(result) === result) return result; | ||
if (_.isObject(result)) return result; | ||
return self; | ||
}; | ||
return bound; | ||
}; | ||
@@ -688,5 +724,8 @@ | ||
_.bindAll = function(obj) { | ||
var funcs = slice.call(arguments, 1); | ||
if (funcs.length === 0) throw new Error('bindAll must be passed function names'); | ||
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); | ||
var i, length = arguments.length, key; | ||
if (length <= 1) throw new Error('bindAll must be passed function names'); | ||
for (i = 1; i < length; i++) { | ||
key = arguments[i]; | ||
obj[key] = _.bind(obj[key], obj); | ||
} | ||
return obj; | ||
@@ -697,8 +736,10 @@ }; | ||
_.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)); | ||
var memoize = function(key) { | ||
var cache = memoize.cache; | ||
var address = hasher ? hasher.apply(this, arguments) : key; | ||
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); | ||
return cache[address]; | ||
}; | ||
memoize.cache = {}; | ||
return memoize; | ||
}; | ||
@@ -710,3 +751,5 @@ | ||
var args = slice.call(arguments, 2); | ||
return setTimeout(function(){ return func.apply(null, args); }, wait); | ||
return setTimeout(function(){ | ||
return func.apply(null, args); | ||
}, wait); | ||
}; | ||
@@ -729,3 +772,3 @@ | ||
var previous = 0; | ||
options || (options = {}); | ||
if (!options) options = {}; | ||
var later = function() { | ||
@@ -735,3 +778,3 @@ previous = options.leading === false ? 0 : _.now(); | ||
result = func.apply(context, args); | ||
context = args = null; | ||
if (!timeout) context = args = null; | ||
}; | ||
@@ -744,3 +787,3 @@ return function() { | ||
args = arguments; | ||
if (remaining <= 0) { | ||
if (remaining <= 0 || remaining > wait) { | ||
clearTimeout(timeout); | ||
@@ -750,3 +793,3 @@ timeout = null; | ||
result = func.apply(context, args); | ||
context = args = null; | ||
if (!timeout) context = args = null; | ||
} else if (!timeout && options.trailing !== false) { | ||
@@ -768,3 +811,4 @@ timeout = setTimeout(later, remaining); | ||
var last = _.now() - timestamp; | ||
if (last < wait) { | ||
if (last < wait && last > 0) { | ||
timeout = setTimeout(later, wait - last); | ||
@@ -775,3 +819,3 @@ } else { | ||
result = func.apply(context, args); | ||
context = args = null; | ||
if (!timeout) context = args = null; | ||
} | ||
@@ -786,5 +830,3 @@ } | ||
var callNow = immediate && !timeout; | ||
if (!timeout) { | ||
timeout = setTimeout(later, wait); | ||
} | ||
if (!timeout) timeout = setTimeout(later, wait); | ||
if (callNow) { | ||
@@ -799,15 +841,2 @@ result = func.apply(context, args); | ||
// 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; | ||
memo = func.apply(this, arguments); | ||
func = null; | ||
return memo; | ||
}; | ||
}; | ||
// Returns the first function passed as an argument to the second, | ||
@@ -820,12 +849,19 @@ // allowing you to adjust arguments, run code before and after, and | ||
// Returns a negated version of the passed-in predicate. | ||
_.negate = function(predicate) { | ||
return function() { | ||
return !predicate.apply(this, arguments); | ||
}; | ||
}; | ||
// 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; | ||
var args = arguments; | ||
var start = args.length - 1; | ||
return function() { | ||
var args = arguments; | ||
for (var i = funcs.length - 1; i >= 0; i--) { | ||
args = [funcs[i].apply(this, args)]; | ||
} | ||
return args[0]; | ||
var i = start; | ||
var result = args[start].apply(this, arguments); | ||
while (i--) result = args[i].call(this, result); | ||
return result; | ||
}; | ||
@@ -843,2 +879,19 @@ }; | ||
// Returns a function that will only be executed before being called N times. | ||
_.before = function(times, func) { | ||
var memo; | ||
return function() { | ||
if (--times > 0) { | ||
memo = func.apply(this, arguments); | ||
} else { | ||
func = null; | ||
} | ||
return memo; | ||
}; | ||
}; | ||
// Returns a function that will be executed at most one time, no matter how | ||
// often you call it. Useful for lazy initialization. | ||
_.once = _.partial(_.before, 2); | ||
// Object Functions | ||
@@ -861,3 +914,3 @@ // ---------------- | ||
var length = keys.length; | ||
var values = new Array(length); | ||
var values = Array(length); | ||
for (var i = 0; i < length; i++) { | ||
@@ -873,3 +926,3 @@ values[i] = obj[keys[i]]; | ||
var length = keys.length; | ||
var pairs = new Array(length); | ||
var pairs = Array(length); | ||
for (var i = 0; i < length; i++) { | ||
@@ -903,9 +956,12 @@ pairs[i] = [keys[i], obj[keys[i]]]; | ||
_.extend = function(obj) { | ||
each(slice.call(arguments, 1), function(source) { | ||
if (source) { | ||
for (var prop in source) { | ||
obj[prop] = source[prop]; | ||
if (!_.isObject(obj)) return obj; | ||
var source, prop; | ||
for (var i = 1, length = arguments.length; i < length; i++) { | ||
source = arguments[i]; | ||
for (prop in source) { | ||
if (hasOwnProperty.call(source, prop)) { | ||
obj[prop] = source[prop]; | ||
} | ||
} | ||
}); | ||
} | ||
return obj; | ||
@@ -915,19 +971,33 @@ }; | ||
// Return a copy of the object only containing the whitelisted properties. | ||
_.pick = function(obj) { | ||
var copy = {}; | ||
var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); | ||
each(keys, function(key) { | ||
if (key in obj) copy[key] = obj[key]; | ||
}); | ||
return copy; | ||
_.pick = function(obj, iteratee, context) { | ||
var result = {}, key; | ||
if (obj == null) return result; | ||
if (_.isFunction(iteratee)) { | ||
iteratee = createCallback(iteratee, context); | ||
for (key in obj) { | ||
var value = obj[key]; | ||
if (iteratee(value, key, obj)) result[key] = value; | ||
} | ||
} else { | ||
var keys = concat.apply([], slice.call(arguments, 1)); | ||
obj = new Object(obj); | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
key = keys[i]; | ||
if (key in obj) result[key] = obj[key]; | ||
} | ||
} | ||
return result; | ||
}; | ||
// Return a copy of the object without the blacklisted properties. | ||
_.omit = function(obj) { | ||
var copy = {}; | ||
var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); | ||
for (var key in obj) { | ||
if (!_.contains(keys, key)) copy[key] = obj[key]; | ||
_.omit = function(obj, iteratee, context) { | ||
if (_.isFunction(iteratee)) { | ||
iteratee = _.negate(iteratee); | ||
} else { | ||
var keys = _.map(concat.apply([], slice.call(arguments, 1)), String); | ||
iteratee = function(value, key) { | ||
return !_.contains(keys, key); | ||
}; | ||
} | ||
return copy; | ||
return _.pick(obj, iteratee, context); | ||
}; | ||
@@ -937,9 +1007,9 @@ | ||
_.defaults = function(obj) { | ||
each(slice.call(arguments, 1), function(source) { | ||
if (source) { | ||
for (var prop in source) { | ||
if (obj[prop] === void 0) obj[prop] = source[prop]; | ||
} | ||
if (!_.isObject(obj)) return obj; | ||
for (var i = 1, length = arguments.length; i < length; i++) { | ||
var source = arguments[i]; | ||
for (var prop in source) { | ||
if (obj[prop] === void 0) obj[prop] = source[prop]; | ||
} | ||
}); | ||
} | ||
return obj; | ||
@@ -966,3 +1036,3 @@ }; | ||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). | ||
if (a === b) return a !== 0 || 1 / a == 1 / b; | ||
if (a === b) return a !== 0 || 1 / a === 1 / b; | ||
// A strict comparison is necessary because `null == undefined`. | ||
@@ -975,13 +1045,17 @@ if (a == null || b == null) return a === b; | ||
var className = toString.call(a); | ||
if (className != toString.call(b)) return false; | ||
if (className !== toString.call(b)) return false; | ||
switch (className) { | ||
// Strings, numbers, dates, and booleans are compared by value. | ||
// Strings, numbers, regular expressions, dates, and booleans are compared by value. | ||
case '[object RegExp]': | ||
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') | ||
case '[object String]': | ||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is | ||
// equivalent to `new String("5")`. | ||
return a == String(b); | ||
return '' + a === '' + 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); | ||
// `NaN`s are equivalent, but non-reflexive. | ||
// Object(NaN) is equivalent to NaN | ||
if (+a !== +a) return +b !== +b; | ||
// An `egal` comparison is performed for other numeric values. | ||
return +a === 0 ? 1 / +a === 1 / b : +a === +b; | ||
case '[object Date]': | ||
@@ -992,9 +1066,3 @@ case '[object Boolean]': | ||
// 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; | ||
return +a === +b; | ||
} | ||
@@ -1008,3 +1076,3 @@ if (typeof a != 'object' || typeof b != 'object') return false; | ||
// unique nested structures. | ||
if (aStack[length] == a) return bStack[length] == b; | ||
if (aStack[length] === a) return bStack[length] === b; | ||
} | ||
@@ -1014,5 +1082,9 @@ // Objects with different constructors are not equivalent, but `Object`s | ||
var aCtor = a.constructor, bCtor = b.constructor; | ||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && | ||
_.isFunction(bCtor) && (bCtor instanceof bCtor)) | ||
&& ('constructor' in a && 'constructor' in b)) { | ||
if ( | ||
aCtor !== bCtor && | ||
// Handle Object.create(x) cases | ||
'constructor' in a && 'constructor' in b && | ||
!(_.isFunction(aCtor) && aCtor instanceof aCtor && | ||
_.isFunction(bCtor) && bCtor instanceof bCtor) | ||
) { | ||
return false; | ||
@@ -1023,8 +1095,8 @@ } | ||
bStack.push(b); | ||
var size = 0, result = true; | ||
var size, result; | ||
// Recursively compare objects and arrays. | ||
if (className == '[object Array]') { | ||
if (className === '[object Array]') { | ||
// Compare array lengths to determine if a deep comparison is necessary. | ||
size = a.length; | ||
result = size == b.length; | ||
result = size === b.length; | ||
if (result) { | ||
@@ -1038,17 +1110,13 @@ // Deep compare the contents, ignoring non-numeric properties. | ||
// Deep compare objects. | ||
for (var key in a) { | ||
if (_.has(a, key)) { | ||
// Count the expected number of properties. | ||
size++; | ||
// Deep compare each member. | ||
var keys = _.keys(a), key; | ||
size = keys.length; | ||
// Ensure that both objects contain the same number of properties before comparing deep equality. | ||
result = _.keys(b).length === size; | ||
if (result) { | ||
while (size--) { | ||
// Deep compare each member | ||
key = keys[size]; | ||
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) 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; | ||
} | ||
} | ||
@@ -1070,3 +1138,3 @@ // Remove the first object from the stack of traversed objects. | ||
if (obj == null) return true; | ||
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; | ||
if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0; | ||
for (var key in obj) if (_.has(obj, key)) return false; | ||
@@ -1084,3 +1152,3 @@ return true; | ||
_.isArray = nativeIsArray || function(obj) { | ||
return toString.call(obj) == '[object Array]'; | ||
return toString.call(obj) === '[object Array]'; | ||
}; | ||
@@ -1090,9 +1158,10 @@ | ||
_.isObject = function(obj) { | ||
return obj === Object(obj); | ||
var type = typeof obj; | ||
return type === 'function' || type === 'object' && !!obj; | ||
}; | ||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. | ||
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { | ||
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { | ||
_['is' + name] = function(obj) { | ||
return toString.call(obj) == '[object ' + name + ']'; | ||
return toString.call(obj) === '[object ' + name + ']'; | ||
}; | ||
@@ -1105,10 +1174,10 @@ }); | ||
_.isArguments = function(obj) { | ||
return !!(obj && _.has(obj, 'callee')); | ||
return _.has(obj, 'callee'); | ||
}; | ||
} | ||
// Optimize `isFunction` if appropriate. | ||
if (typeof (/./) !== 'function') { | ||
// Optimize `isFunction` if appropriate. Work around an IE 11 bug. | ||
if (typeof /./ !== 'function') { | ||
_.isFunction = function(obj) { | ||
return typeof obj === 'function'; | ||
return typeof obj == 'function' || false; | ||
}; | ||
@@ -1124,3 +1193,3 @@ } | ||
_.isNaN = function(obj) { | ||
return _.isNumber(obj) && obj != +obj; | ||
return _.isNumber(obj) && obj !== +obj; | ||
}; | ||
@@ -1130,3 +1199,3 @@ | ||
_.isBoolean = function(obj) { | ||
return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; | ||
return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; | ||
}; | ||
@@ -1147,3 +1216,3 @@ | ||
_.has = function(obj, key) { | ||
return hasOwnProperty.call(obj, key); | ||
return obj != null && hasOwnProperty.call(obj, key); | ||
}; | ||
@@ -1161,3 +1230,3 @@ | ||
// Keep the identity function around for default iterators. | ||
// Keep the identity function around for default iteratees. | ||
_.identity = function(value) { | ||
@@ -1168,3 +1237,3 @@ return value; | ||
_.constant = function(value) { | ||
return function () { | ||
return function() { | ||
return value; | ||
@@ -1174,2 +1243,4 @@ }; | ||
_.noop = function(){}; | ||
_.property = function(key) { | ||
@@ -1183,16 +1254,19 @@ return function(obj) { | ||
_.matches = function(attrs) { | ||
var pairs = _.pairs(attrs), length = pairs.length; | ||
return function(obj) { | ||
if (obj === attrs) return true; //avoid comparing an object to itself. | ||
for (var key in attrs) { | ||
if (attrs[key] !== obj[key]) | ||
return false; | ||
if (obj == null) return !length; | ||
obj = new Object(obj); | ||
for (var i = 0; i < length; i++) { | ||
var pair = pairs[i], key = pair[0]; | ||
if (pair[1] !== obj[key] || !(key in obj)) return false; | ||
} | ||
return true; | ||
} | ||
}; | ||
}; | ||
// Run a function **n** times. | ||
_.times = function(n, iterator, context) { | ||
_.times = function(n, iteratee, context) { | ||
var accum = Array(Math.max(0, n)); | ||
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); | ||
iteratee = createCallback(iteratee, context, 1); | ||
for (var i = 0; i < n; i++) accum[i] = iteratee(i); | ||
return accum; | ||
@@ -1211,31 +1285,33 @@ }; | ||
// A (possibly faster) way to get the current timestamp as an integer. | ||
_.now = Date.now || function() { return new Date().getTime(); }; | ||
// List of HTML entities for escaping. | ||
var entityMap = { | ||
escape: { | ||
'&': '&', | ||
'<': '<', | ||
'>': '>', | ||
'"': '"', | ||
"'": ''' | ||
} | ||
_.now = Date.now || function() { | ||
return new Date().getTime(); | ||
}; | ||
entityMap.unescape = _.invert(entityMap.escape); | ||
// Regexes containing the keys and values listed immediately above. | ||
var entityRegexes = { | ||
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), | ||
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') | ||
// List of HTML entities for escaping. | ||
var escapeMap = { | ||
'&': '&', | ||
'<': '<', | ||
'>': '>', | ||
'"': '"', | ||
"'": ''', | ||
'`': '`' | ||
}; | ||
var unescapeMap = _.invert(escapeMap); | ||
// Functions for escaping and unescaping strings to/from HTML interpolation. | ||
_.each(['escape', 'unescape'], function(method) { | ||
_[method] = function(string) { | ||
if (string == null) return ''; | ||
return ('' + string).replace(entityRegexes[method], function(match) { | ||
return entityMap[method][match]; | ||
}); | ||
var createEscaper = function(map) { | ||
var escaper = function(match) { | ||
return map[match]; | ||
}; | ||
}); | ||
// Regexes for identifying a key that needs to be escaped | ||
var source = '(?:' + _.keys(map).join('|') + ')'; | ||
var testRegexp = RegExp(source); | ||
var replaceRegexp = RegExp(source, 'g'); | ||
return function(string) { | ||
string = string == null ? '' : '' + string; | ||
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; | ||
}; | ||
}; | ||
_.escape = createEscaper(escapeMap); | ||
_.unescape = createEscaper(unescapeMap); | ||
@@ -1247,17 +1323,5 @@ // If the value of the named `property` is a function then invoke it with the | ||
var value = object[property]; | ||
return _.isFunction(value) ? value.call(object) : value; | ||
return _.isFunction(value) ? object[property]() : value; | ||
}; | ||
// Add your own custom functions to the Underscore object. | ||
_.mixin = function(obj) { | ||
each(_.functions(obj), function(name) { | ||
var func = _[name] = obj[name]; | ||
_.prototype[name] = function() { | ||
var args = [this._wrapped]; | ||
push.apply(args, arguments); | ||
return result.call(this, func.apply(_, args)); | ||
}; | ||
}); | ||
}; | ||
// Generate a unique integer id (unique within the entire client session). | ||
@@ -1291,3 +1355,2 @@ // Useful for temporary DOM ids. | ||
'\n': 'n', | ||
'\t': 't', | ||
'\u2028': 'u2028', | ||
@@ -1297,13 +1360,18 @@ '\u2029': 'u2029' | ||
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; | ||
var escaper = /\\|'|\r|\n|\u2028|\u2029/g; | ||
var escapeChar = function(match) { | ||
return '\\' + escapes[match]; | ||
}; | ||
// 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) { | ||
var render; | ||
// NB: `oldSettings` only exists for backwards compatibility. | ||
_.template = function(text, settings, oldSettings) { | ||
if (!settings && oldSettings) settings = oldSettings; | ||
settings = _.defaults({}, settings, _.templateSettings); | ||
// Combine delimiters into one regular expression via alternation. | ||
var matcher = new RegExp([ | ||
var matcher = RegExp([ | ||
(settings.escape || noMatch).source, | ||
@@ -1318,15 +1386,14 @@ (settings.interpolate || noMatch).source, | ||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { | ||
source += text.slice(index, offset) | ||
.replace(escaper, function(match) { return '\\' + escapes[match]; }); | ||
source += text.slice(index, offset).replace(escaper, escapeChar); | ||
index = offset + match.length; | ||
if (escape) { | ||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; | ||
} | ||
if (interpolate) { | ||
} else if (interpolate) { | ||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; | ||
} | ||
if (evaluate) { | ||
} else if (evaluate) { | ||
source += "';\n" + evaluate + "\n__p+='"; | ||
} | ||
index = offset + match.length; | ||
// Adobe VMs need the match returned to produce the correct offest. | ||
return match; | ||
@@ -1341,6 +1408,6 @@ }); | ||
"print=function(){__p+=__j.call(arguments,'');};\n" + | ||
source + "return __p;\n"; | ||
source + 'return __p;\n'; | ||
try { | ||
render = new Function(settings.variable || 'obj', '_', source); | ||
var render = new Function(settings.variable || 'obj', '_', source); | ||
} catch (e) { | ||
@@ -1351,3 +1418,2 @@ e.source = source; | ||
if (data) return render(data, _); | ||
var template = function(data) { | ||
@@ -1357,4 +1423,5 @@ return render.call(this, data, _); | ||
// Provide the compiled function source as a convenience for precompilation. | ||
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; | ||
// Provide the compiled source as a convenience for precompilation. | ||
var argument = settings.variable || 'obj'; | ||
template.source = 'function(' + argument + '){\n' + source + '}'; | ||
@@ -1364,5 +1431,7 @@ return template; | ||
// Add a "chain" function, which will delegate to the wrapper. | ||
// Add a "chain" function. Start chaining a wrapped Underscore object. | ||
_.chain = function(obj) { | ||
return _(obj).chain(); | ||
var instance = _(obj); | ||
instance._chain = true; | ||
return instance; | ||
}; | ||
@@ -1381,2 +1450,14 @@ | ||
// Add your own custom functions to the Underscore object. | ||
_.mixin = function(obj) { | ||
_.each(_.functions(obj), function(name) { | ||
var func = _[name] = obj[name]; | ||
_.prototype[name] = function() { | ||
var args = [this._wrapped]; | ||
push.apply(args, arguments); | ||
return result.call(this, func.apply(_, args)); | ||
}; | ||
}); | ||
}; | ||
// Add all of the Underscore functions to the wrapper object. | ||
@@ -1386,3 +1467,3 @@ _.mixin(_); | ||
// Add all mutator Array functions to the wrapper. | ||
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { | ||
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { | ||
var method = ArrayProto[name]; | ||
@@ -1392,3 +1473,3 @@ _.prototype[name] = function() { | ||
method.apply(obj, arguments); | ||
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; | ||
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; | ||
return result.call(this, obj); | ||
@@ -1399,3 +1480,3 @@ }; | ||
// Add all accessor Array functions to the wrapper. | ||
each(['concat', 'join', 'slice'], function(name) { | ||
_.each(['concat', 'join', 'slice'], function(name) { | ||
var method = ArrayProto[name]; | ||
@@ -1407,17 +1488,7 @@ _.prototype[name] = function() { | ||
_.extend(_.prototype, { | ||
// Extracts the result from a wrapped and chained object. | ||
_.prototype.value = function() { | ||
return this._wrapped; | ||
}; | ||
// Start chaining a wrapped Underscore object. | ||
chain: function() { | ||
this._chain = true; | ||
return this; | ||
}, | ||
// Extracts the result from a wrapped and chained object. | ||
value: function() { | ||
return this._wrapped; | ||
} | ||
}); | ||
// AMD registration happens at the end for compatibility with AMD loaders | ||
@@ -1435,2 +1506,2 @@ // that may not enforce next-turn semantics on modules. Even though general | ||
} | ||
}).call(this); | ||
}.call(this)); |
@@ -1,3 +0,10 @@ | ||
var UriTemplate = (function () { | ||
(function (global, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
define([], factory); | ||
} else if (typeof module !== 'undefined' && module.exports){ | ||
module.exports = factory(); | ||
} else { | ||
global.UriTemplate = factory(); | ||
} | ||
})(this, function () { | ||
var uriTemplateGlobalModifiers = { | ||
@@ -233,3 +240,4 @@ "+": true, | ||
// Try from beginning | ||
for (var firstStarred = 0; firstStarred < varSpecs.length - 1 && firstStarred < i; firstStarred++) { | ||
var firstStarred = 0; | ||
for (; firstStarred < varSpecs.length - 1 && firstStarred < i; firstStarred++) { | ||
if (varSpecs[firstStarred].suffices['*']) { | ||
@@ -239,3 +247,3 @@ break; | ||
} | ||
if (j == i) { | ||
if (firstStarred == i) { | ||
// The first [i] of them have no "*" suffix | ||
@@ -384,4 +392,8 @@ specIndexMap[i] = i; | ||
this.varNames = varNames; | ||
this.template = template; | ||
} | ||
UriTemplate.prototype = { | ||
toString: function () { | ||
return this.template; | ||
}, | ||
fillFromObject: function (obj) { | ||
@@ -394,9 +406,3 @@ return this.fill(function (varName) { | ||
if (typeof module != 'undefined') { | ||
module.exports = UriTemplate; | ||
} | ||
if (this) { | ||
this.UriTemplate = UriTemplate; | ||
} | ||
return UriTemplate; | ||
}).call(this); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
474982
26
13182
205
7