lodash-rails 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 127626c96a38e9e6b845fd385051de464995747d
4
- data.tar.gz: 1fa0af7bb2d5282431d3c4e6effe524caebbae3b
3
+ metadata.gz: 609a957fdd98e57cda8ec71991b828b347e1f72b
4
+ data.tar.gz: ee91615b8dab7e1a09736c0bc29bbf2d39537fd5
5
5
  SHA512:
6
- metadata.gz: 668650791626261ffce969aa9b2592783b79f81aa4479690ad9921a97968d6b0634de5bdbbf7117f5d5f2281762fbc2bc10bcdd8f4a231740f290cf39074a366
7
- data.tar.gz: 8aabf47d94e3251e278af2db1aa8e2f5e6e9d13cc546a4e818d8372bb384227412d852362c7eded659b52edf76cbb477c1b57aa3d0a7706809420eb82dd21ede
6
+ metadata.gz: 58cf03aa0a3a6e6fcd79d1184f739e10fd146ab805e01619d2e0e9191962ff5b84d380c4def7dfeb29516df8309d61411c416a448859fb52a232f6736d15b635
7
+ data.tar.gz: bfadb809b748b42dda8766341b9979f0cbbed08776b399ec55c31ecc3570d17ac4eab3105f407b67c3e714488b566143981255d4407326fc64bd6626dc4ab6ac
data/README.md CHANGED
@@ -18,7 +18,7 @@ Add the necessary library to `app/assets/javascripts/application.js`:
18
18
 
19
19
  ## What's included?
20
20
 
21
- Lo-Dash 2.2.1:
21
+ Lo-Dash 2.3.0:
22
22
 
23
23
  * lodash.js
24
24
  * lodash.min.js
@@ -1,5 +1,5 @@
1
1
  module LoDash
2
2
  module Rails
3
- VERSION = "2.2.1"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Lo-Dash 2.2.1 (Custom Build) <http://lodash.com/>
3
+ * Lo-Dash 2.3.0 (Custom Build) <http://lodash.com/>
4
4
  * Build: `lodash -o ./dist/lodash.compat.js`
5
5
  * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
6
6
  * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
@@ -58,7 +58,7 @@
58
58
  var reFlags = /\w*$/;
59
59
 
60
60
  /** Used to detected named functions */
61
- var reFuncName = /^function[ \n\r\t]+\w/;
61
+ var reFuncName = /^\s*function[ \n\r\t]+\w/;
62
62
 
63
63
  /** Used to match "interpolate" template delimiters */
64
64
  var reInterpolate = /<%=([\s\S]+?)%>/g;
@@ -391,15 +391,6 @@
391
391
  return typeof value.toString != 'function' && typeof (value + '') == 'string';
392
392
  }
393
393
 
394
- /**
395
- * A no-operation function.
396
- *
397
- * @private
398
- */
399
- function noop() {
400
- // no operation performed
401
- }
402
-
403
394
  /**
404
395
  * Releases the given array back to the array pool.
405
396
  *
@@ -505,11 +496,14 @@
505
496
  /** Used to restore the original `_` reference in `noConflict` */
506
497
  var oldDash = context._;
507
498
 
499
+ /** Used to resolve the internal [[Class]] of values */
500
+ var toString = objectProto.toString;
501
+
508
502
  /** Used to detect if a method is native */
509
503
  var reNative = RegExp('^' +
510
- String(objectProto.valueOf)
504
+ String(toString)
511
505
  .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
512
- .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
506
+ .replace(/toString| for [^\]]+/g, '.*?') + '$'
513
507
  );
514
508
 
515
509
  /** Native method shortcuts */
@@ -522,13 +516,16 @@
522
516
  now = reNative.test(now = Date.now) && now || function() { return +new Date; },
523
517
  push = arrayRef.push,
524
518
  propertyIsEnumerable = objectProto.propertyIsEnumerable,
525
- setImmediate = context.setImmediate,
526
519
  setTimeout = context.setTimeout,
527
- splice = arrayRef.splice,
528
- toString = objectProto.toString,
529
- unshift = arrayRef.unshift;
520
+ splice = arrayRef.splice;
521
+
522
+ /** Used to detect `setImmediate` in Node.js */
523
+ var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
524
+ !reNative.test(setImmediate) && setImmediate;
530
525
 
526
+ /** Used to set meta data on functions */
531
527
  var defineProperty = (function() {
528
+ // IE 8 only accepts DOM elements
532
529
  try {
533
530
  var o = {},
534
531
  func = reNative.test(func = Object.defineProperty) && func,
@@ -538,8 +535,7 @@
538
535
  }());
539
536
 
540
537
  /* Native method shortcuts for methods with the same name as other `lodash` methods */
541
- var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
542
- nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
538
+ var nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
543
539
  nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
544
540
  nativeIsFinite = context.isFinite,
545
541
  nativeIsNaN = context.isNaN,
@@ -547,12 +543,7 @@
547
543
  nativeMax = Math.max,
548
544
  nativeMin = Math.min,
549
545
  nativeParseInt = context.parseInt,
550
- nativeRandom = Math.random,
551
- nativeSlice = arrayRef.slice;
552
-
553
- /** Detect various environments */
554
- var isIeOpera = reNative.test(context.attachEvent),
555
- isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
546
+ nativeRandom = Math.random;
556
547
 
557
548
  /** Used to lookup a built-in constructor by [[Class]] */
558
549
  var ctorByClass = {};
@@ -575,10 +566,10 @@
575
566
  (function() {
576
567
  var length = shadowedProps.length;
577
568
  while (length--) {
578
- var prop = shadowedProps[length];
569
+ var key = shadowedProps[length];
579
570
  for (var className in nonEnumProps) {
580
- if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], prop)) {
581
- nonEnumProps[className][prop] = false;
571
+ if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
572
+ nonEnumProps[className][key] = false;
582
573
  }
583
574
  }
584
575
  }
@@ -599,15 +590,16 @@
599
590
  *
600
591
  * The chainable wrapper functions are:
601
592
  * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
602
- * `compose`, `concat`, `countBy`, `createCallback`, `curry`, `debounce`,
603
- * `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`,
604
- * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
605
- * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
606
- * `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, `once`, `pairs`,
607
- * `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, `range`, `reject`,
608
- * `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
609
- * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
610
- * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
593
+ * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
594
+ * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
595
+ * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
596
+ * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
597
+ * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
598
+ * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
599
+ * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
600
+ * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
601
+ * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
602
+ * and `zip`
611
603
  *
612
604
  * The non-chainable wrapper functions are:
613
605
  * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
@@ -687,8 +679,8 @@
687
679
  props = [];
688
680
 
689
681
  ctor.prototype = { 'valueOf': 1, 'y': 1 };
690
- for (var prop in new ctor) { props.push(prop); }
691
- for (prop in arguments) { }
682
+ for (var key in new ctor) { props.push(key); }
683
+ for (key in arguments) { }
692
684
 
693
685
  /**
694
686
  * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
@@ -728,14 +720,6 @@
728
720
  */
729
721
  support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
730
722
 
731
- /**
732
- * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
733
- *
734
- * @memberOf _.support
735
- * @type boolean
736
- */
737
- support.fastBind = nativeBind && !isV8;
738
-
739
723
  /**
740
724
  * Detect if functions can be decompiled by `Function#toString`
741
725
  * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
@@ -760,7 +744,7 @@
760
744
  * @memberOf _.support
761
745
  * @type boolean
762
746
  */
763
- support.nonEnumArgs = prop != 0;
747
+ support.nonEnumArgs = key != 0;
764
748
 
765
749
  /**
766
750
  * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
@@ -984,19 +968,53 @@
984
968
 
985
969
  /*--------------------------------------------------------------------------*/
986
970
 
971
+ /**
972
+ * The base implementation of `_.bind` that creates the bound function and
973
+ * sets its meta data.
974
+ *
975
+ * @private
976
+ * @param {Array} bindData The bind data array.
977
+ * @returns {Function} Returns the new bound function.
978
+ */
979
+ function baseBind(bindData) {
980
+ var func = bindData[0],
981
+ partialArgs = bindData[2],
982
+ thisArg = bindData[4];
983
+
984
+ function bound() {
985
+ // `Function#bind` spec
986
+ // http://es5.github.io/#x15.3.4.5
987
+ if (partialArgs) {
988
+ var args = partialArgs.slice();
989
+ push.apply(args, arguments);
990
+ }
991
+ // mimic the constructor's `return` behavior
992
+ // http://es5.github.io/#x13.2.2
993
+ if (this instanceof bound) {
994
+ // ensure `new bound` is an instance of `func`
995
+ var thisBinding = baseCreate(func.prototype),
996
+ result = func.apply(thisBinding, args || arguments);
997
+ return isObject(result) ? result : thisBinding;
998
+ }
999
+ return func.apply(thisArg, args || arguments);
1000
+ }
1001
+ setBindData(bound, bindData);
1002
+ return bound;
1003
+ }
1004
+
987
1005
  /**
988
1006
  * The base implementation of `_.clone` without argument juggling or support
989
1007
  * for `thisArg` binding.
990
1008
  *
991
1009
  * @private
992
1010
  * @param {*} value The value to clone.
993
- * @param {boolean} [deep=false] Specify a deep clone.
1011
+ * @param {boolean} [isDeep=false] Specify a deep clone.
994
1012
  * @param {Function} [callback] The function to customize cloning values.
995
1013
  * @param {Array} [stackA=[]] Tracks traversed source objects.
996
1014
  * @param {Array} [stackB=[]] Associates clones with source counterparts.
997
1015
  * @returns {*} Returns the cloned value.
998
1016
  */
