lodash-rails 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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