diff --git a/bower.json b/bower.json index a5b9f3f..11abbec 100644 --- a/bower.json +++ b/bower.json @@ -2,12 +2,12 @@ "name": "github-burndown-chart", "version": "1.0.0-alpha", "dependencies": { - "lodash": null, - "async": null, - "d3": null, - "d3-tip": null, - "superagent": null, - "normalize-css": null, - "marked": null + "lodash": "2.3.0", + "async": "0.2.5", + "d3": "3.3.9", + "d3-tip": "0.6.2", + "superagent": "0.15.7", + "normalize-css": "2.1.3", + "marked": "0.2.10" } -} \ No newline at end of file +} diff --git a/build/app.bundle.js b/build/app.bundle.js index 0a9cfbf..4aef560 100644 --- a/build/app.bundle.js +++ b/build/app.bundle.js @@ -10504,7 +10504,7 @@ d3.tip = function() { }; ;/** * @license - * Lo-Dash 2.2.1 (Custom Build) + * Lo-Dash 2.3.0 (Custom Build) * Build: `lodash modern -o ./dist/lodash.js` * Copyright 2012-2013 The Dojo Foundation * Based on Underscore.js 1.5.2 @@ -10559,7 +10559,7 @@ d3.tip = function() { var reFlags = /\w*$/; /** Used to detected named functions */ - var reFuncName = /^function[ \n\r\t]+\w/; + var reFuncName = /^\s*function[ \n\r\t]+\w/; /** Used to match "interpolate" template delimiters */ var reInterpolate = /<%=([\s\S]+?)%>/g; @@ -10857,15 +10857,6 @@ d3.tip = function() { }; } - /** - * A no-operation function. - * - * @private - */ - function noop() { - // no operation performed - } - /** * Releases the given array back to the array pool. * @@ -10968,11 +10959,14 @@ d3.tip = function() { /** Used to restore the original `_` reference in `noConflict` */ var oldDash = context._; + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + /** Used to detect if a method is native */ var reNative = RegExp('^' + - String(objectProto.valueOf) + String(toString) .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/valueOf|for [^\]]+/g, '.+?') + '$' + .replace(/toString| for [^\]]+/g, '.*?') + '$' ); /** Native method shortcuts */ @@ -10984,13 +10978,16 @@ d3.tip = function() { hasOwnProperty = objectProto.hasOwnProperty, now = reNative.test(now = Date.now) && now || function() { return +new Date; }, push = arrayRef.push, - setImmediate = context.setImmediate, setTimeout = context.setTimeout, - splice = arrayRef.splice, - toString = objectProto.toString, - unshift = arrayRef.unshift; + splice = arrayRef.splice; + /** Used to detect `setImmediate` in Node.js */ + var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' && + !reNative.test(setImmediate) && setImmediate; + + /** Used to set meta data on functions */ var defineProperty = (function() { + // IE 8 only accepts DOM elements try { var o = {}, func = reNative.test(func = Object.defineProperty) && func, @@ -11000,8 +10997,7 @@ d3.tip = function() { }()); /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind, - nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate, + var nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate, nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray, nativeIsFinite = context.isFinite, nativeIsNaN = context.isNaN, @@ -11009,12 +11005,7 @@ d3.tip = function() { nativeMax = Math.max, nativeMin = Math.min, nativeParseInt = context.parseInt, - nativeRandom = Math.random, - nativeSlice = arrayRef.slice; - - /** Detect various environments */ - var isIeOpera = reNative.test(context.attachEvent), - isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera); + nativeRandom = Math.random; /** Used to lookup a built-in constructor by [[Class]] */ var ctorByClass = {}; @@ -11042,15 +11033,16 @@ d3.tip = function() { * * The chainable wrapper functions are: * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `createCallback`, `curry`, `debounce`, - * `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, - * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, - * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, - * `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, `once`, `pairs`, - * `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, `range`, `reject`, - * `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, - * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`, - * `unzip`, `values`, `where`, `without`, `wrap`, and `zip` + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` * * The non-chainable wrapper functions are: * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, @@ -11124,14 +11116,6 @@ d3.tip = function() { */ var support = lodash.support = {}; - /** - * Detect if `Function#bind` exists and is inferred to be fast (all but V8). - * - * @memberOf _.support - * @type boolean - */ - support.fastBind = nativeBind && !isV8; - /** * Detect if functions can be decompiled by `Function#toString` * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). @@ -11212,19 +11196,53 @@ d3.tip = function() { /*--------------------------------------------------------------------------*/ + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + var args = partialArgs.slice(); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + /** * The base implementation of `_.clone` without argument juggling or support * for `thisArg` binding. * * @private * @param {*} value The value to clone. - * @param {boolean} [deep=false] Specify a deep clone. + * @param {boolean} [isDeep=false] Specify a deep clone. * @param {Function} [callback] The function to customize cloning values. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates clones with source counterparts. * @returns {*} Returns the cloned value. */ - function baseClone(value, deep, callback, stackA, stackB) { + function baseClone(value, isDeep, callback, stackA, stackB) { if (callback) { var result = callback(value); if (typeof result != 'undefined') { @@ -11257,7 +11275,7 @@ d3.tip = function() { return value; } var isArr = isArray(value); - if (deep) { + if (isDeep) { // check for circular references and return corresponding clone var initedStack = !stackA; stackA || (stackA = getArray()); @@ -11284,7 +11302,7 @@ d3.tip = function() { } } // exit for shallow clone - if (!deep) { + if (!isDeep) { return result; } // add the source value to the stack of traversed objects @@ -11294,7 +11312,7 @@ d3.tip = function() { // recursively populate clone (susceptible to call stack limits) (isArr ? forEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, deep, callback, stackA, stackB); + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); }); if (initedStack) { @@ -11304,6 +11322,32 @@ d3.tip = function() { return result; } + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + /** * The base implementation of `_.createCallback` without support for creating * "_.pluck" or "_.where" style callbacks. @@ -11318,24 +11362,30 @@ d3.tip = function() { if (typeof func != 'function') { return identity; } - // exit early if there is no `thisArg` - if (typeof thisArg == 'undefined') { + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { return func; } - var bindData = func.__bindData__ || (support.funcNames && !func.name); + var bindData = func.__bindData__; if (typeof bindData == 'undefined') { - var source = reThis && fnToString.call(func); - if (!support.funcNames && source && !reFuncName.test(source)) { - bindData = true; + if (support.funcNames) { + bindData = !func.name; } - if (support.funcNames || !bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = !support.funcDecomp || reThis.test(source); - setBindData(func, bindData); + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } } } // exit early if there are no `this` references or `func` is bound - if (bindData !== true && (bindData && bindData[1] & 1)) { + if (bindData === false || (bindData !== true && bindData[1] & 1)) { return func; } switch (argCount) { @@ -11355,6 +11405,96 @@ d3.tip = function() { return bind(func, thisArg); } + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = partialArgs.slice(); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + /** * The base implementation of `_.flatten` without support for callback * shorthands or `thisArg` binding. @@ -11362,11 +11502,11 @@ d3.tip = function() { * @private * @param {Array} array The array to flatten. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isArgArrays=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. * @param {number} [fromIndex=0] The index to start from. * @returns {Array} Returns a new flattened array. */ - function baseFlatten(array, isShallow, isArgArrays, fromIndex) { + function baseFlatten(array, isShallow, isStrict, fromIndex) { var index = (fromIndex || 0) - 1, length = array ? array.length : 0, result = []; @@ -11378,7 +11518,7 @@ d3.tip = function() { && (isArray(value) || isArguments(value))) { // recursively flatten arrays (susceptible to call stack limits) if (!isShallow) { - value = baseFlatten(value, isShallow, isArgArrays); + value = baseFlatten(value, isShallow, isStrict); } var valIndex = -1, valLength = value.length, @@ -11388,7 +11528,7 @@ d3.tip = function() { while (++valIndex < valLength) { result[resIndex++] = value[valIndex]; } - } else if (!isArgArrays) { + } else if (!isStrict) { result.push(value); } } @@ -11471,8 +11611,11 @@ d3.tip = function() { var isArr = className == arrayClass; if (!isArr) { // unwrap any `lodash` wrapped values - if (hasOwnProperty.call(a, '__wrapped__ ') || hasOwnProperty.call(b, '__wrapped__')) { - return baseIsEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, isWhere, stackA, stackB); + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); } // exit for functions and DOM nodes if (className != objectClass) { @@ -11483,10 +11626,10 @@ d3.tip = function() { ctorB = b.constructor; // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && !( - isFunction(ctorA) && ctorA instanceof ctorA && - isFunction(ctorB) && ctorB instanceof ctorB - )) { + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { return false; } } @@ -11629,6 +11772,19 @@ d3.tip = function() { }); } + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + /** * The base implementation of `_.uniq` without support for callback shorthands * or `thisArg` binding. @@ -11733,16 +11889,15 @@ d3.tip = function() { * provided to the new function. * @param {*} [thisArg] The `this` binding of `func`. * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new bound function. + * @returns {Function} Returns the new function. */ - function createBound(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { var isBind = bitmask & 1, isBindKey = bitmask & 2, isCurry = bitmask & 4, isCurryBound = bitmask & 8, isPartial = bitmask & 16, - isPartialRight = bitmask & 32, - key = func; + isPartialRight = bitmask & 32; if (!isBindKey && !isFunction(func)) { throw new TypeError; @@ -11756,96 +11911,36 @@ d3.tip = function() { isPartialRight = partialRightArgs = false; } var bindData = func && func.__bindData__; - if (bindData) { + if (bindData && bindData !== true) { + bindData = bindData.slice(); + + // set `thisBinding` is not previously bound if (isBind && !(bindData[1] & 1)) { bindData[4] = thisArg; } + // set if previously bound but not currently (subsequent curried functions) if (!isBind && bindData[1] & 1) { bitmask |= 8; } + // set curried arity if not yet set if (isCurry && !(bindData[1] & 4)) { bindData[5] = arity; } + // append partial left arguments if (isPartial) { push.apply(bindData[2] || (bindData[2] = []), partialArgs); } + // append partial right arguments if (isPartialRight) { push.apply(bindData[3] || (bindData[3] = []), partialRightArgs); } + // merge flags bindData[1] |= bitmask; - return createBound.apply(null, bindData); + return createWrapper.apply(null, bindData); } - // use `Function#bind` if it exists and is fast - // (in V8 `Function#bind` is slower except when partially applied) - if (isBind && !(isBindKey || isCurry || isPartialRight) && - (support.fastBind || (nativeBind && isPartial))) { - if (isPartial) { - var args = [thisArg]; - push.apply(args, partialArgs); - } - var bound = isPartial - ? nativeBind.apply(func, args) - : nativeBind.call(func, thisArg); - } - else { - bound = function() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - var args = arguments, - thisBinding = isBind ? thisArg : this; - - if (isCurry || isPartial || isPartialRight) { - args = nativeSlice.call(args); - if (isPartial) { - unshift.apply(args, partialArgs); - } - if (isPartialRight) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return createBound(func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity); - } - } - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - thisBinding = createObject(func.prototype); - - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - }; - } - setBindData(bound, nativeSlice.call(arguments)); - return bound; - } - - /** - * Creates a new object with the specified `prototype`. - * - * @private - * @param {Object} prototype The prototype object. - * @returns {Object} Returns the new object. - */ - function createObject(prototype) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - createObject = function(prototype) { - if (isObject(prototype)) { - noop.prototype = prototype; - var result = new noop; - noop.prototype = null; - } - return result || {}; - }; + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); } /** @@ -11877,7 +11972,7 @@ d3.tip = function() { * * @private * @param {Function} func The function to set data on. - * @param {*} value The value to set. + * @param {Array} value The data array to set. */ var setBindData = !defineProperty ? noop : function(func, value) { descriptor.value = value; @@ -12053,16 +12148,16 @@ d3.tip = function() { * @returns {Object} Returns the destination object. * @example * - * _.assign({ 'name': 'moe' }, { 'age': 40 }); - * // => { 'name': 'moe', 'age': 40 } + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } * * var defaults = _.partialRight(_.assign, function(a, b) { * return typeof a == 'undefined' ? b : a; * }); * - * var food = { 'name': 'apple' }; - * defaults(food, { 'name': 'banana', 'type': 'fruit' }); - * // => { 'name': 'apple', 'type': 'fruit' } + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } */ var assign = function(object, source, guard) { var index, iterable = object, result = iterable; @@ -12092,7 +12187,7 @@ d3.tip = function() { }; /** - * Creates a clone of `value`. If `deep` is `true` nested objects will also + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also * be cloned, otherwise they will be assigned by reference. If a callback * is provided it will be executed to produce the cloned values. If the * callback returns `undefined` cloning will be handled by the method instead. @@ -12102,23 +12197,23 @@ d3.tip = function() { * @memberOf _ * @category Objects * @param {*} value The value to clone. - * @param {boolean} [deep=false] Specify a deep clone. + * @param {boolean} [isDeep=false] Specify a deep clone. * @param {Function} [callback] The function to customize cloning values. * @param {*} [thisArg] The `this` binding of `callback`. * @returns {*} Returns the cloned value. * @example * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * - * var shallow = _.clone(stooges); - * shallow[0] === stooges[0]; + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; * // => true * - * var deep = _.clone(stooges, true); - * deep[0] === stooges[0]; + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; * // => false * * _.mixin({ @@ -12131,15 +12226,15 @@ d3.tip = function() { * clone.childNodes.length; * // => 0 */ - function clone(value, deep, callback, thisArg) { + function clone(value, isDeep, callback, thisArg) { // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `deep` and `callback` - if (typeof deep != 'boolean' && deep != null) { + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { thisArg = callback; - callback = deep; - deep = false; + callback = isDeep; + isDeep = false; } - return baseClone(value, deep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); } /** @@ -12162,13 +12257,13 @@ d3.tip = function() { * @returns {*} Returns the deep cloned value. * @example * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * - * var deep = _.cloneDeep(stooges); - * deep[0] === stooges[0]; + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; * // => false * * var view = { @@ -12187,6 +12282,42 @@ d3.tip = function() { return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); } + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + /** * Assigns own enumerable properties of source object(s) to the destination * object for all destination properties that resolve to `undefined`. Once a @@ -12203,9 +12334,9 @@ d3.tip = function() { * @returns {Object} Returns the destination object. * @example * - * var food = { 'name': 'apple' }; - * _.defaults(food, { 'name': 'banana', 'type': 'fruit' }); - * // => { 'name': 'apple', 'type': 'fruit' } + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } */ var defaults = function(object, source, guard) { var index, iterable = object, result = iterable; @@ -12233,6 +12364,13 @@ d3.tip = function() { * This method is like `_.findIndex` except that it returns the key of the * first element that passes the callback check, instead of the element itself. * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * * @static * @memberOf _ * @category Objects @@ -12244,10 +12382,24 @@ d3.tip = function() { * @returns {string|undefined} Returns the key of the found element, else `undefined`. * @example * - * _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) { - * return num % 2 == 0; + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; * }); - * // => 'b' (property order is not guaranteed across environments) + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' */ function findKey(object, callback, thisArg) { var result; @@ -12265,6 +12417,13 @@ d3.tip = function() { * This method is like `_.findKey` except that it iterates over elements * of a `collection` in the opposite order. * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * * @static * @memberOf _ * @category Objects @@ -12276,10 +12435,24 @@ d3.tip = function() { * @returns {string|undefined} Returns the key of the found element, else `undefined`. * @example * - * _.findLastKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) { - * return num % 2 == 1; + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; * }); - * // => returns `c`, assuming `_.findKey` returns `a` + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' */ function findLastKey(object, callback, thisArg) { var result; @@ -12309,18 +12482,20 @@ d3.tip = function() { * @returns {Object} Returns `object`. * @example * - * function Dog(name) { - * this.name = name; + * function Shape() { + * this.x = 0; + * this.y = 0; * } * - * Dog.prototype.bark = function() { - * console.log('Woof, woof!'); + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; * }; * - * _.forIn(new Dog('Dagny'), function(value, key) { + * _.forIn(new Shape, function(value, key) { * console.log(key); * }); - * // => logs 'bark' and 'name' (property order is not guaranteed across environments) + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) */ var forIn = function(collection, callback, thisArg) { var index, iterable = collection, result = iterable; @@ -12346,18 +12521,20 @@ d3.tip = function() { * @returns {Object} Returns `object`. * @example * - * function Dog(name) { - * this.name = name; + * function Shape() { + * this.x = 0; + * this.y = 0; * } * - * Dog.prototype.bark = function() { - * console.log('Woof, woof!'); + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; * }; * - * _.forInRight(new Dog('Dagny'), function(value, key) { + * _.forInRight(new Shape, function(value, key) { * console.log(key); * }); - * // => logs 'name' and 'bark' assuming `_.forIn ` logs 'bark' and 'name' + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' */ function forInRight(object, callback, thisArg) { var pairs = []; @@ -12499,8 +12676,8 @@ d3.tip = function() { * @returns {Object} Returns the created inverted object. * @example * - * _.invert({ 'first': 'moe', 'second': 'larry' }); - * // => { 'moe': 'first', 'larry': 'second' } + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } */ function invert(object) { var index = -1, @@ -12529,7 +12706,8 @@ d3.tip = function() { * // => false */ function isBoolean(value) { - return value === true || value === false || toString.call(value) == boolClass; + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; } /** @@ -12546,7 +12724,7 @@ d3.tip = function() { * // => true */ function isDate(value) { - return value ? (typeof value == 'object' && toString.call(value) == dateClass) : false; + return value && typeof value == 'object' && toString.call(value) == dateClass || false; } /** @@ -12563,7 +12741,7 @@ d3.tip = function() { * // => true */ function isElement(value) { - return value ? value.nodeType === 1 : false; + return value && value.nodeType === 1 || false; } /** @@ -12622,13 +12800,13 @@ d3.tip = function() { * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * var moe = { 'name': 'moe', 'age': 40 }; - * var copy = { 'name': 'moe', 'age': 40 }; + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; * - * moe == copy; + * object == copy; * // => false * - * _.isEqual(moe, copy); + * _.isEqual(object, copy); * // => true * * var words = ['hello', 'goodbye']; @@ -12791,7 +12969,8 @@ d3.tip = function() { * // => true */ function isNumber(value) { - return typeof value == 'number' || toString.call(value) == numberClass; + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; } /** @@ -12804,18 +12983,18 @@ d3.tip = function() { * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * - * function Stooge(name, age) { - * this.name = name; - * this.age = age; + * function Shape() { + * this.x = 0; + * this.y = 0; * } * - * _.isPlainObject(new Stooge('moe', 40)); + * _.isPlainObject(new Shape); * // => false * * _.isPlainObject([1, 2, 3]); * // => false * - * _.isPlainObject({ 'name': 'moe', 'age': 40 }); + * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true */ var isPlainObject = function(value) { @@ -12840,11 +13019,11 @@ d3.tip = function() { * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. * @example * - * _.isRegExp(/moe/); + * _.isRegExp(/fred/); * // => true */ function isRegExp(value) { - return value ? (typeof value == 'object' && toString.call(value) == regexpClass) : false; + return value && typeof value == 'object' && toString.call(value) == regexpClass || false; } /** @@ -12857,11 +13036,12 @@ d3.tip = function() { * @returns {boolean} Returns `true` if the `value` is a string, else `false`. * @example * - * _.isString('moe'); + * _.isString('fred'); * // => true */ function isString(value) { - return typeof value == 'string' || toString.call(value) == stringClass; + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; } /** @@ -12901,21 +13081,21 @@ d3.tip = function() { * @example * * var names = { - * 'stooges': [ - * { 'name': 'moe' }, - * { 'name': 'larry' } + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } * ] * }; * * var ages = { - * 'stooges': [ - * { 'age': 40 }, - * { 'age': 50 } + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } * ] * }; * * _.merge(names, ages); - * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] } + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } * * var food = { * 'fruits': ['apple'], @@ -12939,6 +13119,7 @@ d3.tip = function() { if (!isObject(object)) { return object; } + // allows working with `_.reduce` and `_.reduceRight` without using // their `index` and `collection` arguments if (typeof args[2] != 'number') { @@ -12949,7 +13130,7 @@ d3.tip = function() { } else if (length > 2 && typeof args[length - 1] == 'function') { callback = args[--length]; } - var sources = nativeSlice.call(arguments, 1, length), + var sources = slice(arguments, 1, length), index = -1, stackA = getArray(), stackB = getArray(); @@ -12980,32 +13161,38 @@ d3.tip = function() { * @returns {Object} Returns an object without the omitted properties. * @example * - * _.omit({ 'name': 'moe', 'age': 40 }, 'age'); - * // => { 'name': 'moe' } + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } * - * _.omit({ 'name': 'moe', 'age': 40 }, function(value) { + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { * return typeof value == 'number'; * }); - * // => { 'name': 'moe' } + * // => { 'name': 'fred' } */ function omit(object, callback, thisArg) { - var indexOf = getIndexOf(), - isFunc = typeof callback == 'function', - result = {}; + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - if (isFunc) { - callback = lodash.createCallback(callback, thisArg, 3); - } else { - var props = baseFlatten(arguments, true, false, 1); - } - forIn(object, function(value, key, object) { - if (isFunc - ? !callback(value, key, object) - : indexOf(props, key) < 0 - ) { - result[key] = value; + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; } - }); + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } return result; } @@ -13020,8 +13207,8 @@ d3.tip = function() { * @returns {Array} Returns new array of key-value pairs. * @example * - * _.pairs({ 'moe': 30, 'larry': 40 }); - * // => [['moe', 30], ['larry', 40]] (property order is not guaranteed across environments) + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) */ function pairs(object) { var index = -1, @@ -13055,13 +13242,13 @@ d3.tip = function() { * @returns {Object} Returns an object composed of the picked properties. * @example * - * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name'); - * // => { 'name': 'moe' } + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } * - * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) { + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { * return key.charAt(0) != '_'; * }); - * // => { 'name': 'moe' } + * // => { 'name': 'fred' } */ function pick(object, callback, thisArg) { var result = {}; @@ -13098,7 +13285,7 @@ d3.tip = function() { * @static * @memberOf _ * @category Objects - * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Object} object The object to iterate over. * @param {Function} [callback=identity] The function called per iteration. * @param {*} [accumulator] The custom accumulator value. * @param {*} [thisArg] The `this` binding of `callback`. @@ -13120,8 +13307,6 @@ d3.tip = function() { */ function transform(object, callback, accumulator, thisArg) { var isArr = isArray(object); - callback = baseCreateCallback(callback, thisArg, 4); - if (accumulator == null) { if (isArr) { accumulator = []; @@ -13129,12 +13314,15 @@ d3.tip = function() { var ctor = object && object.constructor, proto = ctor && ctor.prototype; - accumulator = createObject(proto); + accumulator = baseCreate(proto); } } - (isArr ? forEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? forEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } return accumulator; } @@ -13183,8 +13371,8 @@ d3.tip = function() { * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); * // => ['a', 'c', 'e'] * - * _.at(['moe', 'larry', 'curly'], 0, 2); - * // => ['moe', 'curly'] + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] */ function at(collection) { var args = arguments, @@ -13220,10 +13408,10 @@ d3.tip = function() { * _.contains([1, 2, 3], 1, 2); * // => false * - * _.contains({ 'name': 'moe', 'age': 40 }, 'moe'); + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); * // => true * - * _.contains('curly', 'ur'); + * _.contains('pebbles', 'eb'); * // => true */ function contains(collection, target, fromIndex) { @@ -13310,20 +13498,20 @@ d3.tip = function() { * else `false`. * @example * - * _.every([true, 1, null, 'yes'], Boolean); + * _.every([true, 1, null, 'yes']); * // => false * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.every(stooges, 'age'); + * _.every(characters, 'age'); * // => true * * // using "_.where" callback shorthand - * _.every(stooges, { 'age': 50 }); + * _.every(characters, { 'age': 36 }); * // => false */ function every(collection, callback, thisArg) { @@ -13374,18 +13562,18 @@ d3.tip = function() { * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); * // => [2, 4, 6] * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.filter(food, 'organic'); - * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }] + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] * * // using "_.where" callback shorthand - * _.filter(food, { 'type': 'fruit' }); - * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }] + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] */ function filter(collection, callback, thisArg) { var result = []; @@ -13435,24 +13623,24 @@ d3.tip = function() { * @returns {*} Returns the found element, else `undefined`. * @example * - * _.find([1, 2, 3, 4], function(num) { - * return num % 2 == 0; - * }); - * // => 2 - * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'banana', 'organic': true, 'type': 'fruit' }, - * { 'name': 'beet', 'organic': false, 'type': 'vegetable' } + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } * ]; * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * * // using "_.where" callback shorthand - * _.find(food, { 'type': 'vegetable' }); - * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' } + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } * * // using "_.pluck" callback shorthand - * _.find(food, 'organic'); - * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' } + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } */ function find(collection, callback, thisArg) { callback = lodash.createCallback(callback, thisArg, 3); @@ -13517,6 +13705,10 @@ d3.tip = function() { * (value, index|key, collection). Callbacks may exit iteration early by * explicitly returning `false`. * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * * @static * @memberOf _ * @alias each @@ -13662,7 +13854,7 @@ d3.tip = function() { * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } * - * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String); + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } */ var indexBy = createAggregator(function(result, value, key) { @@ -13692,7 +13884,7 @@ d3.tip = function() { * // => [['1', '2', '3'], ['4', '5', '6']] */ function invoke(collection, methodName) { - var args = nativeSlice.call(arguments, 2), + var args = slice(arguments, 2), index = -1, isFunc = typeof methodName == 'function', length = collection ? collection.length : 0, @@ -13734,14 +13926,14 @@ d3.tip = function() { * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); * // => [3, 6, 9] (property order is not guaranteed across environments) * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * * // using "_.pluck" callback shorthand - * _.map(stooges, 'name'); - * // => ['moe', 'larry'] + * _.map(characters, 'name'); + * // => ['barney', 'fred'] */ function map(collection, callback, thisArg) { var index = -1, @@ -13790,23 +13982,28 @@ d3.tip = function() { * _.max([4, 2, 8, 6]); * // => 8 * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * - * _.max(stooges, function(stooge) { return stooge.age; }); - * // => { 'name': 'larry', 'age': 50 }; + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; * * // using "_.pluck" callback shorthand - * _.max(stooges, 'age'); - * // => { 'name': 'larry', 'age': 50 }; + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; */ function max(collection, callback, thisArg) { var computed = -Infinity, result = computed; - if (!callback && isArray(collection)) { + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { var index = -1, length = collection.length; @@ -13817,7 +14014,7 @@ d3.tip = function() { } } } else { - callback = (!callback && isString(collection)) + callback = (callback == null && isString(collection)) ? charAtCallback : lodash.createCallback(callback, thisArg, 3); @@ -13860,23 +14057,28 @@ d3.tip = function() { * _.min([4, 2, 8, 6]); * // => 2 * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * - * _.min(stooges, function(stooge) { return stooge.age; }); - * // => { 'name': 'moe', 'age': 40 }; + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; * * // using "_.pluck" callback shorthand - * _.min(stooges, 'age'); - * // => { 'name': 'moe', 'age': 40 }; + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; */ function min(collection, callback, thisArg) { var computed = Infinity, result = computed; - if (!callback && isArray(collection)) { + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { var index = -1, length = collection.length; @@ -13887,7 +14089,7 @@ d3.tip = function() { } } } else { - callback = (!callback && isString(collection)) + callback = (callback == null && isString(collection)) ? charAtCallback : lodash.createCallback(callback, thisArg, 3); @@ -13903,7 +14105,7 @@ d3.tip = function() { } /** - * Retrieves the value of a specified property from all elements in the `collection`. + * Retrieves the value of a specified property from all elements in the collection. * * @static * @memberOf _ @@ -13914,13 +14116,13 @@ d3.tip = function() { * @returns {Array} Returns a new array of property values. * @example * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * - * _.pluck(stooges, 'name'); - * // => ['moe', 'larry'] + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] */ function pluck(collection, property) { var index = -1, @@ -13968,7 +14170,7 @@ d3.tip = function() { function reduce(collection, callback, accumulator, thisArg) { if (!collection) return accumulator; var noaccum = arguments.length < 3; - callback = baseCreateCallback(callback, thisArg, 4); + callback = lodash.createCallback(callback, thisArg, 4); var index = -1, length = collection.length; @@ -14011,7 +14213,7 @@ d3.tip = function() { */ function reduceRight(collection, callback, accumulator, thisArg) { var noaccum = arguments.length < 3; - callback = baseCreateCallback(callback, thisArg, 4); + callback = lodash.createCallback(callback, thisArg, 4); forEachRight(collection, function(value, index, collection) { accumulator = noaccum ? (noaccum = false, value) @@ -14045,18 +14247,18 @@ d3.tip = function() { * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); * // => [1, 3, 5] * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.reject(food, 'organic'); - * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }] + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] * * // using "_.where" callback shorthand - * _.reject(food, { 'type': 'fruit' }); - * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }] + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] */ function reject(collection, callback, thisArg) { callback = lodash.createCallback(callback, thisArg, 3); @@ -14073,8 +14275,8 @@ d3.tip = function() { * @category Collections * @param {Array|Object|string} collection The collection to sample. * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions, like `_.map`, - * without using their `key` and `object` arguments as sources. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. * @returns {Array} Returns the random sample(s) of `collection`. * @example * @@ -14085,12 +14287,11 @@ d3.tip = function() { * // => [3, 1] */ function sample(collection, n, guard) { - var length = collection ? collection.length : 0; - if (typeof length != 'number') { + if (collection && typeof collection.length != 'number') { collection = values(collection); } if (n == null || guard) { - return collection ? collection[random(length - 1)] : undefined; + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; } var result = shuffle(collection); result.length = nativeMin(nativeMax(0, n), result.length); @@ -14117,7 +14318,7 @@ d3.tip = function() { result = Array(typeof length == 'number' ? length : 0); forEach(collection, function(value) { - var rand = random(++index); + var rand = baseRandom(0, ++index); result[index] = result[rand]; result[rand] = value; }); @@ -14141,7 +14342,7 @@ d3.tip = function() { * _.size({ 'one': 1, 'two': 2, 'three': 3 }); * // => 3 * - * _.size('curly'); + * _.size('pebbles'); * // => 5 */ function size(collection) { @@ -14178,17 +14379,17 @@ d3.tip = function() { * _.some([null, 0, 'yes', false], Boolean); * // => true * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } * ]; * * // using "_.pluck" callback shorthand - * _.some(food, 'organic'); + * _.some(characters, 'blocked'); * // => true * * // using "_.where" callback shorthand - * _.some(food, { 'type': 'meat' }); + * _.some(characters, { 'age': 1 }); * // => false */ function some(collection, callback, thisArg) { @@ -14304,16 +14505,16 @@ d3.tip = function() { * @returns {Array} Returns a new array of elements that have the given properties. * @example * - * var stooges = [ - * { 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }, - * { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] } + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } * ]; * - * _.where(stooges, { 'age': 40 }); - * // => [{ 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }] + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] * - * _.where(stooges, { 'quotes': ['Poifect!'] }); - * // => [{ 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }] + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] */ var where = filter; @@ -14355,7 +14556,7 @@ d3.tip = function() { * @memberOf _ * @category Arrays * @param {Array} array The array to process. - * @param {...Array} [array] The arrays of values to exclude. + * @param {...Array} [values] The arrays of values to exclude. * @returns {Array} Returns a new array of filtered values. * @example * @@ -14363,39 +14564,20 @@ d3.tip = function() { * // => [1, 3, 4] */ function difference(array) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - seen = baseFlatten(arguments, true, true, 1), - result = []; - - var isLarge = length >= largeArraySize && indexOf === baseIndexOf; - - if (isLarge) { - var cache = createCache(seen); - if (cache) { - indexOf = cacheIndexOf; - seen = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(seen, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(seen); - } - return result; + return baseDifference(array, baseFlatten(arguments, true, true, 1)); } /** * This method is like `_.find` except that it returns the index of the first * element that passes the callback check, instead of the element itself. * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * * @static * @memberOf _ * @category Arrays @@ -14407,9 +14589,23 @@ d3.tip = function() { * @returns {number} Returns the index of the found element, else `-1`. * @example * - * _.findIndex(['apple', 'banana', 'beet'], function(food) { - * return /^b/.test(food); + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); * // => 1 */ function findIndex(array, callback, thisArg) { @@ -14429,6 +14625,13 @@ d3.tip = function() { * This method is like `_.findIndex` except that it iterates over elements * of a `collection` from right to left. * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * * @static * @memberOf _ * @category Arrays @@ -14440,9 +14643,23 @@ d3.tip = function() { * @returns {number} Returns the index of the found element, else `-1`. * @example * - * _.findLastIndex(['apple', 'banana', 'beet'], function(food) { - * return /^b/.test(food); + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); * // => 2 */ function findLastIndex(array, callback, thisArg) { @@ -14493,24 +14710,19 @@ d3.tip = function() { * }); * // => [1, 2] * - * var food = [ - * { 'name': 'banana', 'organic': true }, - * { 'name': 'beet', 'organic': false }, + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } * ]; * * // using "_.pluck" callback shorthand - * _.first(food, 'organic'); - * // => [{ 'name': 'banana', 'organic': true }] - * - * var food = [ - * { 'name': 'apple', 'type': 'fruit' }, - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' } - * ]; + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] * * // using "_.where" callback shorthand - * _.first(food, { 'type': 'fruit' }); - * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }] + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] */ function first(array, callback, thisArg) { var n = 0, @@ -14563,20 +14775,20 @@ d3.tip = function() { * _.flatten([1, [2], [3, [[4]]]], true); * // => [1, 2, 3, [[4]]]; * - * var stooges = [ - * { 'name': 'curly', 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }, - * { 'name': 'moe', 'quotes': ['Spread out!', 'You knucklehead!'] } + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } * ]; * * // using "_.pluck" callback shorthand - * _.flatten(stooges, 'quotes'); - * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!'] + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] */ function flatten(array, isShallow, callback, thisArg) { // juggle arguments if (typeof isShallow != 'boolean' && isShallow != null) { thisArg = callback; - callback = !(thisArg && thisArg[isShallow] === array) ? isShallow : null; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; isShallow = false; } if (callback != null) { @@ -14656,24 +14868,19 @@ d3.tip = function() { * }); * // => [1] * - * var food = [ - * { 'name': 'beet', 'organic': false }, - * { 'name': 'carrot', 'organic': true } + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } * ]; * * // using "_.pluck" callback shorthand - * _.initial(food, 'organic'); - * // => [{ 'name': 'beet', 'organic': false }] - * - * var food = [ - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' }, - * { 'name': 'carrot', 'type': 'vegetable' } - * ]; + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] * * // using "_.where" callback shorthand - * _.initial(food, { 'type': 'vegetable' }); - * // => [{ 'name': 'banana', 'type': 'fruit' }] + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] */ function initial(array, callback, thisArg) { var n = 0, @@ -14786,24 +14993,19 @@ d3.tip = function() { * }); * // => [2, 3] * - * var food = [ - * { 'name': 'beet', 'organic': false }, - * { 'name': 'carrot', 'organic': true } + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } * ]; * * // using "_.pluck" callback shorthand - * _.last(food, 'organic'); - * // => [{ 'name': 'carrot', 'organic': true }] - * - * var food = [ - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' }, - * { 'name': 'carrot', 'type': 'vegetable' } - * ]; + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] * * // using "_.where" callback shorthand - * _.last(food, { 'type': 'vegetable' }); - * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }] + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] */ function last(array, callback, thisArg) { var n = 0, @@ -14829,6 +15031,13 @@ d3.tip = function() { * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used * as the offset from the end of the collection. * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * * @static * @memberOf _ * @category Arrays @@ -14907,17 +15116,17 @@ d3.tip = function() { * @returns {Array} Returns a new range array. * @example * - * _.range(10); - * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + * _.range(4); + * // => [0, 1, 2, 3] * - * _.range(1, 11); - * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + * _.range(1, 5); + * // => [1, 2, 3, 4] * - * _.range(0, 30, 5); - * // => [0, 5, 10, 15, 20, 25] + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] * - * _.range(0, -10, -1); - * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] * * _.range(1, 4, 0); * // => [1, 1, 1] @@ -14933,7 +15142,7 @@ d3.tip = function() { end = start; start = 0; } - // use `Array(length)` so engines, like Chakra and V8, avoid slower modes + // use `Array(length)` so engines like Chakra and V8 avoid slower modes // http://youtu.be/XAqIpGU8ZZk#t=17m25s var index = -1, length = nativeMax(0, ceil((end - start) / (step || 1))), @@ -15033,24 +15242,19 @@ d3.tip = function() { * }); * // => [3] * - * var food = [ - * { 'name': 'banana', 'organic': true }, - * { 'name': 'beet', 'organic': false }, + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } * ]; * * // using "_.pluck" callback shorthand - * _.rest(food, 'organic'); - * // => [{ 'name': 'beet', 'organic': false }] - * - * var food = [ - * { 'name': 'apple', 'type': 'fruit' }, - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' } - * ]; + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] * * // using "_.where" callback shorthand - * _.rest(food, { 'type': 'fruit' }); - * // => [{ 'name': 'beet', 'type': 'vegetable' }] + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] */ function rest(array, callback, thisArg) { if (typeof callback != 'number' && callback != null) { @@ -15199,7 +15403,7 @@ d3.tip = function() { // juggle arguments if (typeof isSorted != 'boolean' && isSorted != null) { thisArg = callback; - callback = !(thisArg && thisArg[isSorted] === array) ? isSorted : null; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; isSorted = false; } if (callback != null) { @@ -15224,7 +15428,7 @@ d3.tip = function() { * // => [2, 3, 4] */ function without(array) { - return difference(array, nativeSlice.call(arguments, 1)); + return baseDifference(array, slice(arguments, 1)); } /** @@ -15240,8 +15444,8 @@ d3.tip = function() { * @returns {Array} Returns a new array of grouped elements. * @example * - * _.zip(['moe', 'larry'], [30, 40], [true, false]); - * // => [['moe', 30, true], ['larry', 40, false]] + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] */ function zip() { var array = arguments.length > 1 ? arguments : arguments[0], @@ -15270,8 +15474,8 @@ d3.tip = function() { * corresponding values. * @example * - * _.zipObject(['moe', 'larry'], [30, 40]); - * // => { 'moe': 30, 'larry': 40 } + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } */ function zipObject(keys, values) { var index = -1, @@ -15344,14 +15548,14 @@ d3.tip = function() { * return greeting + ' ' + this.name; * }; * - * func = _.bind(func, { 'name': 'moe' }, 'hi'); + * func = _.bind(func, { 'name': 'fred' }, 'hi'); * func(); - * // => 'hi moe' + * // => 'hi fred' */ function bind(func, thisArg) { return arguments.length > 2 - ? createBound(func, 17, nativeSlice.call(arguments, 2), null, thisArg) - : createBound(func, 1, null, null, thisArg); + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); } /** @@ -15385,7 +15589,7 @@ d3.tip = function() { while (++index < length) { var key = funcs[index]; - object[key] = createBound(object[key], 1, null, null, object); + object[key] = createWrapper(object[key], 1, null, null, object); } return object; } @@ -15407,7 +15611,7 @@ d3.tip = function() { * @example * * var object = { - * 'name': 'moe', + * 'name': 'fred', * 'greet': function(greeting) { * return greeting + ' ' + this.name; * } @@ -15415,19 +15619,19 @@ d3.tip = function() { * * var func = _.bindKey(object, 'greet', 'hi'); * func(); - * // => 'hi moe' + * // => 'hi fred' * * object.greet = function(greeting) { - * return greeting + ', ' + this.name + '!'; + * return greeting + 'ya ' + this.name + '!'; * }; * * func(); - * // => 'hi, moe!' + * // => 'hiya fred!' */ function bindKey(object, key) { return arguments.length > 2 - ? createBound(key, 19, nativeSlice.call(arguments, 2), null, object) - : createBound(key, 3, null, null, object); + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); } /** @@ -15444,7 +15648,7 @@ d3.tip = function() { * @example * * var realNameMap = { - * 'curly': 'jerome' + * 'pebbles': 'penelope' * }; * * var format = function(name) { @@ -15457,8 +15661,8 @@ d3.tip = function() { * }; * * var welcome = _.compose(greet, format); - * welcome('curly'); - * // => 'Hiya Jerome!' + * welcome('pebbles'); + * // => 'Hiya Penelope!' */ function compose() { var funcs = arguments, @@ -15495,9 +15699,9 @@ d3.tip = function() { * @returns {Function} Returns a callback function. * @example * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } * ]; * * // wrap to create custom callback shorthands @@ -15508,8 +15712,8 @@ d3.tip = function() { * }; * }); * - * _.filter(stooges, 'age__gt45'); - * // => [{ 'name': 'larry', 'age': 50 }] + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] */ function createCallback(func, thisArg, argCount) { var type = typeof func; @@ -15578,7 +15782,7 @@ d3.tip = function() { */ function curry(func, arity) { arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createBound(func, 4, null, null, null, arity); + return createWrapper(func, 4, null, null, null, arity); } /** @@ -15655,6 +15859,9 @@ d3.tip = function() { if (isCalled) { lastCalled = now(); result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } } } else { timeoutId = setTimeout(delayed, remaining); @@ -15669,6 +15876,9 @@ d3.tip = function() { if (trailing || (maxWait !== wait)) { lastCalled = now(); result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } } }; @@ -15684,8 +15894,10 @@ d3.tip = function() { if (!maxTimeoutId && !leading) { lastCalled = stamp; } - var remaining = maxWait - (stamp - lastCalled); - if (remaining <= 0) { + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { if (maxTimeoutId) { maxTimeoutId = clearTimeout(maxTimeoutId); } @@ -15696,12 +15908,19 @@ d3.tip = function() { maxTimeoutId = setTimeout(maxDelayed, remaining); } } - if (!timeoutId && wait !== maxWait) { + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { timeoutId = setTimeout(delayed, wait); } if (leadingCall) { + isCalled = true; result = func.apply(thisArg, args); } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } return result; }; } @@ -15725,11 +15944,11 @@ d3.tip = function() { if (!isFunction(func)) { throw new TypeError; } - var args = nativeSlice.call(arguments, 1); + var args = slice(arguments, 1); return setTimeout(function() { func.apply(undefined, args); }, 1); } // use `setImmediate` if available in Node.js - if (isV8 && moduleExports && typeof setImmediate == 'function') { + if (setImmediate) { defer = function(func) { if (!isFunction(func)) { throw new TypeError; @@ -15759,7 +15978,7 @@ d3.tip = function() { if (!isFunction(func)) { throw new TypeError; } - var args = nativeSlice.call(arguments, 2); + var args = slice(arguments, 2); return setTimeout(function() { func.apply(undefined, args); }, wait); } @@ -15783,19 +16002,22 @@ d3.tip = function() { * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); * }); * + * fibonacci(9) + * // => 34 + * * var data = { - * 'moe': { 'name': 'moe', 'age': 40 }, - * 'curly': { 'name': 'curly', 'age': 60 } + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } * }; * * // modifying the result cache - * var stooge = _.memoize(function(name) { return data[name]; }, _.identity); - * stooge('curly'); - * // => { 'name': 'curly', 'age': 60 } + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } * - * stooge.cache.curly.name = 'jerome'; - * stooge('curly'); - * // => { 'name': 'jerome', 'age': 60 } + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } */ function memoize(func, resolver) { if (!isFunction(func)) { @@ -15865,11 +16087,11 @@ d3.tip = function() { * * var greet = function(greeting, name) { return greeting + ' ' + name; }; * var hi = _.partial(greet, 'hi'); - * hi('moe'); - * // => 'hi moe' + * hi('fred'); + * // => 'hi fred' */ function partial(func) { - return createBound(func, 16, nativeSlice.call(arguments, 1)); + return createWrapper(func, 16, slice(arguments, 1)); } /** @@ -15900,7 +16122,7 @@ d3.tip = function() { * // => { '_': _, 'jq': $ } */ function partialRight(func) { - return createBound(func, 32, null, nativeSlice.call(arguments, 1)); + return createWrapper(func, 32, null, slice(arguments, 1)); } /** @@ -15951,8 +16173,7 @@ d3.tip = function() { debounceOptions.maxWait = wait; debounceOptions.trailing = trailing; - var result = debounce(func, wait, debounceOptions); - return result; + return debounce(func, wait, debounceOptions); } /** @@ -15969,22 +16190,15 @@ d3.tip = function() { * @returns {Function} Returns the new function. * @example * - * var hello = function(name) { return 'hello ' + name; }; - * hello = _.wrap(hello, function(func) { - * return 'before, ' + func('moe') + ', after'; + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; * }); - * hello(); - * // => 'before, hello moe, after' + * + * p('Fred, Wilma, & Pebbles'); + * // => '

Fred, Wilma, & Pebbles

' */ function wrap(value, wrapper) { - if (!isFunction(wrapper)) { - throw new TypeError; - } - return function() { - var args = [value]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; + return createWrapper(wrapper, 16, [value]); } /*--------------------------------------------------------------------------*/ @@ -16000,8 +16214,8 @@ d3.tip = function() { * @returns {string} Returns the escaped string. * @example * - * _.escape('Moe, Larry & Curly'); - * // => 'Moe, Larry & Curly' + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' */ function escape(string) { return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); @@ -16017,8 +16231,8 @@ d3.tip = function() { * @returns {*} Returns `value`. * @example * - * var moe = { 'name': 'moe' }; - * moe === _.identity(moe); + * var object = { 'name': 'fred' }; + * _.identity(object) === object; * // => true */ function identity(value) { @@ -16042,11 +16256,11 @@ d3.tip = function() { * } * }); * - * _.capitalize('moe'); - * // => 'Moe' + * _.capitalize('fred'); + * // => 'Fred' * - * _('moe').capitalize(); - * // => 'Moe' + * _('fred').capitalize(); + * // => 'Fred' */ function mixin(object, source) { var ctor = object, @@ -16094,6 +16308,22 @@ d3.tip = function() { return this; } + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + /** * Converts the given value into an integer of the specified radix. * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the @@ -16114,7 +16344,7 @@ d3.tip = function() { * // => 8 */ var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox and Opera still follow the ES3 specified implementation of `parseInt` + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); }; @@ -16169,10 +16399,11 @@ d3.tip = function() { } else { max = +max || 0; } - var rand = nativeRandom(); - return (floating || min % 1 || max % 1) - ? nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max) - : min + floor(rand * (max - min + 1)); + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); } /** @@ -16217,7 +16448,7 @@ d3.tip = function() { * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl * * For more information on precompiling templates see: - * http://lodash.com/#custom-builds + * http://lodash.com/custom-builds * * For more information on Chrome extension sandboxes see: * http://developer.chrome.com/stable/extensions/sandboxingEval.html @@ -16240,8 +16471,8 @@ d3.tip = function() { * * // using the "interpolate" delimiter to create a compiled template * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'moe' }); - * // => 'hello moe' + * compiled({ 'name': 'fred' }); + * // => 'hello fred' * * // using the "escape" delimiter to escape HTML in data property values * _.template('<%- value %>', { 'value': '