999
- function baseClone(value, deep, callback, stackA, stackB) {
1017
+ function baseClone(value, isDeep, callback, stackA, stackB) {
1000
1018
  if (callback) {
1001
1019
  var result = callback(value);
1002
1020
  if (typeof result != 'undefined') {
@@ -1029,7 +1047,7 @@
1029
1047
  return value;
1030
1048
  }
1031
1049
  var isArr = isArray(value);
1032
- if (deep) {
1050
+ if (isDeep) {
1033
1051
  // check for circular references and return corresponding clone
1034
1052
  var initedStack = !stackA;
1035
1053
  stackA || (stackA = getArray());
@@ -1056,7 +1074,7 @@
1056
1074
  }
1057
1075
  }
1058
1076
  // exit for shallow clone
1059
- if (!deep) {
1077
+ if (!isDeep) {
1060
1078
  return result;
1061
1079
  }
1062
1080
  // add the source value to the stack of traversed objects
@@ -1066,7 +1084,7 @@
1066
1084
 
1067
1085
  // recursively populate clone (susceptible to call stack limits)
1068
1086
  (isArr ? baseEach : forOwn)(value, function(objValue, key) {
1069
- result[key] = baseClone(objValue, deep, callback, stackA, stackB);
1087
+ result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
1070
1088
  });
1071
1089
 
1072
1090
  if (initedStack) {
@@ -1076,6 +1094,32 @@
1076
1094
  return result;
1077
1095
  }
1078
1096
 
1097
+ /**
1098
+ * The base implementation of `_.create` without support for assigning
1099
+ * properties to the created object.
1100
+ *
1101
+ * @private
1102
+ * @param {Object} prototype The object to inherit from.
1103
+ * @returns {Object} Returns the new object.
1104
+ */
1105
+ function baseCreate(prototype, properties) {
1106
+ return isObject(prototype) ? nativeCreate(prototype) : {};
1107
+ }
1108
+ // fallback for browsers without `Object.create`
1109
+ if (!nativeCreate) {
1110
+ baseCreate = (function() {
1111
+ function Object() {}
1112
+ return function(prototype) {
1113
+ if (isObject(prototype)) {
1114
+ Object.prototype = prototype;
1115
+ var result = new Object;
1116
+ Object.prototype = null;
1117
+ }
1118
+ return result || context.Object();
1119
+ };
1120
+ }());
1121
+ }
1122
+
1079
1123
  /**
1080
1124
  * The base implementation of `_.createCallback` without support for creating
1081
1125
  * "_.pluck" or "_.where" style callbacks.
@@ -1090,24 +1134,30 @@
1090
1134
  if (typeof func != 'function') {
1091
1135
  return identity;
1092
1136
  }
1093
- // exit early if there is no `thisArg`
1094
- if (typeof thisArg == 'undefined') {
1137
+ // exit early for no `thisArg` or already bound by `Function#bind`
1138
+ if (typeof thisArg == 'undefined' || !('prototype' in func)) {
1095
1139
  return func;
1096
1140
  }
1097
- var bindData = func.__bindData__ || (support.funcNames && !func.name);
1141
+ var bindData = func.__bindData__;
1098
1142
  if (typeof bindData == 'undefined') {
1099
- var source = reThis && fnToString.call(func);
1100
- if (!support.funcNames && source && !reFuncName.test(source)) {
1101
- bindData = true;
1143
+ if (support.funcNames) {
1144
+ bindData = !func.name;
1102
1145
  }
1103
- if (support.funcNames || !bindData) {
1104
- // checks if `func` references the `this` keyword and stores the result
1105
- bindData = !support.funcDecomp || reThis.test(source);
1106
- setBindData(func, bindData);
1146
+ bindData = bindData || !support.funcDecomp;
1147
+ if (!bindData) {
1148
+ var source = fnToString.call(func);
1149
+ if (!support.funcNames) {
1150
+ bindData = !reFuncName.test(source);
1151
+ }
1152
+ if (!bindData) {
1153
+ // checks if `func` references the `this` keyword and stores the result
1154
+ bindData = reThis.test(source);
1155
+ setBindData(func, bindData);
1156
+ }
1107
1157
  }
1108
1158
  }
1109
1159
  // exit early if there are no `this` references or `func` is bound
1110
- if (bindData !== true && (bindData && bindData[1] & 1)) {
1160
+ if (bindData === false || (bindData !== true && bindData[1] & 1)) {
1111
1161
  return func;
1112
1162
  }
1113
1163
  switch (argCount) {
@@ -1127,6 +1177,96 @@
1127
1177
  return bind(func, thisArg);
1128
1178
  }
1129
1179
 
1180
+ /**
1181
+ * The base implementation of `createWrapper` that creates the wrapper and
1182
+ * sets its meta data.
1183
+ *
1184
+ * @private
1185
+ * @param {Array} bindData The bind data array.
1186
+ * @returns {Function} Returns the new function.
1187
+ */
1188
+ function baseCreateWrapper(bindData) {
1189
+ var func = bindData[0],
1190
+ bitmask = bindData[1],
1191
+ partialArgs = bindData[2],
1192
+ partialRightArgs = bindData[3],
1193
+ thisArg = bindData[4],
1194
+ arity = bindData[5];
1195
+
1196
+ var isBind = bitmask & 1,
1197
+ isBindKey = bitmask & 2,
1198
+ isCurry = bitmask & 4,
1199
+ isCurryBound = bitmask & 8,
1200
+ key = func;
1201
+
1202
+ function bound() {
1203
+ var thisBinding = isBind ? thisArg : this;
1204
+ if (partialArgs) {
1205
+ var args = partialArgs.slice();
1206
+ push.apply(args, arguments);
1207
+ }
1208
+ if (partialRightArgs || isCurry) {
1209
+ args || (args = slice(arguments));
1210
+ if (partialRightArgs) {
1211
+ push.apply(args, partialRightArgs);
1212
+ }
1213
+ if (isCurry && args.length < arity) {
1214
+ bitmask |= 16 & ~32;
1215
+ return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
1216
+ }
1217
+ }
1218
+ args || (args = arguments);
1219
+ if (isBindKey) {
1220
+ func = thisBinding[key];
1221
+ }
1222
+ if (this instanceof bound) {
1223
+ thisBinding = baseCreate(func.prototype);
1224
+ var result = func.apply(thisBinding, args);
1225
+ return isObject(result) ? result : thisBinding;
1226
+ }
1227
+ return func.apply(thisBinding, args);
1228
+ }
1229
+ setBindData(bound, bindData);
1230
+ return bound;
1231
+ }
1232
+
1233
+ /**
1234
+ * The base implementation of `_.difference` that accepts a single array
1235
+ * of values to exclude.
1236
+ *
1237
+ * @private
1238
+ * @param {Array} array The array to process.
1239
+ * @param {Array} [values] The array of values to exclude.
1240
+ * @returns {Array} Returns a new array of filtered values.
1241
+ */
1242
+ function baseDifference(array, values) {
1243
+ var index = -1,
1244
+ indexOf = getIndexOf(),
1245
+ length = array ? array.length : 0,
1246
+ isLarge = length >= largeArraySize && indexOf === baseIndexOf,
1247
+ result = [];
1248
+
1249
+ if (isLarge) {
1250
+ var cache = createCache(values);
1251
+ if (cache) {
1252
+ indexOf = cacheIndexOf;
1253
+ values = cache;
1254
+ } else {
1255
+ isLarge = false;
1256
+ }
1257
+ }
1258
+ while (++index < length) {
1259
+ var value = array[index];
1260
+ if (indexOf(values, value) < 0) {
1261
+ result.push(value);
1262
+ }
1263
+ }
1264
+ if (isLarge) {
1265
+ releaseObject(values);
1266
+ }
1267
+ return result;
1268
+ }
1269
+
1130
1270
  /**
1131
1271
  * The base implementation of `_.flatten` without support for callback
1132
1272
  * shorthands or `thisArg` binding.
@@ -1134,11 +1274,11 @@
1134
1274
  * @private
1135
1275
  * @param {Array} array The array to flatten.
1136
1276
  * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
1137
- * @param {boolean} [isArgArrays=false] A flag to restrict flattening to arrays and `arguments` objects.
1277
+ * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
1138
1278
  * @param {number} [fromIndex=0] The index to start from.
1139
1279
  * @returns {Array} Returns a new flattened array.
1140
1280
  */
1141
- function baseFlatten(array, isShallow, isArgArrays, fromIndex) {
1281
+ function baseFlatten(array, isShallow, isStrict, fromIndex) {
1142
1282
  var index = (fromIndex || 0) - 1,
1143
1283
  length = array ? array.length : 0,
1144
1284
  result = [];
@@ -1150,7 +1290,7 @@
1150
1290
  && (isArray(value) || isArguments(value))) {
1151
1291
  // recursively flatten arrays (susceptible to call stack limits)
1152
1292
  if (!isShallow) {
1153
- value = baseFlatten(value, isShallow, isArgArrays);
1293
+ value = baseFlatten(value, isShallow, isStrict);
1154
1294
  }
1155
1295
  var valIndex = -1,
1156
1296
  valLength = value.length,
@@ -1160,7 +1300,7 @@
1160
1300
  while (++valIndex < valLength) {
1161
1301
  result[resIndex++] = value[valIndex];
1162
1302
  }
1163
- } else if (!isArgArrays) {
1303
+ } else if (!isStrict) {
1164
1304
  result.push(value);
1165
1305
  }
1166
1306
  }
@@ -1243,8 +1383,11 @@
1243
1383
  var isArr = className == arrayClass;
1244
1384
  if (!isArr) {
1245
1385
  // unwrap any `lodash` wrapped values
1246
- if (hasOwnProperty.call(a, '__wrapped__ ') || hasOwnProperty.call(b, '__wrapped__')) {
1247
- return baseIsEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, isWhere, stackA, stackB);
1386
+ var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
1387
+ bWrapped = hasOwnProperty.call(b, '__wrapped__');
1388
+
1389
+ if (aWrapped || bWrapped) {
1390
+ return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
1248
1391
  }
1249
1392
  // exit for functions and DOM nodes
1250
1393
  if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
@@ -1255,10 +1398,10 @@
1255
1398
  ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
1256
1399
 
1257
1400
  // non `Object` object instances with different constructors are not equal
1258
- if (ctorA != ctorB && !(
1259
- isFunction(ctorA) && ctorA instanceof ctorA &&
1260
- isFunction(ctorB) && ctorB instanceof ctorB
1261
- )) {
1401
+ if (ctorA != ctorB &&
1402
+ !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
1403
+ ('constructor' in a && 'constructor' in b)
1404
+ ) {
1262
1405
  return false;
1263
1406
  }
1264
1407
  }
@@ -1401,6 +1544,19 @@
1401
1544
  });
1402
1545
  }
1403
1546
 
1547
+ /**
1548
+ * The base implementation of `_.random` without argument juggling or support
1549
+ * for returning floating-point numbers.
1550
+ *
1551
+ * @private
1552
+ * @param {number} min The minimum possible value.
1553
+ * @param {number} max The maximum possible value.
1554
+ * @returns {number} Returns a random number.
1555
+ */
1556
+ function baseRandom(min, max) {
1557
+ return min + floor(nativeRandom() * (max - min + 1));
1558
+ }
1559
+
1404
1560
  /**
1405
1561
  * The base implementation of `_.uniq` without support for callback shorthands
1406
1562
  * or `thisArg` binding.
@@ -1505,16 +1661,15 @@
1505
1661
  * provided to the new function.
1506
1662
  * @param {*} [thisArg] The `this` binding of `func`.
1507
1663
  * @param {number} [arity] The arity of `func`.
1508
- * @returns {Function} Returns the new bound function.
1664
+ * @returns {Function} Returns the new function.
1509
1665
  */
1510
- function createBound(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
1666
+ function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
1511
1667
  var isBind = bitmask & 1,
1512
1668
  isBindKey = bitmask & 2,
1513
1669
  isCurry = bitmask & 4,
1514
1670
  isCurryBound = bitmask & 8,
1515
1671
  isPartial = bitmask & 16,
1516
- isPartialRight = bitmask & 32,
1517
- key = func;
1672
+ isPartialRight = bitmask & 32;
1518
1673
 
1519
1674
  if (!isBindKey && !isFunction(func)) {
1520
1675
  throw new TypeError;
@@ -1528,74 +1683,36 @@
1528
1683
  isPartialRight = partialRightArgs = false;
1529
1684
  }
1530
1685
  var bindData = func && func.__bindData__;
1531
- if (bindData) {
1686
+ if (bindData && bindData !== true) {
1687
+ bindData = bindData.slice();
1688
+
1689
+ // set `thisBinding` is not previously bound
1532
1690
  if (isBind && !(bindData[1] & 1)) {
1533
1691
  bindData[4] = thisArg;
1534
1692
  }
1693
+ // set if previously bound but not currently (subsequent curried functions)
1535
1694
  if (!isBind && bindData[1] & 1) {
1536
1695
  bitmask |= 8;
1537
1696
  }
1697
+ // set curried arity if not yet set
1538
1698
  if (isCurry && !(bindData[1] & 4)) {
1539
1699
  bindData[5] = arity;
1540
1700
  }
1701
+ // append partial left arguments
1541
1702
  if (isPartial) {
1542
1703
  push.apply(bindData[2] || (bindData[2] = []), partialArgs);
1543
1704
  }
1705
+ // append partial right arguments
1544
1706
  if (isPartialRight) {
1545
1707
  push.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
1546
1708
  }
1709
+ // merge flags
1547
1710
  bindData[1] |= bitmask;
1548
- return createBound.apply(null, bindData);
1549
- }
1550
- // use `Function#bind` if it exists and is fast
1551
- // (in V8 `Function#bind` is slower except when partially applied)
1552
- if (isBind && !(isBindKey || isCurry || isPartialRight) &&
1553
- (support.fastBind || (nativeBind && isPartial))) {
1554
- if (isPartial) {
1555
- var args = [thisArg];
1556
- push.apply(args, partialArgs);
1557
- }
1558
- var bound = isPartial
1559
- ? nativeBind.apply(func, args)
1560
- : nativeBind.call(func, thisArg);
1561
- }
1562
- else {
1563
- bound = function() {
1564
- // `Function#bind` spec
1565
- // http://es5.github.io/#x15.3.4.5
1566
- var args = arguments,
1567
- thisBinding = isBind ? thisArg : this;
1568
-
1569
- if (isCurry || isPartial || isPartialRight) {
1570
- args = nativeSlice.call(args);
1571
- if (isPartial) {
1572
- unshift.apply(args, partialArgs);
1573
- }
1574
- if (isPartialRight) {
1575
- push.apply(args, partialRightArgs);
1576
- }
1577
- if (isCurry && args.length < arity) {
1578
- bitmask |= 16 & ~32;
1579
- return createBound(func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity);
1580
- }
1581
- }
1582
- if (isBindKey) {
1583
- func = thisBinding[key];
1584
- }
1585
- if (this instanceof bound) {
1586
- // ensure `new bound` is an instance of `func`
1587
- thisBinding = createObject(func.prototype);
1588
-
1589
- // mimic the constructor's `return` behavior
1590
- // http://es5.github.io/#x13.2.2
1591
- var result = func.apply(thisBinding, args);
1592
- return isObject(result) ? result : thisBinding;
1593
- }
1594
- return func.apply(thisBinding, args);
1595
- };
1711
+ return createWrapper.apply(null, bindData);
1596
1712
  }
1597
- setBindData(bound, nativeSlice.call(arguments));
1598
- return bound;
1713
+ // fast path for `_.bind`
1714
+ var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
1715
+ return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
1599
1716
  }
1600
1717
 
1601
1718
  /**
@@ -1646,28 +1763,6 @@
1646
1763
  );
1647
1764
  }
1648
1765
 
1649
- /**
1650
- * Creates a new object with the specified `prototype`.
1651
- *
1652
- * @private
1653
- * @param {Object} prototype The prototype object.
1654
- * @returns {Object} Returns the new object.
1655
- */
1656
- function createObject(prototype) {
1657
- return isObject(prototype) ? nativeCreate(prototype) : {};
1658
- }
1659
- // fallback for browsers without `Object.create`
1660
- if (!nativeCreate) {
1661
- createObject = function(prototype) {
1662
- if (isObject(prototype)) {
1663
- noop.prototype = prototype;
1664
- var result = new noop;
1665
- noop.prototype = null;
1666
- }
1667
- return result || {};
1668
- };
1669
- }
1670
-
1671
1766
  /**
1672
1767
  * Used by `escape` to convert characters to HTML entities.
1673
1768
  *
@@ -1697,7 +1792,7 @@
1697
1792
  *
1698
1793
  * @private
1699
1794
  * @param {Function} func The function to set data on.
1700
- * @param {*} value The value to set.
1795
+ * @param {Array} value The data array to set.
1701
1796
  */
1702
1797
  var setBindData = !defineProperty ? noop : function(func, value) {
1703
1798
  descriptor.value = value;
@@ -1781,7 +1876,7 @@
1781
1876
  if (!support.argsClass) {
1782
1877
  isArguments = function(value) {
1783
1878
  return value && typeof value == 'object' && typeof value.length == 'number' &&
1784
- hasOwnProperty.call(value, 'callee') || false;
1879
+ hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
1785
1880
  };
1786
1881
  }
1787
1882
 
@@ -1937,16 +2032,16 @@
1937
2032
  * @returns {Object} Returns the destination object.
1938
2033
  * @example
1939
2034
  *
1940
- * _.assign({ 'name': 'moe' }, { 'age': 40 });
1941
- * // => { 'name': 'moe', 'age': 40 }
2035
+ * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
2036
+ * // => { 'name': 'fred', 'employer': 'slate' }
1942
2037
  *
1943
2038
  * var defaults = _.partialRight(_.assign, function(a, b) {
1944
2039
  * return typeof a == 'undefined' ? b : a;
1945
2040
  * });
1946
2041
  *
1947
- * var food = { 'name': 'apple' };
1948
- * defaults(food, { 'name': 'banana', 'type': 'fruit' });
1949
- * // => { 'name': 'apple', 'type': 'fruit' }
2042
+ * var object = { 'name': 'barney' };
2043
+ * defaults(object, { 'name': 'fred', 'employer': 'slate' });
2044
+ * // => { 'name': 'barney', 'employer': 'slate' }
1950
2045
  */
1951
2046
  var assign = createIterator(defaultsIteratorOptions, {
1952
2047
  'top':
@@ -1962,7 +2057,7 @@
1962
2057
  });
1963
2058
 
1964
2059
  /**
1965
- * Creates a clone of `value`. If `deep` is `true` nested objects will also
2060
+ * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
1966
2061
  * be cloned, otherwise they will be assigned by reference. If a callback
1967
2062
  * is provided it will be executed to produce the cloned values. If the
1968
2063
  * callback returns `undefined` cloning will be handled by the method instead.
@@ -1972,23 +2067,23 @@
1972
2067
  * @memberOf _
1973
2068
  * @category Objects
1974
2069
  * @param {*} value The value to clone.
1975
- * @param {boolean} [deep=false] Specify a deep clone.
2070
+ * @param {boolean} [isDeep=false] Specify a deep clone.
1976
2071
  * @param {Function} [callback] The function to customize cloning values.
1977
2072
  * @param {*} [thisArg] The `this` binding of `callback`.
1978
2073
  * @returns {*} Returns the cloned value.
1979
2074
  * @example
1980
2075
  *
1981
- * var stooges = [
1982
- * { 'name': 'moe', 'age': 40 },
1983
- * { 'name': 'larry', 'age': 50 }
2076
+ * var characters = [
2077
+ * { 'name': 'barney', 'age': 36 },
2078
+ * { 'name': 'fred', 'age': 40 }
1984
2079
  * ];
1985
2080
  *
1986
- * var shallow = _.clone(stooges);
1987
- * shallow[0] === stooges[0];
2081
+ * var shallow = _.clone(characters);
2082
+ * shallow[0] === characters[0];
1988
2083
  * // => true
1989
2084
  *
1990
- * var deep = _.clone(stooges, true);
1991
- * deep[0] === stooges[0];
2085
+ * var deep = _.clone(characters, true);
2086
+ * deep[0] === characters[0];
1992
2087
  * // => false
1993
2088
  *
1994
2089
  * _.mixin({
@@ -2001,15 +2096,15 @@
2001
2096
  * clone.childNodes.length;
2002
2097
  * // => 0
2003
2098
  */
2004
- function clone(value, deep, callback, thisArg) {
2099
+ function clone(value, isDeep, callback, thisArg) {
2005
2100
  // allows working with "Collections" methods without using their `index`
2006
- // and `collection` arguments for `deep` and `callback`
2007
- if (typeof deep != 'boolean' && deep != null) {
2101
+ // and `collection` arguments for `isDeep` and `callback`
2102
+ if (typeof isDeep != 'boolean' && isDeep != null) {
2008
2103
  thisArg = callback;
2009
- callback = deep;
2010
- deep = false;
2104
+ callback = isDeep;
2105
+ isDeep = false;
2011
2106
  }
2012
- return baseClone(value, deep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
2107
+ return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
2013
2108
  }
2014
2109
 
2015
2110
  /**
@@ -2032,13 +2127,13 @@
2032
2127
  * @returns {*} Returns the deep cloned value.
2033
2128
  * @example
2034
2129
  *
2035
- * var stooges = [
2036
- * { 'name': 'moe', 'age': 40 },
2037
- * { 'name': 'larry', 'age': 50 }
2130
+ * var characters = [
2131
+ * { 'name': 'barney', 'age': 36 },
2132
+ * { 'name': 'fred', 'age': 40 }
2038
2133
  * ];
2039
2134
  *
2040
- * var deep = _.cloneDeep(stooges);
2041
- * deep[0] === stooges[0];
2135
+ * var deep = _.cloneDeep(characters);
2136
+ * deep[0] === characters[0];
2042
2137
  * // => false
2043
2138
  *
2044
2139
  * var view = {
@@ -2057,6 +2152,42 @@
2057
2152
  return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
2058
2153
  }
2059
2154
 
2155
+ /**
2156
+ * Creates an object that inherits from the given `prototype` object. If a
2157
+ * `properties` object is provided its own enumerable properties are assigned
2158
+ * to the created object.
2159
+ *
2160
+ * @static
2161
+ * @memberOf _
2162
+ * @category Objects
2163
+ * @param {Object} prototype The object to inherit from.
2164
+ * @param {Object} [properties] The properties to assign to the object.
2165
+ * @returns {Object} Returns the new object.
2166
+ * @example
2167
+ *
2168
+ * function Shape() {
2169
+ * this.x = 0;
2170
+ * this.y = 0;
2171
+ * }
2172
+ *
2173
+ * function Circle() {
2174
+ * Shape.call(this);
2175
+ * }
2176
+ *
2177
+ * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
2178
+ *
2179
+ * var circle = new Circle;
2180
+ * circle instanceof Circle;
2181
+ * // => true
2182
+ *
2183
+ * circle instanceof Shape;
2184
+ * // => true
2185
+ */
2186
+ function create(prototype, properties) {
2187
+ var result = baseCreate(prototype);
2188
+ return properties ? assign(result, properties) : result;
2189
+ }
2190
+
2060
2191
  /**
2061
2192
  * Assigns own enumerable properties of source object(s) to the destination
2062
2193
  * object for all destination properties that resolve to `undefined`. Once a
@@ -2073,9 +2204,9 @@
2073
2204
  * @returns {Object} Returns the destination object.
2074
2205
  * @example
2075
2206
  *
2076
- * var food = { 'name': 'apple' };
2077
- * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
2078
- * // => { 'name': 'apple', 'type': 'fruit' }
2207
+ * var object = { 'name': 'barney' };
2208
+ * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
2209
+ * // => { 'name': 'barney', 'employer': 'slate' }
2079
2210
  */
2080
2211
  var defaults = createIterator(defaultsIteratorOptions);
2081
2212
 
@@ -2083,6 +2214,13 @@
2083
2214
  * This method is like `_.findIndex` except that it returns the key of the
2084
2215
  * first element that passes the callback check, instead of the element itself.
2085
2216
  *
2217
+ * If a property name is provided for `callback` the created "_.pluck" style
2218
+ * callback will return the property value of the given element.
2219
+ *
2220
+ * If an object is provided for `callback` the created "_.where" style callback
2221
+ * will return `true` for elements that have the properties of the given object,
2222
+ * else `false`.
2223
+ *
2086
2224
  * @static
2087
2225
  * @memberOf _
2088
2226
  * @category Objects
@@ -2094,10 +2232,24 @@
2094
2232
  * @returns {string|undefined} Returns the key of the found element, else `undefined`.
2095
2233
  * @example
2096
2234
  *
2097
- * _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
2098
- * return num % 2 == 0;
2235
+ * var characters = {
2236
+ * 'barney': { 'age': 36, 'blocked': false },
2237
+ * 'fred': { 'age': 40, 'blocked': true },
2238
+ * 'pebbles': { 'age': 1, 'blocked': false }
2239
+ * };
2240
+ *
2241
+ * _.findKey(characters, function(chr) {
2242
+ * return chr.age < 40;
2099
2243
  * });
2100
- * // => 'b' (property order is not guaranteed across environments)
2244
+ * // => 'barney' (property order is not guaranteed across environments)
2245
+ *
2246
+ * // using "_.where" callback shorthand
2247
+ * _.findKey(characters, { 'age': 1 });
2248
+ * // => 'pebbles'
2249
+ *
2250
+ * // using "_.pluck" callback shorthand
2251
+ * _.findKey(characters, 'blocked');
2252
+ * // => 'fred'
2101
2253
  */
2102
2254
  function findKey(object, callback, thisArg) {
2103
2255
  var result;
@@ -2115,6 +2267,13 @@
2115
2267
  * This method is like `_.findKey` except that it iterates over elements
2116
2268
  * of a `collection` in the opposite order.
2117
2269
  *
2270
+ * If a property name is provided for `callback` the created "_.pluck" style
2271
+ * callback will return the property value of the given element.
2272
+ *
2273
+ * If an object is provided for `callback` the created "_.where" style callback
2274
+ * will return `true` for elements that have the properties of the given object,
2275
+ * else `false`.
2276
+ *
2118
2277
  * @static
2119
2278
  * @memberOf _
2120
2279
  * @category Objects
@@ -2126,10 +2285,24 @@
2126
2285
  * @returns {string|undefined} Returns the key of the found element, else `undefined`.
2127
2286
  * @example
2128
2287
  *
2129
- * _.findLastKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
2130
- * return num % 2 == 1;
2288
+ * var characters = {
2289
+ * 'barney': { 'age': 36, 'blocked': true },
2290
+ * 'fred': { 'age': 40, 'blocked': false },
2291
+ * 'pebbles': { 'age': 1, 'blocked': true }
2292
+ * };
2293
+ *
2294
+ * _.findLastKey(characters, function(chr) {
2295
+ * return chr.age < 40;
2131
2296
  * });
2132
- * // => returns `c`, assuming `_.findKey` returns `a`
2297
+ * // => returns `pebbles`, assuming `_.findKey` returns `barney`
2298
+ *
2299
+ * // using "_.where" callback shorthand
2300
+ * _.findLastKey(characters, { 'age': 40 });
2301
+ * // => 'fred'
2302
+ *
2303
+ * // using "_.pluck" callback shorthand
2304
+ * _.findLastKey(characters, 'blocked');
2305
+ * // => 'pebbles'
2133
2306
  */
2134
2307
  function findLastKey(object, callback, thisArg) {
2135
2308
  var result;
@@ -2159,18 +2332,20 @@
2159
2332
  * @returns {Object} Returns `object`.
2160
2333
  * @example
2161
2334
  *
2162
- * function Dog(name) {
2163
- * this.name = name;
2335
+ * function Shape() {
2336
+ * this.x = 0;
2337
+ * this.y = 0;
2164
2338
  * }
2165
2339
  *
2166
- * Dog.prototype.bark = function() {
2167
- * console.log('Woof, woof!');
2340
+ * Shape.prototype.move = function(x, y) {
2341
+ * this.x += x;
2342
+ * this.y += y;
2168
2343
  * };
2169
2344
  *
2170
- * _.forIn(new Dog('Dagny'), function(value, key) {
2345
+ * _.forIn(new Shape, function(value, key) {
2171
2346
  * console.log(key);
2172
2347
  * });
2173
- * // => logs 'bark' and 'name' (property order is not guaranteed across environments)
2348
+ * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
2174
2349
  */
2175
2350
  var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
2176
2351
  'useHas': false
@@ -2189,18 +2364,20 @@
2189
2364
  * @returns {Object} Returns `object`.
2190
2365
  * @example
2191
2366
  *
2192
- * function Dog(name) {
2193
- * this.name = name;
2367
+ * function Shape() {
2368
+ * this.x = 0;
2369
+ * this.y = 0;
2194
2370
  * }
2195
2371
  *
2196
- * Dog.prototype.bark = function() {
2197
- * console.log('Woof, woof!');
2372
+ * Shape.prototype.move = function(x, y) {
2373
+ * this.x += x;
2374
+ * this.y += y;
2198
2375
  * };
2199
2376
  *
2200
- * _.forInRight(new Dog('Dagny'), function(value, key) {
2377
+ * _.forInRight(new Shape, function(value, key) {
2201
2378
  * console.log(key);
2202
2379
  * });
2203
- * // => logs 'name' and 'bark' assuming `_.forIn ` logs 'bark' and 'name'
2380
+ * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
2204
2381
  */
2205
2382
  function forInRight(object, callback, thisArg) {
2206
2383
  var pairs = [];
@@ -2328,8 +2505,8 @@
2328
2505
  * @returns {Object} Returns the created inverted object.
2329
2506
  * @example
2330
2507
  *
2331
- * _.invert({ 'first': 'moe', 'second': 'larry' });
2332
- * // => { 'moe': 'first', 'larry': 'second' }
2508
+ * _.invert({ 'first': 'fred', 'second': 'barney' });
2509
+ * // => { 'fred': 'first', 'barney': 'second' }
2333
2510
  */
2334
2511
  function invert(object) {
2335
2512
  var index = -1,
@@ -2358,7 +2535,8 @@
2358
2535
  * // => false
2359
2536
  */
2360
2537
  function isBoolean(value) {
2361
- return value === true || value === false || toString.call(value) == boolClass;
2538
+ return value === true || value === false ||
2539
+ value && typeof value == 'object' && toString.call(value) == boolClass || false;
2362
2540
  }
2363
2541
 
2364
2542
  /**
@@ -2375,7 +2553,7 @@
2375
2553
  * // => true
2376
2554
  */
2377
2555
  function isDate(value) {
2378
- return value ? (typeof value == 'object' && toString.call(value) == dateClass) : false;
2556
+ return value && typeof value == 'object' && toString.call(value) == dateClass || false;
2379
2557
  }
2380
2558
 
2381
2559
  /**
@@ -2392,7 +2570,7 @@
2392
2570
  * // => true
2393
2571
  */
2394
2572
  function isElement(value) {
2395
- return value ? value.nodeType === 1 : false;
2573
+ return value && value.nodeType === 1 || false;
2396
2574
  }
2397
2575
 
2398
2576
  /**
@@ -2452,13 +2630,13 @@
2452
2630
  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2453
2631
  * @example
2454
2632
  *
2455
- * var moe = { 'name': 'moe', 'age': 40 };
2456
- * var copy = { 'name': 'moe', 'age': 40 };
2633
+ * var object = { 'name': 'fred' };
2634
+ * var copy = { 'name': 'fred' };
2457
2635
  *
2458
- * moe == copy;
2636
+ * object == copy;
2459
2637
  * // => false
2460
2638
  *
2461
- * _.isEqual(moe, copy);
2639
+ * _.isEqual(object, copy);
2462
2640
  * // => true
2463
2641
  *
2464
2642
  * var words = ['hello', 'goodbye'];
@@ -2627,7 +2805,8 @@
2627
2805
  * // => true
2628
2806
  */
2629
2807
  function isNumber(value) {
2630
- return typeof value == 'number' || toString.call(value) == numberClass;
2808
+ return typeof value == 'number' ||
2809
+ value && typeof value == 'object' && toString.call(value) == numberClass || false;
2631
2810
  }
2632
2811
 
2633
2812
  /**
@@ -2640,18 +2819,18 @@
2640
2819
  * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
2641
2820
  * @example
2642
2821
  *
2643
- * function Stooge(name, age) {
2644
- * this.name = name;
2645
- * this.age = age;
2822
+ * function Shape() {
2823
+ * this.x = 0;
2824
+ * this.y = 0;
2646
2825
  * }
2647
2826
  *
2648
- * _.isPlainObject(new Stooge('moe', 40));
2827
+ * _.isPlainObject(new Shape);
2649
2828
  * // => false
2650
2829
  *
2651
2830
  * _.isPlainObject([1, 2, 3]);
2652
2831
  * // => false
2653
2832
  *
2654
- * _.isPlainObject({ 'name': 'moe', 'age': 40 });
2833
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
2655
2834
  * // => true
2656
2835
  */
2657
2836
  var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
@@ -2676,11 +2855,11 @@
2676
2855
  * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
2677
2856
  * @example
2678
2857
  *
2679
- * _.isRegExp(/moe/);
2858
+ * _.isRegExp(/fred/);
2680
2859
  * // => true
2681
2860
  */
2682
2861
  function isRegExp(value) {
2683
- return (value && objectTypes[typeof value]) ? toString.call(value) == regexpClass : false;
2862
+ return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
2684
2863
  }
2685
2864
 
2686
2865
  /**
@@ -2693,11 +2872,12 @@
2693
2872
  * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
2694
2873
  * @example
2695
2874
  *
2696
- * _.isString('moe');
2875
+ * _.isString('fred');
2697
2876
  * // => true
2698
2877
  */
2699
2878
  function isString(value) {
2700
- return typeof value == 'string' || toString.call(value) == stringClass;
2879
+ return typeof value == 'string' ||
2880
+ value && typeof value == 'object' && toString.call(value) == stringClass || false;
2701
2881
  }
2702
2882
 
2703
2883
  /**
@@ -2737,21 +2917,21 @@
2737
2917
  * @example
2738
2918
  *
2739
2919
  * var names = {
2740
- * 'stooges': [
2741
- * { 'name': 'moe' },
2742
- * { 'name': 'larry' }
2920
+ * 'characters': [
2921
+ * { 'name': 'barney' },
2922
+ * { 'name': 'fred' }
2743
2923
  * ]
2744
2924
  * };
2745
2925
  *
2746
2926
  * var ages = {
2747
- * 'stooges': [
2748
- * { 'age': 40 },
2749
- * { 'age': 50 }
2927
+ * 'characters': [
2928
+ * { 'age': 36 },
2929
+ * { 'age': 40 }
2750
2930
  * ]
2751
2931
  * };
2752
2932
  *
2753
2933
  * _.merge(names, ages);
2754
- * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
2934
+ * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
2755
2935
  *
2756
2936
  * var food = {
2757
2937
  * 'fruits': ['apple'],
@@ -2775,6 +2955,7 @@
2775
2955
  if (!isObject(object)) {
2776
2956
  return object;
2777
2957
  }
2958
+
2778
2959
  // allows working with `_.reduce` and `_.reduceRight` without using
2779
2960
  // their `index` and `collection` arguments
2780
2961
  if (typeof args[2] != 'number') {
@@ -2785,7 +2966,7 @@
2785
2966
  } else if (length > 2 && typeof args[length - 1] == 'function') {
2786
2967
  callback = args[--length];
2787
2968
  }
2788
- var sources = nativeSlice.call(arguments, 1, length),
2969
+ var sources = slice(arguments, 1, length),
2789
2970
  index = -1,
2790
2971
  stackA = getArray(),
2791
2972
  stackB = getArray();
@@ -2816,32 +2997,38 @@
2816
2997
  * @returns {Object} Returns an object without the omitted properties.
2817
2998
  * @example
2818
2999
  *
2819
- * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
2820
- * // => { 'name': 'moe' }
3000
+ * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
3001
+ * // => { 'name': 'fred' }
2821
3002
  *
2822
- * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
3003
+ * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
2823
3004
  * return typeof value == 'number';
2824
3005
  * });
2825
- * // => { 'name': 'moe' }
3006
+ * // => { 'name': 'fred' }
2826
3007
  */
2827
3008
  function omit(object, callback, thisArg) {
2828
- var indexOf = getIndexOf(),
2829
- isFunc = typeof callback == 'function',
2830
- result = {};
3009
+ var result = {};
3010
+ if (typeof callback != 'function') {
3011
+ var props = [];
3012
+ forIn(object, function(value, key) {
3013
+ props.push(key);
3014
+ });
3015
+ props = baseDifference(props, baseFlatten(arguments, true, false, 1));
2831
3016
 
2832
- if (isFunc) {
2833
- callback = lodash.createCallback(callback, thisArg, 3);
3017
+ var index = -1,
3018
+ length = props.length;
3019
+
3020
+ while (++index < length) {
3021
+ var key = props[index];
3022
+ result[key] = object[key];
3023
+ }
2834
3024
  } else {
2835
- var props = baseFlatten(arguments, true, false, 1);
3025
+ callback = lodash.createCallback(callback, thisArg, 3);
3026
+ forIn(object, function(value, key, object) {
3027
+ if (!callback(value, key, object)) {
3028
+ result[key] = value;
3029
+ }
3030
+ });
2836
3031
  }
2837
- forIn(object, function(value, key, object) {
2838
- if (isFunc
2839
- ? !callback(value, key, object)
2840
- : indexOf(props, key) < 0
2841
- ) {
2842
- result[key] = value;
2843
- }
2844
- });
2845
3032
  return result;
2846
3033
  }
2847
3034
 
@@ -2856,8 +3043,8 @@
2856
3043
  * @returns {Array} Returns new array of key-value pairs.
2857
3044
  * @example
2858
3045
  *
2859
- * _.pairs({ 'moe': 30, 'larry': 40 });
2860
- * // => [['moe', 30], ['larry', 40]] (property order is not guaranteed across environments)
3046
+ * _.pairs({ 'barney': 36, 'fred': 40 });
3047
+ * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
2861
3048
  */
2862
3049
  function pairs(object) {
2863
3050
  var index = -1,
@@ -2891,13 +3078,13 @@
2891
3078
  * @returns {Object} Returns an object composed of the picked properties.
2892
3079
  * @example
2893
3080
  *
2894
- * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
2895
- * // => { 'name': 'moe' }
3081
+ * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
3082
+ * // => { 'name': 'fred' }
2896
3083
  *
2897
- * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
3084
+ * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
2898
3085
  * return key.charAt(0) != '_';
2899
3086
  * });
2900
- * // => { 'name': 'moe' }
3087
+ * // => { 'name': 'fred' }
2901
3088
  */
2902
3089
  function pick(object, callback, thisArg) {
2903
3090
  var result = {};
@@ -2934,7 +3121,7 @@
2934
3121
  * @static
2935
3122
  * @memberOf _
2936
3123
  * @category Objects
2937
- * @param {Array|Object} collection The collection to iterate over.
3124
+ * @param {Array|Object} object The object to iterate over.
2938
3125
  * @param {Function} [callback=identity] The function called per iteration.
2939
3126
  * @param {*} [accumulator] The custom accumulator value.
2940
3127
  * @param {*} [thisArg] The `this` binding of `callback`.
@@ -2956,8 +3143,6 @@
2956
3143
  */
2957
3144
  function transform(object, callback, accumulator, thisArg) {
2958
3145
  var isArr = isArray(object);
2959
- callback = baseCreateCallback(callback, thisArg, 4);
2960
-
2961
3146
  if (accumulator == null) {
2962
3147
  if (isArr) {
2963
3148
  accumulator = [];
@@ -2965,12 +3150,15 @@
2965
3150
  var ctor = object && object.constructor,
2966
3151
  proto = ctor && ctor.prototype;
2967
3152
 
2968
- accumulator = createObject(proto);
3153
+ accumulator = baseCreate(proto);
2969
3154
  }
2970
3155
  }
2971
- (isArr ? baseEach : forOwn)(object, function(value, index, object) {
2972
- return callback(accumulator, value, index, object);
2973
- });
3156
+ if (callback) {
3157
+ callback = lodash.createCallback(callback, thisArg, 4);
3158
+ (isArr ? baseEach : forOwn)(object, function(value, index, object) {
3159
+ return callback(accumulator, value, index, object);
3160
+ });
3161
+ }
2974
3162
  return accumulator;
2975
3163
  }
2976
3164
 
@@ -3019,8 +3207,8 @@
3019
3207
  * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
3020
3208
  * // => ['a', 'c', 'e']
3021
3209
  *
3022
- * _.at(['moe', 'larry', 'curly'], 0, 2);
3023
- * // => ['moe', 'curly']
3210
+ * _.at(['fred', 'barney', 'pebbles'], 0, 2);
3211
+ * // => ['fred', 'pebbles']
3024
3212
  */
3025
3213
  function at(collection) {
3026
3214
  var args = arguments,
@@ -3059,10 +3247,10 @@
3059
3247
  * _.contains([1, 2, 3], 1, 2);
3060
3248
  * // => false
3061
3249
  *
3062
- * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
3250
+ * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
3063
3251
  * // => true
3064
3252
  *
3065
- * _.contains('curly', 'ur');
3253
+ * _.contains('pebbles', 'eb');
3066
3254
  * // => true
3067
3255
  */
3068
3256
  function contains(collection, target, fromIndex) {
@@ -3149,20 +3337,20 @@
3149
3337
  * else `false`.
3150
3338
  * @example
3151
3339
  *
3152
- * _.every([true, 1, null, 'yes'], Boolean);
3340
+ * _.every([true, 1, null, 'yes']);
3153
3341
  * // => false
3154
3342
  *
3155
- * var stooges = [
3156
- * { 'name': 'moe', 'age': 40 },
3157
- * { 'name': 'larry', 'age': 50 }
3343
+ * var characters = [
3344
+ * { 'name': 'barney', 'age': 36 },
3345
+ * { 'name': 'fred', 'age': 40 }
3158
3346
  * ];
3159
3347
  *
3160
3348
  * // using "_.pluck" callback shorthand
3161
- * _.every(stooges, 'age');
3349
+ * _.every(characters, 'age');
3162
3350
  * // => true
3163
3351
  *
3164
3352
  * // using "_.where" callback shorthand
3165
- * _.every(stooges, { 'age': 50 });
3353
+ * _.every(characters, { 'age': 36 });
3166
3354
  * // => false
3167
3355
  */
3168
3356
  function every(collection, callback, thisArg) {
@@ -3213,18 +3401,18 @@
3213
3401
  * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
3214
3402
  * // => [2, 4, 6]
3215
3403
  *
3216
- * var food = [
3217
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
3218
- * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
3404
+ * var characters = [
3405
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
3406
+ * { 'name': 'fred', 'age': 40, 'blocked': true }
3219
3407
  * ];
3220
3408
  *
3221
3409
  * // using "_.pluck" callback shorthand
3222
- * _.filter(food, 'organic');
3223
- * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
3410
+ * _.filter(characters, 'blocked');
3411
+ * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
3224
3412
  *
3225
3413
  * // using "_.where" callback shorthand
3226
- * _.filter(food, { 'type': 'fruit' });
3227
- * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
3414
+ * _.filter(characters, { 'age': 36 });
3415
+ * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
3228
3416
  */
3229
3417
  function filter(collection, callback, thisArg) {
3230
3418
  var result = [];
@@ -3274,24 +3462,24 @@
3274
3462
  * @returns {*} Returns the found element, else `undefined`.
3275
3463
  * @example
3276
3464
  *
3277
- * _.find([1, 2, 3, 4], function(num) {
3278
- * return num % 2 == 0;
3279
- * });
3280
- * // => 2
3281
- *
3282
- * var food = [
3283
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
3284
- * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
3285
- * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
3465
+ * var characters = [
3466
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
3467
+ * { 'name': 'fred', 'age': 40, 'blocked': true },
3468
+ * { 'name': 'pebbles', 'age': 1, 'blocked': false }
3286
3469
  * ];
3287
3470
  *
3471
+ * _.find(characters, function(chr) {
3472
+ * return chr.age < 40;
3473
+ * });
3474
+ * // => { 'name': 'barney', 'age': 36, 'blocked': false }
3475
+ *
3288
3476
  * // using "_.where" callback shorthand
3289
- * _.find(food, { 'type': 'vegetable' });
3290
- * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
3477
+ * _.find(characters, { 'age': 1 });
3478
+ * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
3291
3479
  *
3292
3480
  * // using "_.pluck" callback shorthand
3293
- * _.find(food, 'organic');
3294
- * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
3481
+ * _.find(characters, 'blocked');
3482
+ * // => { 'name': 'fred', 'age': 40, 'blocked': true }
3295
3483
  */
3296
3484
  function find(collection, callback, thisArg) {
3297
3485
  callback = lodash.createCallback(callback, thisArg, 3);
@@ -3356,6 +3544,10 @@
3356
3544
  * (value, index|key, collection). Callbacks may exit iteration early by
3357
3545
  * explicitly returning `false`.
3358
3546
  *
3547
+ * Note: As with other "Collections" methods, objects with a `length` property
3548
+ * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
3549
+ * may be used for object iteration.
3550
+ *
3359
3551
  * @static
3360
3552
  * @memberOf _
3361
3553
  * @alias each
@@ -3506,7 +3698,7 @@
3506
3698
  * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
3507
3699
  * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
3508
3700
  *
3509
- * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String);
3701
+ * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
3510
3702
  * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
3511
3703
  */
3512
3704
  var indexBy = createAggregator(function(result, value, key) {
@@ -3536,7 +3728,7 @@
3536
3728
  * // => [['1', '2', '3'], ['4', '5', '6']]
3537
3729
  */
3538
3730
  function invoke(collection, methodName) {
3539
- var args = nativeSlice.call(arguments, 2),
3731
+ var args = slice(arguments, 2),
3540
3732
  index = -1,
3541
3733
  isFunc = typeof methodName == 'function',
3542
3734
  length = collection ? collection.length : 0,
@@ -3578,14 +3770,14 @@
3578
3770
  * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
3579
3771
  * // => [3, 6, 9] (property order is not guaranteed across environments)
3580
3772
  *
3581
- * var stooges = [
3582
- * { 'name': 'moe', 'age': 40 },
3583
- * { 'name': 'larry', 'age': 50 }
3773
+ * var characters = [
3774
+ * { 'name': 'barney', 'age': 36 },
3775
+ * { 'name': 'fred', 'age': 40 }
3584
3776
  * ];
3585
3777
  *
3586
3778
  * // using "_.pluck" callback shorthand
3587
- * _.map(stooges, 'name');
3588
- * // => ['moe', 'larry']
3779
+ * _.map(characters, 'name');
3780
+ * // => ['barney', 'fred']
3589
3781
  */
3590
3782
  function map(collection, callback, thisArg) {
3591
3783
  var index = -1,
@@ -3633,23 +3825,28 @@
3633
3825
  * _.max([4, 2, 8, 6]);
3634
3826
  * // => 8
3635
3827
  *
3636
- * var stooges = [
3637
- * { 'name': 'moe', 'age': 40 },
3638
- * { 'name': 'larry', 'age': 50 }
3828
+ * var characters = [
3829
+ * { 'name': 'barney', 'age': 36 },
3830
+ * { 'name': 'fred', 'age': 40 }
3639
3831
  * ];
3640
3832
  *
3641
- * _.max(stooges, function(stooge) { return stooge.age; });
3642
- * // => { 'name': 'larry', 'age': 50 };
3833
+ * _.max(characters, function(chr) { return chr.age; });
3834
+ * // => { 'name': 'fred', 'age': 40 };
3643
3835
  *
3644
3836
  * // using "_.pluck" callback shorthand
3645
- * _.max(stooges, 'age');
3646
- * // => { 'name': 'larry', 'age': 50 };
3837
+ * _.max(characters, 'age');
3838
+ * // => { 'name': 'fred', 'age': 40 };
3647
3839
  */
3648
3840
  function max(collection, callback, thisArg) {
3649
3841
  var computed = -Infinity,
3650
3842
  result = computed;
3651
3843
 
3652
- if (!callback && isArray(collection)) {
3844
+ // allows working with functions like `_.map` without using
3845
+ // their `index` argument as a callback
3846
+ if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
3847
+ callback = null;
3848
+ }
3849
+ if (callback == null && isArray(collection)) {
3653
3850
  var index = -1,
3654
3851
  length = collection.length;
3655
3852
 
@@ -3660,7 +3857,7 @@
3660
3857
  }
3661
3858
  }
3662
3859
  } else {
3663
- callback = (!callback && isString(collection))
3860
+ callback = (callback == null && isString(collection))
3664
3861
  ? charAtCallback
3665
3862
  : lodash.createCallback(callback, thisArg, 3);
3666
3863
 
@@ -3703,23 +3900,28 @@
3703
3900
  * _.min([4, 2, 8, 6]);
3704
3901
  * // => 2
3705
3902
  *
3706
- * var stooges = [
3707
- * { 'name': 'moe', 'age': 40 },
3708
- * { 'name': 'larry', 'age': 50 }
3903
+ * var characters = [
3904
+ * { 'name': 'barney', 'age': 36 },
3905
+ * { 'name': 'fred', 'age': 40 }
3709
3906
  * ];
3710
3907
  *
3711
- * _.min(stooges, function(stooge) { return stooge.age; });
3712
- * // => { 'name': 'moe', 'age': 40 };
3908
+ * _.min(characters, function(chr) { return chr.age; });
3909
+ * // => { 'name': 'barney', 'age': 36 };
3713
3910
  *
3714
3911
  * // using "_.pluck" callback shorthand
3715
- * _.min(stooges, 'age');
3716
- * // => { 'name': 'moe', 'age': 40 };
3912
+ * _.min(characters, 'age');
3913
+ * // => { 'name': 'barney', 'age': 36 };
3717
3914
  */
3718
3915
  function min(collection, callback, thisArg) {
3719
3916
  var computed = Infinity,
3720
3917
  result = computed;
3721
3918
 
3722
- if (!callback && isArray(collection)) {
3919
+ // allows working with functions like `_.map` without using
3920
+ // their `index` argument as a callback
3921
+ if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
3922
+ callback = null;
3923
+ }
3924
+ if (callback == null && isArray(collection)) {
3723
3925
  var index = -1,
3724
3926
  length = collection.length;
3725
3927
 
@@ -3730,7 +3932,7 @@
3730
3932
  }
3731
3933
  }
3732
3934
  } else {
3733
- callback = (!callback && isString(collection))
3935
+ callback = (callback == null && isString(collection))
3734
3936
  ? charAtCallback
3735
3937
  : lodash.createCallback(callback, thisArg, 3);
3736
3938
 
@@ -3746,7 +3948,7 @@
3746
3948
  }
3747
3949
 
3748
3950
  /**
3749
- * Retrieves the value of a specified property from all elements in the `collection`.
3951
+ * Retrieves the value of a specified property from all elements in the collection.
3750
3952
  *
3751
3953
  * @static
3752
3954
  * @memberOf _
@@ -3757,13 +3959,13 @@
3757
3959
  * @returns {Array} Returns a new array of property values.
3758
3960
  * @example
3759
3961
  *
3760
- * var stooges = [
3761
- * { 'name': 'moe', 'age': 40 },
3762
- * { 'name': 'larry', 'age': 50 }
3962
+ * var characters = [
3963
+ * { 'name': 'barney', 'age': 36 },
3964
+ * { 'name': 'fred', 'age': 40 }
3763
3965
  * ];
3764
3966
  *
3765
- * _.pluck(stooges, 'name');
3766
- * // => ['moe', 'larry']
3967
+ * _.pluck(characters, 'name');
3968
+ * // => ['barney', 'fred']
3767
3969
  */
3768
3970
  var pluck = map;
3769
3971
 
@@ -3799,7 +4001,7 @@
3799
4001
  */
3800
4002
  function reduce(collection, callback, accumulator, thisArg) {
3801
4003
  var noaccum = arguments.length < 3;
3802
- callback = baseCreateCallback(callback, thisArg, 4);
4004
+ callback = lodash.createCallback(callback, thisArg, 4);
3803
4005
 
3804
4006
  if (isArray(collection)) {
3805
4007
  var index = -1,
@@ -3842,7 +4044,7 @@
3842
4044
  */
3843
4045
  function reduceRight(collection, callback, accumulator, thisArg) {
3844
4046
  var noaccum = arguments.length < 3;
3845
- callback = baseCreateCallback(callback, thisArg, 4);
4047
+ callback = lodash.createCallback(callback, thisArg, 4);
3846
4048
  forEachRight(collection, function(value, index, collection) {
3847
4049
  accumulator = noaccum
3848
4050
  ? (noaccum = false, value)
@@ -3876,18 +4078,18 @@
3876
4078
  * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
3877
4079
  * // => [1, 3, 5]
3878
4080
  *
3879
- * var food = [
3880
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
3881
- * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
4081
+ * var characters = [
4082
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
4083
+ * { 'name': 'fred', 'age': 40, 'blocked': true }
3882
4084
  * ];
3883
4085
  *
3884
4086
  * // using "_.pluck" callback shorthand
3885
- * _.reject(food, 'organic');
3886
- * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
4087
+ * _.reject(characters, 'blocked');
4088
+ * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
3887
4089
  *
3888
4090
  * // using "_.where" callback shorthand
3889
- * _.reject(food, { 'type': 'fruit' });
3890
- * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
4091
+ * _.reject(characters, { 'age': 36 });
4092
+ * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
3891
4093
  */
3892
4094
  function reject(collection, callback, thisArg) {
3893
4095
  callback = lodash.createCallback(callback, thisArg, 3);
@@ -3904,8 +4106,8 @@
3904
4106
  * @category Collections
3905
4107
  * @param {Array|Object|string} collection The collection to sample.
3906
4108
  * @param {number} [n] The number of elements to sample.
3907
- * @param- {Object} [guard] Allows working with functions, like `_.map`,
3908
- * without using their `key` and `object` arguments as sources.
4109
+ * @param- {Object} [guard] Allows working with functions like `_.map`
4110
+ * without using their `index` arguments as `n`.
3909
4111
  * @returns {Array} Returns the random sample(s) of `collection`.
3910
4112
  * @example
3911
4113
  *
@@ -3916,14 +4118,13 @@
3916
4118
  * // => [3, 1]
3917
4119
  */
3918
4120
  function sample(collection, n, guard) {
3919
- var length = collection ? collection.length : 0;
3920
- if (typeof length != 'number') {
4121
+ if (collection && typeof collection.length != 'number') {
3921
4122
  collection = values(collection);
3922
4123
  } else if (support.unindexedChars && isString(collection)) {
3923
4124
  collection = collection.split('');
3924
4125
  }
3925
4126
  if (n == null || guard) {
3926
- return collection ? collection[random(length - 1)] : undefined;
4127
+ return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
3927
4128
  }
3928
4129
  var result = shuffle(collection);
3929
4130
  result.length = nativeMin(nativeMax(0, n), result.length);
@@ -3950,7 +4151,7 @@
3950
4151
  result = Array(typeof length == 'number' ? length : 0);
3951
4152
 
3952
4153
  forEach(collection, function(value) {
3953
- var rand = random(++index);
4154
+ var rand = baseRandom(0, ++index);
3954
4155
  result[index] = result[rand];
3955
4156
  result[rand] = value;
3956
4157
  });
@@ -3974,7 +4175,7 @@
3974
4175
  * _.size({ 'one': 1, 'two': 2, 'three': 3 });
3975
4176
  * // => 3
3976
4177
  *
3977
- * _.size('curly');
4178
+ * _.size('pebbles');
3978
4179
  * // => 5
3979
4180
  */
3980
4181
  function size(collection) {
@@ -4011,17 +4212,17 @@
4011
4212
  * _.some([null, 0, 'yes', false], Boolean);
4012
4213
  * // => true
4013
4214
  *
4014
- * var food = [
4015
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
4016
- * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
4215
+ * var characters = [
4216
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
4217
+ * { 'name': 'fred', 'age': 40, 'blocked': true }
4017
4218
  * ];
4018
4219
  *
4019
4220
  * // using "_.pluck" callback shorthand
4020
- * _.some(food, 'organic');
4221
+ * _.some(characters, 'blocked');
4021
4222
  * // => true
4022
4223
  *
4023
4224
  * // using "_.where" callback shorthand
4024
- * _.some(food, { 'type': 'meat' });
4225
+ * _.some(characters, { 'age': 1 });
4025
4226
  * // => false
4026
4227
  */
4027
4228
  function some(collection, callback, thisArg) {
@@ -4139,16 +4340,16 @@
4139
4340
  * @returns {Array} Returns a new array of elements that have the given properties.
4140
4341
  * @example
4141
4342
  *
4142
- * var stooges = [
4143
- * { 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
4144
- * { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }
4343
+ * var characters = [
4344
+ * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
4345
+ * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
4145
4346
  * ];
4146
4347
  *
4147
- * _.where(stooges, { 'age': 40 });
4148
- * // => [{ 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }]
4348
+ * _.where(characters, { 'age': 36 });
4349
+ * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
4149
4350
  *
4150
- * _.where(stooges, { 'quotes': ['Poifect!'] });
4151
- * // => [{ 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }]
4351
+ * _.where(characters, { 'pets': ['dino'] });
4352
+ * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
4152
4353
  */
4153
4354
  var where = filter;
4154
4355
 
@@ -4190,7 +4391,7 @@
4190
4391
  * @memberOf _
4191
4392
  * @category Arrays
4192
4393
  * @param {Array} array The array to process.
4193
- * @param {...Array} [array] The arrays of values to exclude.
4394
+ * @param {...Array} [values] The arrays of values to exclude.
4194
4395
  * @returns {Array} Returns a new array of filtered values.
4195
4396
  * @example
4196
4397
  *
@@ -4198,39 +4399,20 @@
4198
4399
  * // => [1, 3, 4]
4199
4400
  */
4200
4401
  function difference(array) {
4201
- var index = -1,
4202
- indexOf = getIndexOf(),
4203
- length = array ? array.length : 0,
4204
- seen = baseFlatten(arguments, true, true, 1),
4205
- result = [];
4206
-
4207
- var isLarge = length >= largeArraySize && indexOf === baseIndexOf;
4208
-
4209
- if (isLarge) {
4210
- var cache = createCache(seen);
4211
- if (cache) {
4212
- indexOf = cacheIndexOf;
4213
- seen = cache;
4214
- } else {
4215
- isLarge = false;
4216
- }
4217
- }
4218
- while (++index < length) {
4219
- var value = array[index];
4220
- if (indexOf(seen, value) < 0) {
4221
- result.push(value);
4222
- }
4223
- }
4224
- if (isLarge) {
4225
- releaseObject(seen);
4226
- }
4227
- return result;
4402
+ return baseDifference(array, baseFlatten(arguments, true, true, 1));
4228
4403
  }
4229
4404
 
4230
4405
  /**
4231
4406
  * This method is like `_.find` except that it returns the index of the first
4232
4407
  * element that passes the callback check, instead of the element itself.
4233
4408
  *
4409
+ * If a property name is provided for `callback` the created "_.pluck" style
4410
+ * callback will return the property value of the given element.
4411
+ *
4412
+ * If an object is provided for `callback` the created "_.where" style callback
4413
+ * will return `true` for elements that have the properties of the given object,
4414
+ * else `false`.
4415
+ *
4234
4416
  * @static
4235
4417
  * @memberOf _
4236
4418
  * @category Arrays
@@ -4242,9 +4424,23 @@
4242
4424
  * @returns {number} Returns the index of the found element, else `-1`.
4243
4425
  * @example
4244
4426
  *
4245
- * _.findIndex(['apple', 'banana', 'beet'], function(food) {
4246
- * return /^b/.test(food);
4427
+ * var characters = [
4428
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
4429
+ * { 'name': 'fred', 'age': 40, 'blocked': true },
4430
+ * { 'name': 'pebbles', 'age': 1, 'blocked': false }
4431
+ * ];
4432
+ *
4433
+ * _.findIndex(characters, function(chr) {
4434
+ * return chr.age < 20;
4247
4435
  * });
4436
+ * // => 2
4437
+ *
4438
+ * // using "_.where" callback shorthand
4439
+ * _.findIndex(characters, { 'age': 36 });
4440
+ * // => 0
4441
+ *
4442
+ * // using "_.pluck" callback shorthand
4443
+ * _.findIndex(characters, 'blocked');
4248
4444
  * // => 1
4249
4445
  */
4250
4446
  function findIndex(array, callback, thisArg) {
@@ -4264,6 +4460,13 @@
4264
4460
  * This method is like `_.findIndex` except that it iterates over elements
4265
4461
  * of a `collection` from right to left.
4266
4462
  *
4463
+ * If a property name is provided for `callback` the created "_.pluck" style
4464
+ * callback will return the property value of the given element.
4465
+ *
4466
+ * If an object is provided for `callback` the created "_.where" style callback
4467
+ * will return `true` for elements that have the properties of the given object,
4468
+ * else `false`.
4469
+ *
4267
4470
  * @static
4268
4471
  * @memberOf _
4269
4472
  * @category Arrays
@@ -4275,9 +4478,23 @@
4275
4478
  * @returns {number} Returns the index of the found element, else `-1`.
4276
4479
  * @example
4277
4480
  *
4278
- * _.findLastIndex(['apple', 'banana', 'beet'], function(food) {
4279
- * return /^b/.test(food);
4481
+ * var characters = [
4482
+ * { 'name': 'barney', 'age': 36, 'blocked': true },
4483
+ * { 'name': 'fred', 'age': 40, 'blocked': false },
4484
+ * { 'name': 'pebbles', 'age': 1, 'blocked': true }
4485
+ * ];
4486
+ *
4487
+ * _.findLastIndex(characters, function(chr) {
4488
+ * return chr.age > 30;
4280
4489
  * });
4490
+ * // => 1
4491
+ *
4492
+ * // using "_.where" callback shorthand
4493
+ * _.findLastIndex(characters, { 'age': 36 });
4494
+ * // => 0
4495
+ *
4496
+ * // using "_.pluck" callback shorthand
4497
+ * _.findLastIndex(characters, 'blocked');
4281
4498
  * // => 2
4282
4499
  */
4283
4500
  function findLastIndex(array, callback, thisArg) {
@@ -4328,24 +4545,19 @@
4328
4545
  * });
4329
4546
  * // => [1, 2]
4330
4547
  *
4331
- * var food = [
4332
- * { 'name': 'banana', 'organic': true },
4333
- * { 'name': 'beet', 'organic': false },
4548
+ * var characters = [
4549
+ * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
4550
+ * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
4551
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4334
4552
  * ];
4335
4553
  *
4336
4554
  * // using "_.pluck" callback shorthand
4337
- * _.first(food, 'organic');
4338
- * // => [{ 'name': 'banana', 'organic': true }]
4339
- *
4340
- * var food = [
4341
- * { 'name': 'apple', 'type': 'fruit' },
4342
- * { 'name': 'banana', 'type': 'fruit' },
4343
- * { 'name': 'beet', 'type': 'vegetable' }
4344
- * ];
4555
+ * _.first(characters, 'blocked');
4556
+ * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
4345
4557
  *
4346
4558
  * // using "_.where" callback shorthand
4347
- * _.first(food, { 'type': 'fruit' });
4348
- * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
4559
+ * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
4560
+ * // => ['barney', 'fred']
4349
4561
  */
4350
4562
  function first(array, callback, thisArg) {
4351
4563
  var n = 0,
@@ -4398,20 +4610,20 @@
4398
4610
  * _.flatten([1, [2], [3, [[4]]]], true);
4399
4611
  * // => [1, 2, 3, [[4]]];
4400
4612
  *
4401
- * var stooges = [
4402
- * { 'name': 'curly', 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
4403
- * { 'name': 'moe', 'quotes': ['Spread out!', 'You knucklehead!'] }
4613
+ * var characters = [
4614
+ * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
4615
+ * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
4404
4616
  * ];
4405
4617
  *
4406
4618
  * // using "_.pluck" callback shorthand
4407
- * _.flatten(stooges, 'quotes');
4408
- * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
4619
+ * _.flatten(characters, 'pets');
4620
+ * // => ['hoppy', 'baby puss', 'dino']
4409
4621
  */
4410
4622
  function flatten(array, isShallow, callback, thisArg) {
4411
4623
  // juggle arguments
4412
4624
  if (typeof isShallow != 'boolean' && isShallow != null) {
4413
4625
  thisArg = callback;
4414
- callback = !(thisArg && thisArg[isShallow] === array) ? isShallow : null;
4626
+ callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
4415
4627
  isShallow = false;
4416
4628
  }
4417
4629
  if (callback != null) {
@@ -4491,24 +4703,19 @@
4491
4703
  * });
4492
4704
  * // => [1]
4493
4705
  *
4494
- * var food = [
4495
- * { 'name': 'beet', 'organic': false },
4496
- * { 'name': 'carrot', 'organic': true }
4706
+ * var characters = [
4707
+ * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
4708
+ * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
4709
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4497
4710
  * ];
4498
4711
  *
4499
4712
  * // using "_.pluck" callback shorthand
4500
- * _.initial(food, 'organic');
4501
- * // => [{ 'name': 'beet', 'organic': false }]
4502
- *
4503
- * var food = [
4504
- * { 'name': 'banana', 'type': 'fruit' },
4505
- * { 'name': 'beet', 'type': 'vegetable' },
4506
- * { 'name': 'carrot', 'type': 'vegetable' }
4507
- * ];
4713
+ * _.initial(characters, 'blocked');
4714
+ * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
4508
4715
  *
4509
4716
  * // using "_.where" callback shorthand
4510
- * _.initial(food, { 'type': 'vegetable' });
4511
- * // => [{ 'name': 'banana', 'type': 'fruit' }]
4717
+ * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
4718
+ * // => ['barney', 'fred']
4512
4719
  */
4513
4720
  function initial(array, callback, thisArg) {
4514
4721
  var n = 0,
@@ -4621,24 +4828,19 @@
4621
4828
  * });
4622
4829
  * // => [2, 3]
4623
4830
  *
4624
- * var food = [
4625
- * { 'name': 'beet', 'organic': false },
4626
- * { 'name': 'carrot', 'organic': true }
4831
+ * var characters = [
4832
+ * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
4833
+ * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
4834
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4627
4835
  * ];
4628
4836
  *
4629
4837
  * // using "_.pluck" callback shorthand
4630
- * _.last(food, 'organic');
4631
- * // => [{ 'name': 'carrot', 'organic': true }]
4632
- *
4633
- * var food = [
4634
- * { 'name': 'banana', 'type': 'fruit' },
4635
- * { 'name': 'beet', 'type': 'vegetable' },
4636
- * { 'name': 'carrot', 'type': 'vegetable' }
4637
- * ];
4838
+ * _.pluck(_.last(characters, 'blocked'), 'name');
4839
+ * // => ['fred', 'pebbles']
4638
4840
  *
4639
4841
  * // using "_.where" callback shorthand
4640
- * _.last(food, { 'type': 'vegetable' });
4641
- * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
4842
+ * _.last(characters, { 'employer': 'na' });
4843
+ * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
4642
4844
  */
4643
4845
  function last(array, callback, thisArg) {
4644
4846
  var n = 0,
@@ -4664,6 +4866,13 @@
4664
4866
  * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
4665
4867
  * as the offset from the end of the collection.
4666
4868
  *
4869
+ * If a property name is provided for `callback` the created "_.pluck" style
4870
+ * callback will return the property value of the given element.
4871
+ *
4872
+ * If an object is provided for `callback` the created "_.where" style callback
4873
+ * will return `true` for elements that have the properties of the given object,
4874
+ * else `false`.
4875
+ *
4667
4876
  * @static
4668
4877
  * @memberOf _
4669
4878
  * @category Arrays
@@ -4742,17 +4951,17 @@
4742
4951
  * @returns {Array} Returns a new range array.
4743
4952
  * @example
4744
4953
  *
4745
- * _.range(10);
4746
- * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4954
+ * _.range(4);
4955
+ * // => [0, 1, 2, 3]
4747
4956
  *
4748
- * _.range(1, 11);
4749
- * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
4957
+ * _.range(1, 5);
4958
+ * // => [1, 2, 3, 4]
4750
4959
  *
4751
- * _.range(0, 30, 5);
4752
- * // => [0, 5, 10, 15, 20, 25]
4960
+ * _.range(0, 20, 5);
4961
+ * // => [0, 5, 10, 15]
4753
4962
  *
4754
- * _.range(0, -10, -1);
4755
- * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
4963
+ * _.range(0, -4, -1);
4964
+ * // => [0, -1, -2, -3]
4756
4965
  *
4757
4966
  * _.range(1, 4, 0);
4758
4967
  * // => [1, 1, 1]
@@ -4768,7 +4977,7 @@
4768
4977
  end = start;
4769
4978
  start = 0;
4770
4979
  }
4771
- // use `Array(length)` so engines, like Chakra and V8, avoid slower modes
4980
+ // use `Array(length)` so engines like Chakra and V8 avoid slower modes
4772
4981
  // http://youtu.be/XAqIpGU8ZZk#t=17m25s
4773
4982
  var index = -1,
4774
4983
  length = nativeMax(0, ceil((end - start) / (step || 1))),
@@ -4868,24 +5077,19 @@
4868
5077
  * });
4869
5078
  * // => [3]
4870
5079
  *
4871
- * var food = [
4872
- * { 'name': 'banana', 'organic': true },
4873
- * { 'name': 'beet', 'organic': false },
5080
+ * var characters = [
5081
+ * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
5082
+ * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
5083
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4874
5084
  * ];
4875
5085
  *
4876
5086
  * // using "_.pluck" callback shorthand
4877
- * _.rest(food, 'organic');
4878
- * // => [{ 'name': 'beet', 'organic': false }]
4879
- *
4880
- * var food = [
4881
- * { 'name': 'apple', 'type': 'fruit' },
4882
- * { 'name': 'banana', 'type': 'fruit' },
4883
- * { 'name': 'beet', 'type': 'vegetable' }
4884
- * ];
5087
+ * _.pluck(_.rest(characters, 'blocked'), 'name');
5088
+ * // => ['fred', 'pebbles']
4885
5089
  *
4886
5090
  * // using "_.where" callback shorthand
4887
- * _.rest(food, { 'type': 'fruit' });
4888
- * // => [{ 'name': 'beet', 'type': 'vegetable' }]
5091
+ * _.rest(characters, { 'employer': 'slate' });
5092
+ * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
4889
5093
  */
4890
5094
  function rest(array, callback, thisArg) {
4891
5095
  if (typeof callback != 'number' && callback != null) {
@@ -5034,7 +5238,7 @@
5034
5238
  // juggle arguments
5035
5239
  if (typeof isSorted != 'boolean' && isSorted != null) {
5036
5240
  thisArg = callback;
5037
- callback = !(thisArg && thisArg[isSorted] === array) ? isSorted : null;
5241
+ callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
5038
5242
  isSorted = false;
5039
5243
  }
5040
5244
  if (callback != null) {
@@ -5059,7 +5263,7 @@
5059
5263
  * // => [2, 3, 4]
5060
5264
  */
5061
5265
  function without(array) {
5062
- return difference(array, nativeSlice.call(arguments, 1));
5266
+ return baseDifference(array, slice(arguments, 1));
5063
5267
  }
5064
5268
 
5065
5269
  /**
@@ -5075,8 +5279,8 @@
5075
5279
  * @returns {Array} Returns a new array of grouped elements.
5076
5280
  * @example
5077
5281
  *
5078
- * _.zip(['moe', 'larry'], [30, 40], [true, false]);
5079
- * // => [['moe', 30, true], ['larry', 40, false]]
5282
+ * _.zip(['fred', 'barney'], [30, 40], [true, false]);
5283
+ * // => [['fred', 30, true], ['barney', 40, false]]
5080
5284
  */
5081
5285
  function zip() {
5082
5286
  var array = arguments.length > 1 ? arguments : arguments[0],
@@ -5105,8 +5309,8 @@
5105
5309
  * corresponding values.
5106
5310
  * @example
5107
5311
  *
5108
- * _.zipObject(['moe', 'larry'], [30, 40]);
5109
- * // => { 'moe': 30, 'larry': 40 }
5312
+ * _.zipObject(['fred', 'barney'], [30, 40]);
5313
+ * // => { 'fred': 30, 'barney': 40 }
5110
5314
  */
5111
5315
  function zipObject(keys, values) {
5112
5316
  var index = -1,
@@ -5179,14 +5383,14 @@
5179
5383
  * return greeting + ' ' + this.name;
5180
5384
  * };
5181
5385
  *
5182
- * func = _.bind(func, { 'name': 'moe' }, 'hi');
5386
+ * func = _.bind(func, { 'name': 'fred' }, 'hi');
5183
5387
  * func();
5184
- * // => 'hi moe'
5388
+ * // => 'hi fred'
5185
5389
  */
5186
5390
  function bind(func, thisArg) {
5187
5391
  return arguments.length > 2
5188
- ? createBound(func, 17, nativeSlice.call(arguments, 2), null, thisArg)
5189
- : createBound(func, 1, null, null, thisArg);
5392
+ ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
5393
+ : createWrapper(func, 1, null, null, thisArg);
5190
5394
  }
5191
5395
 
5192
5396
  /**
@@ -5220,7 +5424,7 @@
5220
5424
 
5221
5425
  while (++index < length) {
5222
5426
  var key = funcs[index];
5223
- object[key] = createBound(object[key], 1, null, null, object);
5427
+ object[key] = createWrapper(object[key], 1, null, null, object);
5224
5428
  }
5225
5429
  return object;
5226
5430
  }
@@ -5242,7 +5446,7 @@
5242
5446
  * @example
5243
5447
  *
5244
5448
  * var object = {
5245
- * 'name': 'moe',
5449
+ * 'name': 'fred',
5246
5450
  * 'greet': function(greeting) {
5247
5451
  * return greeting + ' ' + this.name;
5248
5452
  * }
@@ -5250,19 +5454,19 @@
5250
5454
  *
5251
5455
  * var func = _.bindKey(object, 'greet', 'hi');
5252
5456
  * func();
5253
- * // => 'hi moe'
5457
+ * // => 'hi fred'
5254
5458
  *
5255
5459
  * object.greet = function(greeting) {
5256
- * return greeting + ', ' + this.name + '!';
5460
+ * return greeting + 'ya ' + this.name + '!';
5257
5461
  * };
5258
5462
  *
5259
5463
  * func();
5260
- * // => 'hi, moe!'
5464
+ * // => 'hiya fred!'
5261
5465
  */
5262
5466
  function bindKey(object, key) {
5263
5467
  return arguments.length > 2
5264
- ? createBound(key, 19, nativeSlice.call(arguments, 2), null, object)
5265
- : createBound(key, 3, null, null, object);
5468
+ ? createWrapper(key, 19, slice(arguments, 2), null, object)
5469
+ : createWrapper(key, 3, null, null, object);
5266
5470
  }
5267
5471
 
5268
5472
  /**
@@ -5279,7 +5483,7 @@
5279
5483
  * @example
5280
5484
  *
5281
5485
  * var realNameMap = {
5282
- * 'curly': 'jerome'
5486
+ * 'pebbles': 'penelope'
5283
5487
  * };
5284
5488
  *
5285
5489
  * var format = function(name) {
@@ -5292,8 +5496,8 @@
5292
5496
  * };
5293
5497
  *
5294
5498
  * var welcome = _.compose(greet, format);
5295
- * welcome('curly');
5296
- * // => 'Hiya Jerome!'
5499
+ * welcome('pebbles');
5500
+ * // => 'Hiya Penelope!'
5297
5501
  */
5298
5502
  function compose() {
5299
5503
  var funcs = arguments,
@@ -5330,9 +5534,9 @@
5330
5534
  * @returns {Function} Returns a callback function.
5331
5535
  * @example
5332
5536
  *
5333
- * var stooges = [
5334
- * { 'name': 'moe', 'age': 40 },
5335
- * { 'name': 'larry', 'age': 50 }
5537
+ * var characters = [
5538
+ * { 'name': 'barney', 'age': 36 },
5539
+ * { 'name': 'fred', 'age': 40 }
5336
5540
  * ];
5337
5541
  *
5338
5542
  * // wrap to create custom callback shorthands
@@ -5343,8 +5547,8 @@
5343
5547
  * };
5344
5548
  * });
5345
5549
  *
5346
- * _.filter(stooges, 'age__gt45');
5347
- * // => [{ 'name': 'larry', 'age': 50 }]
5550
+ * _.filter(characters, 'age__gt38');
5551
+ * // => [{ 'name': 'fred', 'age': 40 }]
5348
5552
  */
5349
5553
  function createCallback(func, thisArg, argCount) {
5350
5554
  var type = typeof func;
@@ -5413,7 +5617,7 @@
5413
5617
  */
5414
5618
  function curry(func, arity) {
5415
5619
  arity = typeof arity == 'number' ? arity : (+arity || func.length);
5416
- return createBound(func, 4, null, null, null, arity);
5620
+ return createWrapper(func, 4, null, null, null, arity);
5417
5621
  }
5418
5622
 
5419
5623
  /**
@@ -5490,6 +5694,9 @@
5490
5694
  if (isCalled) {
5491
5695
  lastCalled = now();
5492
5696
  result = func.apply(thisArg, args);
5697
+ if (!timeoutId && !maxTimeoutId) {
5698
+ args = thisArg = null;
5699
+ }
5493
5700
  }
5494
5701
  } else {
5495
5702
  timeoutId = setTimeout(delayed, remaining);
@@ -5504,6 +5711,9 @@
5504
5711
  if (trailing || (maxWait !== wait)) {
5505
5712
  lastCalled = now();
5506
5713
  result = func.apply(thisArg, args);
5714
+ if (!timeoutId && !maxTimeoutId) {
5715
+ args = thisArg = null;
5716
+ }
5507
5717
  }
5508
5718
  };
5509
5719
 
@@ -5519,8 +5729,10 @@
5519
5729
  if (!maxTimeoutId && !leading) {
5520
5730
  lastCalled = stamp;
5521
5731
  }
5522
- var remaining = maxWait - (stamp - lastCalled);
5523
- if (remaining <= 0) {
5732
+ var remaining = maxWait - (stamp - lastCalled),
5733
+ isCalled = remaining <= 0;
5734
+
5735
+ if (isCalled) {
5524
5736
  if (maxTimeoutId) {
5525
5737
  maxTimeoutId = clearTimeout(maxTimeoutId);
5526
5738
  }
@@ -5531,12 +5743,19 @@
5531
5743
  maxTimeoutId = setTimeout(maxDelayed, remaining);
5532
5744
  }
5533
5745
  }
5534
- if (!timeoutId && wait !== maxWait) {
5746
+ if (isCalled && timeoutId) {
5747
+ timeoutId = clearTimeout(timeoutId);
5748
+ }
5749
+ else if (!timeoutId && wait !== maxWait) {
5535
5750
  timeoutId = setTimeout(delayed, wait);
5536
5751
  }
5537
5752
  if (leadingCall) {
5753
+ isCalled = true;
5538
5754
  result = func.apply(thisArg, args);
5539
5755
  }
5756
+ if (isCalled && !timeoutId && !maxTimeoutId) {
5757
+ args = thisArg = null;
5758
+ }
5540
5759
  return result;
5541
5760
  };
5542
5761
  }
@@ -5560,11 +5779,11 @@
5560
5779
  if (!isFunction(func)) {
5561
5780
  throw new TypeError;
5562
5781
  }
5563
- var args = nativeSlice.call(arguments, 1);
5782
+ var args = slice(arguments, 1);
5564
5783
  return setTimeout(function() { func.apply(undefined, args); }, 1);
5565
5784
  }
5566
5785
  // use `setImmediate` if available in Node.js
5567
- if (isV8 && moduleExports && typeof setImmediate == 'function') {
5786
+ if (setImmediate) {
5568
5787
  defer = function(func) {
5569
5788
  if (!isFunction(func)) {
5570
5789
  throw new TypeError;
@@ -5594,7 +5813,7 @@
5594
5813
  if (!isFunction(func)) {
5595
5814
  throw new TypeError;
5596
5815
  }
5597
- var args = nativeSlice.call(arguments, 2);
5816
+ var args = slice(arguments, 2);
5598
5817
  return setTimeout(function() { func.apply(undefined, args); }, wait);
5599
5818
  }
5600
5819
 
@@ -5618,19 +5837,22 @@
5618
5837
  * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
5619
5838
  * });
5620
5839
  *
5840
+ * fibonacci(9)
5841
+ * // => 34
5842
+ *
5621
5843
  * var data = {
5622
- * 'moe': { 'name': 'moe', 'age': 40 },
5623
- * 'curly': { 'name': 'curly', 'age': 60 }
5844
+ * 'fred': { 'name': 'fred', 'age': 40 },
5845
+ * 'pebbles': { 'name': 'pebbles', 'age': 1 }
5624
5846
  * };
5625
5847
  *
5626
5848
  * // modifying the result cache
5627
- * var stooge = _.memoize(function(name) { return data[name]; }, _.identity);
5628
- * stooge('curly');
5629
- * // => { 'name': 'curly', 'age': 60 }
5849
+ * var get = _.memoize(function(name) { return data[name]; }, _.identity);
5850
+ * get('pebbles');
5851
+ * // => { 'name': 'pebbles', 'age': 1 }
5630
5852
  *
5631
- * stooge.cache.curly.name = 'jerome';
5632
- * stooge('curly');
5633
- * // => { 'name': 'jerome', 'age': 60 }
5853
+ * get.cache.pebbles.name = 'penelope';
5854
+ * get('pebbles');
5855
+ * // => { 'name': 'penelope', 'age': 1 }
5634
5856
  */
5635
5857
  function memoize(func, resolver) {
5636
5858
  if (!isFunction(func)) {
@@ -5700,11 +5922,11 @@
5700
5922
  *
5701
5923
  * var greet = function(greeting, name) { return greeting + ' ' + name; };
5702
5924
  * var hi = _.partial(greet, 'hi');
5703
- * hi('moe');
5704
- * // => 'hi moe'
5925
+ * hi('fred');
5926
+ * // => 'hi fred'
5705
5927
  */
5706
5928
  function partial(func) {
5707
- return createBound(func, 16, nativeSlice.call(arguments, 1));
5929
+ return createWrapper(func, 16, slice(arguments, 1));
5708
5930
  }
5709
5931
 
5710
5932
  /**
@@ -5735,7 +5957,7 @@
5735
5957
  * // => { '_': _, 'jq': $ }
5736
5958
  */
5737
5959
  function partialRight(func) {
5738
- return createBound(func, 32, null, nativeSlice.call(arguments, 1));
5960
+ return createWrapper(func, 32, null, slice(arguments, 1));
5739
5961
  }
5740
5962
 
5741
5963
  /**
@@ -5786,8 +6008,7 @@
5786
6008
  debounceOptions.maxWait = wait;
5787
6009
  debounceOptions.trailing = trailing;
5788
6010
 
5789
- var result = debounce(func, wait, debounceOptions);
5790
- return result;
6011
+ return debounce(func, wait, debounceOptions);
5791
6012
  }
5792
6013
 
5793
6014
  /**
@@ -5804,22 +6025,15 @@
5804
6025
  * @returns {Function} Returns the new function.
5805
6026
  * @example
5806
6027
  *
5807
- * var hello = function(name) { return 'hello ' + name; };
5808
- * hello = _.wrap(hello, function(func) {
5809
- * return 'before, ' + func('moe') + ', after';
6028
+ * var p = _.wrap(_.escape, function(func, text) {
6029
+ * return '<p>' + func(text) + '</p>';
5810
6030
  * });
5811
- * hello();
5812
- * // => 'before, hello moe, after'
6031
+ *
6032
+ * p('Fred, Wilma, & Pebbles');
6033
+ * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
5813
6034
  */
5814
6035
  function wrap(value, wrapper) {
5815
- if (!isFunction(wrapper)) {
5816
- throw new TypeError;
5817
- }
5818
- return function() {
5819
- var args = [value];
5820
- push.apply(args, arguments);
5821
- return wrapper.apply(this, args);
5822
- };
6036
+ return createWrapper(wrapper, 16, [value]);
5823
6037
  }
5824
6038
 
5825
6039
  /*--------------------------------------------------------------------------*/
@@ -5835,8 +6049,8 @@
5835
6049
  * @returns {string} Returns the escaped string.
5836
6050
  * @example
5837
6051
  *
5838
- * _.escape('Moe, Larry & Curly');
5839
- * // => 'Moe, Larry &amp; Curly'
6052
+ * _.escape('Fred, Wilma, & Pebbles');
6053
+ * // => 'Fred, Wilma, &amp; Pebbles'
5840
6054
  */
5841
6055
  function escape(string) {
5842
6056
  return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
@@ -5852,8 +6066,8 @@
5852
6066
  * @returns {*} Returns `value`.
5853
6067
  * @example
5854
6068
  *
5855
- * var moe = { 'name': 'moe' };
5856
- * moe === _.identity(moe);
6069
+ * var object = { 'name': 'fred' };
6070
+ * _.identity(object) === object;
5857
6071
  * // => true
5858
6072
  */
5859
6073
  function identity(value) {
@@ -5877,11 +6091,11 @@
5877
6091
  * }
5878
6092
  * });
5879
6093
  *
5880
- * _.capitalize('moe');
5881
- * // => 'Moe'
6094
+ * _.capitalize('fred');
6095
+ * // => 'Fred'
5882
6096
  *
5883
- * _('moe').capitalize();
5884
- * // => 'Moe'
6097
+ * _('fred').capitalize();
6098
+ * // => 'Fred'
5885
6099
  */
5886
6100
  function mixin(object, source) {
5887
6101
  var ctor = object,
@@ -5929,6 +6143,22 @@
5929
6143
  return this;
5930
6144
  }
5931
6145
 
6146
+ /**
6147
+ * A no-operation function.
6148
+ *
6149
+ * @static
6150
+ * @memberOf _
6151
+ * @category Utilities
6152
+ * @example
6153
+ *
6154
+ * var object = { 'name': 'fred' };
6155
+ * _.noop(object) === undefined;
6156
+ * // => true
6157
+ */
6158
+ function noop() {
6159
+ // no operation performed
6160
+ }
6161
+
5932
6162
  /**
5933
6163
  * Converts the given value into an integer of the specified radix.
5934
6164
  * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
@@ -5949,7 +6179,7 @@
5949
6179
  * // => 8
5950
6180
  */
5951
6181
  var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
5952
- // Firefox and Opera still follow the ES3 specified implementation of `parseInt`
6182
+ // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
5953
6183
  return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
5954
6184
  };
5955
6185
 
@@ -6004,10 +6234,11 @@
6004
6234
  } else {
6005
6235
  max = +max || 0;
6006
6236
  }
6007
- var rand = nativeRandom();
6008
- return (floating || min % 1 || max % 1)
6009
- ? nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max)
6010
- : min + floor(rand * (max - min + 1));
6237
+ if (floating || min % 1 || max % 1) {
6238
+ var rand = nativeRandom();
6239
+ return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
6240
+ }
6241
+ return baseRandom(min, max);
6011
6242
  }
6012
6243
 
6013
6244
  /**
@@ -6052,7 +6283,7 @@
6052
6283
  * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
6053
6284
  *
6054
6285
  * For more information on precompiling templates see:
6055
- * http://lodash.com/#custom-builds
6286
+ * http://lodash.com/custom-builds
6056
6287
  *
6057
6288
  * For more information on Chrome extension sandboxes see:
6058
6289
  * http://developer.chrome.com/stable/extensions/sandboxingEval.html
@@ -6075,8 +6306,8 @@
6075
6306
  *
6076
6307
  * // using the "interpolate" delimiter to create a compiled template
6077
6308
  * var compiled = _.template('hello <%= name %>');
6078
- * compiled({ 'name': 'moe' });
6079
- * // => 'hello moe'
6309
+ * compiled({ 'name': 'fred' });
6310
+ * // => 'hello fred'
6080
6311
  *
6081
6312
  * // using the "escape" delimiter to escape HTML in data property values
6082
6313
  * _.template('<b><%- value %></b>', { 'value': '<script>' });
@@ -6084,16 +6315,16 @@
6084
6315
  *
6085
6316
  * // using the "evaluate" delimiter to generate HTML
6086
6317
  * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
6087
- * _.template(list, { 'people': ['moe', 'larry'] });
6088
- * // => '<li>moe</li><li>larry</li>'
6318
+ * _.template(list, { 'people': ['fred', 'barney'] });
6319
+ * // => '<li>fred</li><li>barney</li>'
6089
6320
  *
6090
6321
  * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
6091
- * _.template('hello ${ name }', { 'name': 'curly' });
6092
- * // => 'hello curly'
6322
+ * _.template('hello ${ name }', { 'name': 'pebbles' });
6323
+ * // => 'hello pebbles'
6093
6324
  *
6094
6325
  * // using the internal `print` function in "evaluate" delimiters
6095
- * _.template('<% print("hello " + name); %>!', { 'name': 'larry' });
6096
- * // => 'hello larry!'
6326
+ * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
6327
+ * // => 'hello barney!'
6097
6328
  *
6098
6329
  * // using a custom template delimiters
6099
6330
  * _.templateSettings = {
@@ -6105,8 +6336,8 @@
6105
6336
  *
6106
6337
  * // using the `imports` option to import jQuery
6107
6338
  * var list = '<% $.each(people, function(name) { %><li><%- name %></li><% }); %>';
6108
- * _.template(list, { 'people': ['moe', 'larry'] }, { 'imports': { '$': jQuery } });
6109
- * // => '<li>moe</li><li>larry</li>'
6339
+ * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { '$': jQuery } });
6340
+ * // => '<li>fred</li><li>barney</li>'
6110
6341
  *
6111
6342
  * // using the `sourceURL` option to specify a custom sourceURL for the template
6112
6343
  * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
@@ -6136,7 +6367,7 @@
6136
6367
  // and Laura Doktorova's doT.js
6137
6368
  // https://github.com/olado/doT
6138
6369
  var settings = lodash.templateSettings;
6139
- text || (text = '');
6370
+ text = String(text || '');
6140
6371
 
6141
6372
  // avoid missing dependencies when `iteratorTemplate` is not defined
6142
6373
  options = defaults({}, options, settings);
@@ -6277,8 +6508,8 @@
6277
6508
  * @returns {string} Returns the unescaped string.
6278
6509
  * @example
6279
6510
  *
6280
- * _.unescape('Moe, Larry &amp; Curly');
6281
- * // => 'Moe, Larry & Curly'
6511
+ * _.unescape('Fred, Barney &amp; Pebbles');
6512
+ * // => 'Fred, Barney & Pebbles'
6282
6513
  */
6283
6514
  function unescape(string) {
6284
6515
  return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
@@ -6318,18 +6549,18 @@
6318
6549
  * @returns {Object} Returns the wrapper object.
6319
6550
  * @example
6320
6551
  *
6321
- * var stooges = [
6322
- * { 'name': 'moe', 'age': 40 },
6323
- * { 'name': 'larry', 'age': 50 },
6324
- * { 'name': 'curly', 'age': 60 }
6552
+ * var characters = [
6553
+ * { 'name': 'barney', 'age': 36 },
6554
+ * { 'name': 'fred', 'age': 40 },
6555
+ * { 'name': 'pebbles', 'age': 1 }
6325
6556
  * ];
6326
6557
  *
6327
- * var youngest = _.chain(stooges)
6558
+ * var youngest = _.chain(characters)
6328
6559
  * .sortBy('age')
6329
- * .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
6560
+ * .map(function(chr) { return chr.name + ' is ' + chr.age; })
6330
6561
  * .first()
6331
6562
  * .value();
6332
- * // => 'moe is 40'
6563
+ * // => 'pebbles is 1'
6333
6564
  */
6334
6565
  function chain(value) {
6335
6566
  value = new lodashWrapper(value);
@@ -6352,12 +6583,10 @@
6352
6583
  * @example
6353
6584
  *
6354
6585
  * _([1, 2, 3, 4])
6355
- * .filter(function(num) { return num % 2 == 0; })
6356
- * .tap(function(array) { console.log(array); })
6357
- * .map(function(num) { return num * num; })
6586
+ * .tap(function(array) { array.pop(); })
6587
+ * .reverse()
6358
6588
  * .value();
6359
- * // => // [2, 4] (logged)
6360
- * // => [4, 16]
6589
+ * // => [3, 2, 1]
6361
6590
  */
6362
6591
  function tap(value, interceptor) {
6363
6592
  interceptor(value);
@@ -6373,21 +6602,21 @@
6373
6602
  * @returns {*} Returns the wrapper object.
6374
6603
  * @example
6375
6604
  *
6376
- * var stooges = [
6377
- * { 'name': 'moe', 'age': 40 },
6378
- * { 'name': 'larry', 'age': 50 }
6605
+ * var characters = [
6606
+ * { 'name': 'barney', 'age': 36 },
6607
+ * { 'name': 'fred', 'age': 40 }
6379
6608
  * ];
6380
6609
  *
6381
6610
  * // without explicit chaining
6382
- * _(stooges).first();
6383
- * // => { 'name': 'moe', 'age': 40 }
6611
+ * _(characters).first();
6612
+ * // => { 'name': 'barney', 'age': 36 }
6384
6613
  *
6385
6614
  * // with explicit chaining
6386
- * _(stooges).chain()
6615
+ * _(characters).chain()
6387
6616
  * .first()
6388
6617
  * .pick('age')
6389
6618
  * .value()
6390
- * // => { 'age': 40 }
6619
+ * // => { 'age': 36 }
6391
6620
  */
6392
6621
  function wrapperChain() {
6393
6622
  this.__chain__ = true;
@@ -6440,6 +6669,7 @@
6440
6669
  lodash.compact = compact;
6441
6670
  lodash.compose = compose;
6442
6671
  lodash.countBy = countBy;
6672
+ lodash.create = create;
6443
6673
  lodash.createCallback = createCallback;
6444
6674
  lodash.curry = curry;
6445
6675
  lodash.debounce = debounce;
@@ -6549,6 +6779,7 @@
6549
6779
  lodash.lastIndexOf = lastIndexOf;
6550
6780
  lodash.mixin = mixin;
6551
6781
  lodash.noConflict = noConflict;
6782
+ lodash.noop = noop;
6552
6783
  lodash.parseInt = parseInt;
6553
6784
  lodash.random = random;
6554
6785
  lodash.reduce = reduce;
@@ -6621,7 +6852,7 @@
6621
6852
  * @memberOf _
6622
6853
  * @type string
6623
6854
  */
6624
- lodash.VERSION = '2.2.1';
6855
+ lodash.VERSION = '2.3.0';
6625
6856
 
6626
6857
  // add "Chaining" functions to the wrapper
6627
6858
  lodash.prototype.chain = wrapperChain;
@@ -6689,7 +6920,7 @@
6689
6920
  // expose Lo-Dash
6690
6921
  var _ = runInContext();
6691
6922
 
6692
- // some AMD build optimizers, like r.js, check for condition patterns like the following:
6923
+ // some AMD build optimizers like r.js check for condition patterns like the following:
6693
6924
  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
6694
6925
  // Expose Lo-Dash to the global object even when an AMD loader is present in
6695
6926
  // case Lo-Dash was injected by a third-party script and not intended to be