lodash-rails 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9089f7760c413d0fbdcce61c9c402fc9fecb166
4
- data.tar.gz: 9a4cb9209a13b45d3448839f166382aba4515064
3
+ metadata.gz: 6c3d07e40e33fc43cb27c4c2b221bee184530e91
4
+ data.tar.gz: 4f03dba97d9e3e66da1167f76b1c10eb2551f389
5
5
  SHA512:
6
- metadata.gz: 6a48be1a691143fcee7c3eb280adedf4225d5fee96969ee6377798fde1407ea9bb2e676bd29464f732784b8e1934e7624a817fef33ee66dc51b7c07293d9b426
7
- data.tar.gz: 44a4d5b5b92f68715d9d488ae77bcb39591005572facf4e93564d3086e0095bb9a4bc41eb36472a73e76334b5c842a5256631db10cc039647eab856507343497
6
+ metadata.gz: 2e3e834d09b482a5276114505827391902cd0ec7f257789f78f26f33f0e4a77f1b88b9032ab4244da30c611262e5799a1af27f2801bc014e0cf05a49e440ab0b
7
+ data.tar.gz: 4856de9a072fecc4d3b5c4cbf6a59b80e3f242f87e09098ab68c3beb6e0a297297faa85e90ff08ea9cf50ebdccee3a6e81e67a1b26d32765e4779fb7a88d7ecf
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 1.2.1:
21
+ Lo-Dash 1.3.1:
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 = "1.2.1"
3
+ VERSION = "1.3.1"
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Lo-Dash 1.2.1 (Custom Build) <http://lodash.com/>
3
+ * Lo-Dash 1.3.1 (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.4.4 <http://underscorejs.org/>
@@ -12,17 +12,9 @@
12
12
  /** Used as a safe reference for `undefined` in pre ES5 environments */
13
13
  var undefined;
14
14
 
15
- /** Detect free variable `exports` */
16
- var freeExports = typeof exports == 'object' && exports;
17
-
18
- /** Detect free variable `module` */
19
- var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
20
-
21
- /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
22
- var freeGlobal = typeof global == 'object' && global;
23
- if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
24
- window = freeGlobal;
25
- }
15
+ /** Used to pool arrays and objects used internally */
16
+ var arrayPool = [],
17
+ objectPool = [];
26
18
 
27
19
  /** Used to generate unique IDs */
28
20
  var idCounter = 0;
@@ -34,7 +26,10 @@
34
26
  var keyPrefix = +new Date + '';
35
27
 
36
28
  /** Used as the size when optimizations are enabled for large arrays */
37
- var largeArraySize = 200;
29
+ var largeArraySize = 75;
30
+
31
+ /** Used as the max size of the `arrayPool` and `objectPool` */
32
+ var maxPoolSize = 40;
38
33
 
39
34
  /** Used to match empty string literals in compiled template source */
40
35
  var reEmptyStringLeading = /\b__p \+= '';/g,
@@ -56,6 +51,9 @@
56
51
  /** Used to match "interpolate" template delimiters */
57
52
  var reInterpolate = /<%=([\s\S]+?)%>/g;
58
53
 
54
+ /** Used to detect functions containing a `this` reference */
55
+ var reThis = (reThis = /\bthis\b/) && reThis.test(runInContext) && reThis;
56
+
59
57
  /** Used to detect and test whitespace */
60
58
  var whitespace = (
61
59
  // whitespace
@@ -82,9 +80,9 @@
82
80
 
83
81
  /** Used to assign default `context` object properties */
84
82
  var contextProps = [
85
- 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object', 'RegExp',
86
- 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', 'parseInt',
87
- 'setImmediate', 'setTimeout'
83
+ 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
84
+ 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
85
+ 'parseInt', 'setImmediate', 'setTimeout'
88
86
  ];
89
87
 
90
88
  /** Used to fix the JScript [[DontEnum]] bug */
@@ -101,6 +99,7 @@
101
99
  arrayClass = '[object Array]',
102
100
  boolClass = '[object Boolean]',
103
101
  dateClass = '[object Date]',
102
+ errorClass = '[object Error]',
104
103
  funcClass = '[object Function]',
105
104
  numberClass = '[object Number]',
106
105
  objectClass = '[object Object]',
@@ -136,6 +135,304 @@
136
135
  '\u2029': 'u2029'
137
136
  };
138
137
 
138
+ /** Detect free variable `exports` */
139
+ var freeExports = objectTypes[typeof exports] && exports;
140
+
141
+ /** Detect free variable `module` */
142
+ var freeModule = objectTypes[typeof module] && module && module.exports == freeExports && module;
143
+
144
+ /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
145
+ var freeGlobal = objectTypes[typeof global] && global;
146
+ if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
147
+ window = freeGlobal;
148
+ }
149
+
150
+ /*--------------------------------------------------------------------------*/
151
+
152
+ /**
153
+ * A basic implementation of `_.indexOf` without support for binary searches
154
+ * or `fromIndex` constraints.
155
+ *
156
+ * @private
157
+ * @param {Array} array The array to search.
158
+ * @param {Mixed} value The value to search for.
159
+ * @param {Number} [fromIndex=0] The index to search from.
160
+ * @returns {Number} Returns the index of the matched value or `-1`.
161
+ */
162
+ function basicIndexOf(array, value, fromIndex) {
163
+ var index = (fromIndex || 0) - 1,
164
+ length = array.length;
165
+
166
+ while (++index < length) {
167
+ if (array[index] === value) {
168
+ return index;
169
+ }
170
+ }
171
+ return -1;
172
+ }
173
+
174
+ /**
175
+ * An implementation of `_.contains` for cache objects that mimics the return
176
+ * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
177
+ *
178
+ * @private
179
+ * @param {Object} cache The cache object to inspect.
180
+ * @param {Mixed} value The value to search for.
181
+ * @returns {Number} Returns `0` if `value` is found, else `-1`.
182
+ */
183
+ function cacheIndexOf(cache, value) {
184
+ var type = typeof value;
185
+ cache = cache.cache;
186
+
187
+ if (type == 'boolean' || value == null) {
188
+ return cache[value];
189
+ }
190
+ if (type != 'number' && type != 'string') {
191
+ type = 'object';
192
+ }
193
+ var key = type == 'number' ? value : keyPrefix + value;
194
+ cache = cache[type] || (cache[type] = {});
195
+
196
+ return type == 'object'
197
+ ? (cache[key] && basicIndexOf(cache[key], value) > -1 ? 0 : -1)
198
+ : (cache[key] ? 0 : -1);
199
+ }
200
+
201
+ /**
202
+ * Adds a given `value` to the corresponding cache object.
203
+ *
204
+ * @private
205
+ * @param {Mixed} value The value to add to the cache.
206
+ */
207
+ function cachePush(value) {
208
+ var cache = this.cache,
209
+ type = typeof value;
210
+
211
+ if (type == 'boolean' || value == null) {
212
+ cache[value] = true;
213
+ } else {
214
+ if (type != 'number' && type != 'string') {
215
+ type = 'object';
216
+ }
217
+ var key = type == 'number' ? value : keyPrefix + value,
218
+ typeCache = cache[type] || (cache[type] = {});
219
+
220
+ if (type == 'object') {
221
+ if ((typeCache[key] || (typeCache[key] = [])).push(value) == this.array.length) {
222
+ cache[type] = false;
223
+ }
224
+ } else {
225
+ typeCache[key] = true;
226
+ }
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Used by `_.max` and `_.min` as the default `callback` when a given
232
+ * `collection` is a string value.
233
+ *
234
+ * @private
235
+ * @param {String} value The character to inspect.
236
+ * @returns {Number} Returns the code unit of given character.
237
+ */
238
+ function charAtCallback(value) {
239
+ return value.charCodeAt(0);
240
+ }
241
+
242
+ /**
243
+ * Used by `sortBy` to compare transformed `collection` values, stable sorting
244
+ * them in ascending order.
245
+ *
246
+ * @private
247
+ * @param {Object} a The object to compare to `b`.
248
+ * @param {Object} b The object to compare to `a`.
249
+ * @returns {Number} Returns the sort order indicator of `1` or `-1`.
250
+ */
251
+ function compareAscending(a, b) {
252
+ var ai = a.index,
253
+ bi = b.index;
254
+
255
+ a = a.criteria;
256
+ b = b.criteria;
257
+
258
+ // ensure a stable sort in V8 and other engines
259
+ // http://code.google.com/p/v8/issues/detail?id=90
260
+ if (a !== b) {
261
+ if (a > b || typeof a == 'undefined') {
262
+ return 1;
263
+ }
264
+ if (a < b || typeof b == 'undefined') {
265
+ return -1;
266
+ }
267
+ }
268
+ return ai < bi ? -1 : 1;
269
+ }
270
+
271
+ /**
272
+ * Creates a cache object to optimize linear searches of large arrays.
273
+ *
274
+ * @private
275
+ * @param {Array} [array=[]] The array to search.
276
+ * @returns {Null|Object} Returns the cache object or `null` if caching should not be used.
277
+ */
278
+ function createCache(array) {
279
+ var index = -1,
280
+ length = array.length;
281
+
282
+ var cache = getObject();
283
+ cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
284
+
285
+ var result = getObject();
286
+ result.array = array;
287
+ result.cache = cache;
288
+ result.push = cachePush;
289
+
290
+ while (++index < length) {
291
+ result.push(array[index]);
292
+ }
293
+ return cache.object === false
294
+ ? (releaseObject(result), null)
295
+ : result;
296
+ }
297
+
298
+ /**
299
+ * Used by `template` to escape characters for inclusion in compiled
300
+ * string literals.
301
+ *
302
+ * @private
303
+ * @param {String} match The matched character to escape.
304
+ * @returns {String} Returns the escaped character.
305
+ */
306
+ function escapeStringChar(match) {
307
+ return '\\' + stringEscapes[match];
308
+ }
309
+
310
+ /**
311
+ * Gets an array from the array pool or creates a new one if the pool is empty.
312
+ *
313
+ * @private
314
+ * @returns {Array} The array from the pool.
315
+ */
316
+ function getArray() {
317
+ return arrayPool.pop() || [];
318
+ }
319
+
320
+ /**
321
+ * Gets an object from the object pool or creates a new one if the pool is empty.
322
+ *
323
+ * @private
324
+ * @returns {Object} The object from the pool.
325
+ */
326
+ function getObject() {
327
+ return objectPool.pop() || {
328
+ 'args': '',
329
+ 'array': null,
330
+ 'bottom': '',
331
+ 'cache': null,
332
+ 'criteria': null,
333
+ 'false': false,
334
+ 'firstArg': '',
335
+ 'index': 0,
336
+ 'init': '',
337
+ 'leading': false,
338
+ 'loop': '',
339
+ 'maxWait': 0,
340
+ 'null': false,
341
+ 'number': null,
342
+ 'object': null,
343
+ 'push': null,
344
+ 'shadowedProps': null,
345
+ 'string': null,
346
+ 'top': '',
347
+ 'trailing': false,
348
+ 'true': false,
349
+ 'undefined': false,
350
+ 'useHas': false,
351
+ 'useKeys': false,
352
+ 'value': null
353
+ };
354
+ }
355
+
356
+ /**
357
+ * Checks if `value` is a DOM node in IE < 9.
358
+ *
359
+ * @private
360
+ * @param {Mixed} value The value to check.
361
+ * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
362
+ */
363
+ function isNode(value) {
364
+ // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
365
+ // methods that are `typeof` "string" and still can coerce nodes to strings
366
+ return typeof value.toString != 'function' && typeof (value + '') == 'string';
367
+ }
368
+
369
+ /**
370
+ * A no-operation function.
371
+ *
372
+ * @private
373
+ */
374
+ function noop() {
375
+ // no operation performed
376
+ }
377
+
378
+ /**
379
+ * Releases the given `array` back to the array pool.
380
+ *
381
+ * @private
382
+ * @param {Array} [array] The array to release.
383
+ */
384
+ function releaseArray(array) {
385
+ array.length = 0;
386
+ if (arrayPool.length < maxPoolSize) {
387
+ arrayPool.push(array);
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Releases the given `object` back to the object pool.
393
+ *
394
+ * @private
395
+ * @param {Object} [object] The object to release.
396
+ */
397
+ function releaseObject(object) {
398
+ var cache = object.cache;
399
+ if (cache) {
400
+ releaseObject(cache);
401
+ }
402
+ object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
403
+ if (objectPool.length < maxPoolSize) {
404
+ objectPool.push(object);
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Slices the `collection` from the `start` index up to, but not including,
410
+ * the `end` index.
411
+ *
412
+ * Note: This function is used, instead of `Array#slice`, to support node lists
413
+ * in IE < 9 and to ensure dense arrays are returned.
414
+ *
415
+ * @private
416
+ * @param {Array|Object|String} collection The collection to slice.
417
+ * @param {Number} start The start index.
418
+ * @param {Number} end The end index.
419
+ * @returns {Array} Returns the new array.
420
+ */
421
+ function slice(array, start, end) {
422
+ start || (start = 0);
423
+ if (typeof end == 'undefined') {
424
+ end = array ? array.length : 0;
425
+ }
426
+ var index = -1,
427
+ length = end - start || 0,
428
+ result = Array(length < 0 ? 0 : length);
429
+
430
+ while (++index < length) {
431
+ result[index] = array[start + index];
432
+ }
433
+ return result;
434
+ }
435
+
139
436
  /*--------------------------------------------------------------------------*/
140
437
 
141
438
  /**
@@ -158,6 +455,7 @@
158
455
  var Array = context.Array,
159
456
  Boolean = context.Boolean,
160
457
  Date = context.Date,
458
+ Error = context.Error,
161
459
  Function = context.Function,
162
460
  Math = context.Math,
163
461
  Number = context.Number,
@@ -166,16 +464,25 @@
166
464
  String = context.String,
167
465
  TypeError = context.TypeError;
168
466
 
169
- /** Used for `Array` and `Object` method references */
170
- var arrayRef = Array(),
171
- objectRef = Object();
467
+ /**
468
+ * Used for `Array` method references.
469
+ *
470
+ * Normally `Array.prototype` would suffice, however, using an array literal
471
+ * avoids issues in Narwhal.
472
+ */
473
+ var arrayRef = [];
474
+
475
+ /** Used for native method references */
476
+ var errorProto = Error.prototype,
477
+ objectProto = Object.prototype,
478
+ stringProto = String.prototype;
172
479
 
173
480
  /** Used to restore the original `_` reference in `noConflict` */
174
481
  var oldDash = context._;
175
482
 
176
483
  /** Used to detect if a method is native */
177
484
  var reNative = RegExp('^' +
178
- String(objectRef.valueOf)
485
+ String(objectProto.valueOf)
179
486
  .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
180
487
  .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
181
488
  );
@@ -185,15 +492,18 @@
185
492
  clearTimeout = context.clearTimeout,
186
493
  concat = arrayRef.concat,
187
494
  floor = Math.floor,
495
+ fnToString = Function.prototype.toString,
188
496
  getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
189
- hasOwnProperty = objectRef.hasOwnProperty,
497
+ hasOwnProperty = objectProto.hasOwnProperty,
190
498
  push = arrayRef.push,
499
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
191
500
  setImmediate = context.setImmediate,
192
501
  setTimeout = context.setTimeout,
193
- toString = objectRef.toString;
502
+ toString = objectProto.toString;
194
503
 
195
504
  /* Native method shortcuts for methods with the same name as other `lodash` methods */
196
505
  var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
506
+ nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
197
507
  nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
198
508
  nativeIsFinite = context.isFinite,
199
509
  nativeIsNaN = context.isNaN,
@@ -213,11 +523,31 @@
213
523
  ctorByClass[arrayClass] = Array;
214
524
  ctorByClass[boolClass] = Boolean;
215
525
  ctorByClass[dateClass] = Date;
526
+ ctorByClass[funcClass] = Function;
216
527
  ctorByClass[objectClass] = Object;
217
528
  ctorByClass[numberClass] = Number;
218
529
  ctorByClass[regexpClass] = RegExp;
219
530
  ctorByClass[stringClass] = String;
220
531
 
532
+ /** Used to avoid iterating non-enumerable properties in IE < 9 */
533
+ var nonEnumProps = {};
534
+ nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
535
+ nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
536
+ nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
537
+ nonEnumProps[objectClass] = { 'constructor': true };
538
+
539
+ (function() {
540
+ var length = shadowedProps.length;
541
+ while (length--) {
542
+ var prop = shadowedProps[length];
543
+ for (var className in nonEnumProps) {
544
+ if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], prop)) {
545
+ nonEnumProps[className][prop] = false;
546
+ }
547
+ }
548
+ }
549
+ }());
550
+
221
551
  /*--------------------------------------------------------------------------*/
222
552
 
223
553
  /**
@@ -239,8 +569,8 @@
239
569
  * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
240
570
  * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
241
571
  * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
242
- * `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `unzip`,
243
- * `values`, `where`, `without`, `wrap`, and `zip`
572
+ * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
573
+ * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
244
574
  *
245
575
  * The non-chainable wrapper functions are:
246
576
  * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
@@ -256,6 +586,7 @@
256
586
  *
257
587
  * @name _
258
588
  * @constructor
589
+ * @alias chain
259
590
  * @category Chaining
260
591
  * @param {Mixed} value The value to wrap in a `lodash` instance.
261
592
  * @returns {Object} Returns a `lodash` instance.
@@ -287,6 +618,19 @@
287
618
  : new lodashWrapper(value);
288
619
  }
289
620
 
621
+ /**
622
+ * A fast path for creating `lodash` wrapper objects.
623
+ *
624
+ * @private
625
+ * @param {Mixed} value The value to wrap in a `lodash` instance.
626
+ * @returns {Object} Returns a `lodash` instance.
627
+ */
628
+ function lodashWrapper(value) {
629
+ this.__wrapped__ = value;
630
+ }
631
+ // ensure `new lodashWrapper` is an instance of `lodash`
632
+ lodashWrapper.prototype = lodash.prototype;
633
+
290
634
  /**
291
635
  * An object used to flag environments features.
292
636
  *
@@ -321,6 +665,15 @@
321
665
  */
322
666
  support.argsClass = isArguments(arguments);
323
667
 
668
+ /**
669
+ * Detect if `name` or `message` properties of `Error.prototype` are
670
+ * enumerable by default. (IE < 9, Safari < 5.1)
671
+ *
672
+ * @memberOf _.support
673
+ * @type Boolean
674
+ */
675
+ support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
676
+
324
677
  /**
325
678
  * Detect if `prototype` properties are enumerable by default.
326
679
  *
@@ -332,7 +685,7 @@
332
685
  * @memberOf _.support
333
686
  * @type Boolean
334
687
  */
335
- support.enumPrototypes = ctor.propertyIsEnumerable('prototype');
688
+ support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
336
689
 
337
690
  /**
338
691
  * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
@@ -488,77 +841,80 @@
488
841
  (obj.init) +
489
842
  ';\nif (!iterable) return result;\n' +
490
843
  (obj.top) +
491
- ';\n';
492
- if (obj.arrays) {
493
- __p += 'var length = iterable.length; index = -1;\nif (' +
494
- (obj.arrays) +
844
+ ';';
845
+ if (obj.array) {
846
+ __p += '\nvar length = iterable.length; index = -1;\nif (' +
847
+ (obj.array) +
495
848
  ') { ';
496
849
  if (support.unindexedChars) {
497
850
  __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
498
851
  }
499
852
  __p += '\n while (++index < length) {\n ' +
500
853
  (obj.loop) +
501
- '\n }\n}\nelse { ';
502
- } else if (support.nonEnumArgs) {
854
+ ';\n }\n}\nelse { ';
855
+ } else if (support.nonEnumArgs) {
503
856
  __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
504
857
  (obj.loop) +
505
- '\n }\n } else { ';
858
+ ';\n }\n } else { ';
506
859
  }
507
860
 
508
861
  if (support.enumPrototypes) {
509
862
  __p += '\n var skipProto = typeof iterable == \'function\';\n ';
510
863
  }
511
864
 
865
+ if (support.enumErrorProps) {
866
+ __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
867
+ }
868
+
869
+ var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
870
+
512
871
  if (obj.useHas && obj.useKeys) {
513
- __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? keys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n ';
514
- if (support.enumPrototypes) {
515
- __p += 'if (!(skipProto && index == \'prototype\')) {\n ';
872
+ __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
873
+ if (conditions.length) {
874
+ __p += ' if (' +
875
+ (conditions.join(' && ')) +
876
+ ') {\n ';
516
877
  }
517
878
  __p +=
518
- (obj.loop);
519
- if (support.enumPrototypes) {
520
- __p += '}\n';
879
+ (obj.loop) +
880
+ '; ';
881
+ if (conditions.length) {
882
+ __p += '\n }';
521
883
  }
522
- __p += ' } ';
884
+ __p += '\n } ';
523
885
  } else {
524
- __p += '\n for (index in iterable) {';
525
- if (support.enumPrototypes || obj.useHas) {
526
- __p += '\n if (';
527
- if (support.enumPrototypes) {
528
- __p += '!(skipProto && index == \'prototype\')';
529
- } if (support.enumPrototypes && obj.useHas) {
530
- __p += ' && ';
531
- } if (obj.useHas) {
532
- __p += 'hasOwnProperty.call(iterable, index)';
533
- }
534
- __p += ') { ';
886
+ __p += '\n for (index in iterable) {\n';
887
+ if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
888
+ __p += ' if (' +
889
+ (conditions.join(' && ')) +
890
+ ') {\n ';
535
891
  }
536
892
  __p +=
537
893
  (obj.loop) +
538
894
  '; ';
539
- if (support.enumPrototypes || obj.useHas) {
895
+ if (conditions.length) {
540
896
  __p += '\n }';
541
897
  }
542
898
  __p += '\n } ';
543
899
  if (support.nonEnumShadows) {
544
- __p += '\n\n var ctor = iterable.constructor;\n ';
545
- for (var k = 0; k < 7; k++) {
546
- __p += '\n index = \'' +
900
+ __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
901
+ for (k = 0; k < 7; k++) {
902
+ __p += '\n index = \'' +
547
903
  (obj.shadowedProps[k]) +
548
- '\';\n if (';
549
- if (obj.shadowedProps[k] == 'constructor') {
550
- __p += '!(ctor && ctor.prototype === iterable) && ';
551
- }
552
- __p += 'hasOwnProperty.call(iterable, index)) {\n ' +
904
+ '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
905
+ if (!obj.useHas) {
906
+ __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
907
+ }
908
+ __p += ') {\n ' +
553
909
  (obj.loop) +
554
- '\n } ';
910
+ ';\n } ';
555
911
  }
556
-
912
+ __p += '\n } ';
557
913
  }
558
914
 
559
915
  }
560
916
 
561
- if (obj.arrays || support.nonEnumArgs) {
917
+ if (obj.array || support.nonEnumArgs) {
562
918
  __p += '\n}';
563
919
  }
564
920
  __p +=
@@ -586,90 +942,18 @@
586
942
  var eachIteratorOptions = {
587
943
  'args': 'collection, callback, thisArg',
588
944
  'top': "callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg)",
589
- 'arrays': "typeof length == 'number'",
945
+ 'array': "typeof length == 'number'",
590
946
  'loop': 'if (callback(iterable[index], index, collection) === false) return result'
591
947
  };
592
948
 
593
949
  /** Reusable iterator options for `forIn` and `forOwn` */
594
950
  var forOwnIteratorOptions = {
595
951
  'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
596
- 'arrays': false
952
+ 'array': false
597
953
  };
598
954
 
599
955
  /*--------------------------------------------------------------------------*/
600
956
 
601
- /**
602
- * Creates a function optimized to search large arrays for a given `value`,
603
- * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
604
- *
605
- * @private
606
- * @param {Array} array The array to search.
607
- * @param {Mixed} value The value to search for.
608
- * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
609
- */
610
- function cachedContains(array) {
611
- var length = array.length,
612
- isLarge = length >= largeArraySize;
613
-
614
- if (isLarge) {
615
- var cache = {},
616
- index = -1;
617
-
618
- while (++index < length) {
619
- var key = keyPrefix + array[index];
620
- (cache[key] || (cache[key] = [])).push(array[index]);
621
- }
622
- }
623
- return function(value) {
624
- if (isLarge) {
625
- var key = keyPrefix + value;
626
- return cache[key] && indexOf(cache[key], value) > -1;
627
- }
628
- return indexOf(array, value) > -1;
629
- }
630
- }
631
-
632
- /**
633
- * Used by `_.max` and `_.min` as the default `callback` when a given
634
- * `collection` is a string value.
635
- *
636
- * @private
637
- * @param {String} value The character to inspect.
638
- * @returns {Number} Returns the code unit of given character.
639
- */
640
- function charAtCallback(value) {
641
- return value.charCodeAt(0);
642
- }
643
-
644
- /**
645
- * Used by `sortBy` to compare transformed `collection` values, stable sorting
646
- * them in ascending order.
647
- *
648
- * @private
649
- * @param {Object} a The object to compare to `b`.
650
- * @param {Object} b The object to compare to `a`.
651
- * @returns {Number} Returns the sort order indicator of `1` or `-1`.
652
- */
653
- function compareAscending(a, b) {
654
- var ai = a.index,
655
- bi = b.index;
656
-
657
- a = a.criteria;
658
- b = b.criteria;
659
-
660
- // ensure a stable sort in V8 and other engines
661
- // http://code.google.com/p/v8/issues/detail?id=90
662
- if (a !== b) {
663
- if (a > b || typeof a == 'undefined') {
664
- return 1;
665
- }
666
- if (a < b || typeof b == 'undefined') {
667
- return -1;
668
- }
669
- }
670
- return ai < bi ? -1 : 1;
671
- }
672
-
673
957
  /**
674
958
  * Creates a function that, when called, invokes `func` with the `this` binding
675
959
  * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
@@ -716,9 +1000,7 @@
716
1000
  }
717
1001
  if (this instanceof bound) {
718
1002
  // ensure `new bound` is an instance of `func`
719
- noop.prototype = func.prototype;
720
- thisBinding = new noop;
721
- noop.prototype = null;
1003
+ thisBinding = createObject(func.prototype);
722
1004
 
723
1005
  // mimic the constructor's `return` behavior
724
1006
  // http://es5.github.com/#x13.2.2
@@ -735,7 +1017,7 @@
735
1017
  *
736
1018
  * @private
737
1019
  * @param {Object} [options1, options2, ...] The compile options object(s).
738
- * arrays - A string of code to determine if the iterable is an array or array-like.
1020
+ * array - A string of code to determine if the iterable is an array or array-like.
739
1021
  * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
740
1022
  * useKeys - A boolean to specify using `_.keys` for own property iteration.
741
1023
  * args - A string of comma separated arguments the iteration function will accept.
@@ -745,18 +1027,15 @@
745
1027
  * @returns {Function} Returns the compiled function.
746
1028
  */
747
1029
  function createIterator() {
748
- var data = {
749
- // data properties
750
- 'shadowedProps': shadowedProps,
751
- // iterator options
752
- 'arrays': 'isArray(iterable)',
753
- 'bottom': '',
754
- 'init': 'iterable',
755
- 'loop': '',
756
- 'top': '',
757
- 'useHas': true,
758
- 'useKeys': !!keys
759
- };
1030
+ var data = getObject();
1031
+
1032
+ // data properties
1033
+ data.shadowedProps = shadowedProps;
1034
+ // iterator options
1035
+ data.array = data.bottom = data.loop = data.top = '';
1036
+ data.init = 'iterable';
1037
+ data.useHas = true;
1038
+ data.useKeys = !!keys;
760
1039
 
761
1040
  // merge options into a template data object
762
1041
  for (var object, index = 0; object = arguments[index]; index++) {
@@ -769,27 +1048,42 @@
769
1048
 
770
1049
  // create the function factory
771
1050
  var factory = Function(
772
- 'hasOwnProperty, isArguments, isArray, isString, keys, ' +
773
- 'lodash, objectTypes',
1051
+ 'errorClass, errorProto, hasOwnProperty, isArguments, isArray, ' +
1052
+ 'isString, keys, lodash, objectProto, objectTypes, nonEnumProps, ' +
1053
+ 'stringClass, stringProto, toString',
774
1054
  'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
775
1055
  );
1056
+
1057
+ releaseObject(data);
1058
+
776
1059
  // return the compiled function
777
1060
  return factory(
778
- hasOwnProperty, isArguments, isArray, isString, keys,
779
- lodash, objectTypes
1061
+ errorClass, errorProto, hasOwnProperty, isArguments, isArray,
1062
+ isString, keys, lodash, objectProto, objectTypes, nonEnumProps,
1063
+ stringClass, stringProto, toString
780
1064
  );
781
1065
  }
782
1066
 
783
1067
  /**
784
- * Used by `template` to escape characters for inclusion in compiled
785
- * string literals.
1068
+ * Creates a new object with the specified `prototype`.
786
1069
  *
787
1070
  * @private
788
- * @param {String} match The matched character to escape.
789
- * @returns {String} Returns the escaped character.
1071
+ * @param {Object} prototype The prototype object.
1072
+ * @returns {Object} Returns the new object.
790
1073
  */
791
- function escapeStringChar(match) {
792
- return '\\' + stringEscapes[match];
1074
+ function createObject(prototype) {
1075
+ return isObject(prototype) ? nativeCreate(prototype) : {};
1076
+ }
1077
+ // fallback for browsers without `Object.create`
1078
+ if (!nativeCreate) {
1079
+ var createObject = function(prototype) {
1080
+ if (isObject(prototype)) {
1081
+ noop.prototype = prototype;
1082
+ var result = new noop;
1083
+ noop.prototype = null;
1084
+ }
1085
+ return result || {};
1086
+ };
793
1087
  }
794
1088
 
795
1089
  /**
@@ -804,38 +1098,39 @@
804
1098
  }
805
1099
 
806
1100
  /**
807
- * Checks if `value` is a DOM node in IE < 9.
1101
+ * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
1102
+ * customized, this method returns the custom method, otherwise it returns
1103
+ * the `basicIndexOf` function.
808
1104
  *
809
1105
  * @private
810
- * @param {Mixed} value The value to check.
811
- * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
1106
+ * @returns {Function} Returns the "indexOf" function.
812
1107
  */
813
- function isNode(value) {
814
- // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
815
- // methods that are `typeof` "string" and still can coerce nodes to strings
816
- return typeof value.toString != 'function' && typeof (value + '') == 'string';
817
- }
818
-
819
- /**
820
- * A fast path for creating `lodash` wrapper objects.
821
- *
822
- * @private
823
- * @param {Mixed} value The value to wrap in a `lodash` instance.
824
- * @returns {Object} Returns a `lodash` instance.
825
- */
826
- function lodashWrapper(value) {
827
- this.__wrapped__ = value;
1108
+ function getIndexOf(array, value, fromIndex) {
1109
+ var result = (result = lodash.indexOf) === indexOf ? basicIndexOf : result;
1110
+ return result;
828
1111
  }
829
- // ensure `new lodashWrapper` is an instance of `lodash`
830
- lodashWrapper.prototype = lodash.prototype;
831
1112
 
832
1113
  /**
833
- * A no-operation function.
1114
+ * Creates a function that juggles arguments, allowing argument overloading
1115
+ * for `_.flatten` and `_.uniq`, before passing them to the given `func`.
834
1116
  *
835
1117
  * @private
1118
+ * @param {Function} func The function to wrap.
1119
+ * @returns {Function} Returns the new function.
836
1120
  */
837
- function noop() {
838
- // no operation performed
1121
+ function overloadWrapper(func) {
1122
+ return function(array, flag, callback, thisArg) {
1123
+ // juggle arguments
1124
+ if (typeof flag != 'boolean' && flag != null) {
1125
+ thisArg = callback;
1126
+ callback = !(thisArg && thisArg[flag] === array) ? flag : undefined;
1127
+ flag = false;
1128
+ }
1129
+ if (callback != null) {
1130
+ callback = lodash.createCallback(callback, thisArg);
1131
+ }
1132
+ return func(array, flag, callback, thisArg);
1133
+ };
839
1134
  }
840
1135
 
841
1136
  /**
@@ -849,62 +1144,33 @@
849
1144
  * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
850
1145
  */
851
1146
  function shimIsPlainObject(value) {
852
- // avoid non-objects and false positives for `arguments` objects
853
- var result = false;
854
- if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
855
- return result;
856
- }
857
- // check that the constructor is `Object` (i.e. `Object instanceof Object`)
858
- var ctor = value.constructor;
859
-
860
- if (isFunction(ctor) ? ctor instanceof ctor : (support.nodeClass || !isNode(value))) {
861
- // IE < 9 iterates inherited properties before own properties. If the first
862
- // iterated property is an object's own property then there are no inherited
863
- // enumerable properties.
864
- if (support.ownLast) {
865
- forIn(value, function(value, key, object) {
866
- result = hasOwnProperty.call(object, key);
867
- return false;
868
- });
869
- return result === true;
870
- }
871
- // In most environments an object's own properties are iterated before
872
- // its inherited properties. If the last iterated property is an object's
873
- // own property then there are no inherited enumerable properties.
874
- forIn(value, function(value, key) {
875
- result = key;
876
- });
877
- return result === false || hasOwnProperty.call(value, result);
878
- }
879
- return result;
880
- }
1147
+ var ctor,
1148
+ result;
881
1149
 
882
- /**
883
- * Slices the `collection` from the `start` index up to, but not including,
884
- * the `end` index.
885
- *
886
- * Note: This function is used, instead of `Array#slice`, to support node lists
887
- * in IE < 9 and to ensure dense arrays are returned.
888
- *
889
- * @private
890
- * @param {Array|Object|String} collection The collection to slice.
891
- * @param {Number} start The start index.
892
- * @param {Number} end The end index.
893
- * @returns {Array} Returns the new array.
894
- */
895
- function slice(array, start, end) {
896
- start || (start = 0);
897
- if (typeof end == 'undefined') {
898
- end = array ? array.length : 0;
1150
+ // avoid non Object objects, `arguments` objects, and DOM elements
1151
+ if (!(value && toString.call(value) == objectClass) ||
1152
+ (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
1153
+ (!support.argsClass && isArguments(value)) ||
1154
+ (!support.nodeClass && isNode(value))) {
1155
+ return false;
899
1156
  }
900
- var index = -1,
901
- length = end - start || 0,
902
- result = Array(length < 0 ? 0 : length);
903
-
904
- while (++index < length) {
905
- result[index] = array[start + index];
1157
+ // IE < 9 iterates inherited properties before own properties. If the first
1158
+ // iterated property is an object's own property then there are no inherited
1159
+ // enumerable properties.
1160
+ if (support.ownLast) {
1161
+ forIn(value, function(value, key, object) {
1162
+ result = hasOwnProperty.call(object, key);
1163
+ return false;
1164
+ });
1165
+ return result !== false;
906
1166
  }
907
- return result;
1167
+ // In most environments an object's own properties are iterated before
1168
+ // its inherited properties. If the last iterated property is an object's
1169
+ // own property then there are no inherited enumerable properties.
1170
+ forIn(value, function(value, key) {
1171
+ result = key;
1172
+ });
1173
+ return result === undefined || hasOwnProperty.call(value, result);
908
1174
  }
909
1175
 
910
1176
  /**
@@ -979,8 +1245,7 @@
979
1245
  'args': 'object',
980
1246
  'init': '[]',
981
1247
  'top': 'if (!(objectTypes[typeof object])) return result',
982
- 'loop': 'result.push(index)',
983
- 'arrays': false
1248
+ 'loop': 'result.push(index)'
984
1249
  });
985
1250
 
986
1251
  /**
@@ -1021,7 +1286,7 @@
1021
1286
  * @param {Mixed} [thisArg] The `this` binding of `callback`.
1022
1287
  * @returns {Array|Object|String} Returns `collection`.
1023
1288
  */
1024
- var each = createIterator(eachIteratorOptions);
1289
+ var basicEach = createIterator(eachIteratorOptions);
1025
1290
 
1026
1291
  /**
1027
1292
  * Used to convert characters to HTML entities:
@@ -1134,7 +1399,7 @@
1134
1399
 
1135
1400
  // allows working with "Collections" methods without using their `callback`
1136
1401
  // argument, `index|key`, for this method's `callback`
1137
- if (typeof deep == 'function') {
1402
+ if (typeof deep != 'boolean' && deep != null) {
1138
1403
  thisArg = callback;
1139
1404
  callback = deep;
1140
1405
  deep = false;
@@ -1179,8 +1444,9 @@
1179
1444
  return ctor(result.source, reFlags.exec(result));
1180
1445
  }
1181
1446
  // check for circular references and return corresponding clone
1182
- stackA || (stackA = []);
1183
- stackB || (stackB = []);
1447
+ var initedStack = !stackA;
1448
+ stackA || (stackA = getArray());
1449
+ stackB || (stackB = getArray());
1184
1450
 
1185
1451
  var length = stackA.length;
1186
1452
  while (length--) {
@@ -1206,10 +1472,14 @@
1206
1472
  stackB.push(result);
1207
1473
 
1208
1474
  // recursively populate clone (susceptible to call stack limits)
1209
- (isArr ? forEach : forOwn)(value, function(objValue, key) {
1475
+ (isArr ? basicEach : forOwn)(value, function(objValue, key) {
1210
1476
  result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
1211
1477
  });
1212
1478
 
1479
+ if (initedStack) {
1480
+ releaseArray(stackA);
1481
+ releaseArray(stackB);
1482
+ }
1213
1483
  return result;
1214
1484
  }
1215
1485
 
@@ -1219,7 +1489,7 @@
1219
1489
  * `undefined`, cloning will be handled by the method instead. The `callback`
1220
1490
  * is bound to `thisArg` and invoked with one argument; (value).
1221
1491
  *
1222
- * Note: This function is loosely based on the structured clone algorithm. Functions
1492
+ * Note: This method is loosely based on the structured clone algorithm. Functions
1223
1493
  * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1224
1494
  * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1225
1495
  * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
@@ -1656,8 +1926,9 @@
1656
1926
  // assume cyclic structures are equal
1657
1927
  // the algorithm for detecting cyclic structures is adapted from ES 5.1
1658
1928
  // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
1659
- stackA || (stackA = []);
1660
- stackB || (stackB = []);
1929
+ var initedStack = !stackA;
1930
+ stackA || (stackA = getArray());
1931
+ stackB || (stackB = getArray());
1661
1932
 
1662
1933
  var length = stackA.length;
1663
1934
  while (length--) {
@@ -1719,6 +1990,10 @@
1719
1990
  }
1720
1991
  });
1721
1992
  }
1993
+ if (initedStack) {
1994
+ releaseArray(stackA);
1995
+ releaseArray(stackB);
1996
+ }
1722
1997
  return result;
1723
1998
  }
1724
1999
 
@@ -1802,7 +2077,7 @@
1802
2077
  // http://es5.github.com/#x8
1803
2078
  // and avoid a V8 bug
1804
2079
  // http://code.google.com/p/v8/issues/detail?id=2291
1805
- return value ? objectTypes[typeof value] : false;
2080
+ return !!(value && objectTypes[typeof value]);
1806
2081
  }
1807
2082
 
1808
2083
  /**
@@ -1923,7 +2198,7 @@
1923
2198
  * // => true
1924
2199
  */
1925
2200
  function isRegExp(value) {
1926
- return value ? (objectTypes[typeof value] && toString.call(value) == regexpClass) : false;
2201
+ return !!(value && objectTypes[typeof value]) && toString.call(value) == regexpClass;
1927
2202
  }
1928
2203
 
1929
2204
  /**
@@ -2028,8 +2303,9 @@
2028
2303
  stackA = args[4],
2029
2304
  stackB = args[5];
2030
2305
  } else {
2031
- stackA = [];
2032
- stackB = [];
2306
+ var initedStack = true;
2307
+ stackA = getArray();
2308
+ stackB = getArray();
2033
2309
 
2034
2310
  // allows working with `_.reduce` and `_.reduceRight` without
2035
2311
  // using their `callback` arguments, `index|key` and `collection`
@@ -2095,6 +2371,11 @@
2095
2371
  object[key] = value;
2096
2372
  });
2097
2373
  }
2374
+
2375
+ if (initedStack) {
2376
+ releaseArray(stackA);
2377
+ releaseArray(stackB);
2378
+ }
2098
2379
  return object;
2099
2380
  }
2100
2381
 
@@ -2125,7 +2406,8 @@
2125
2406
  * // => { 'name': 'moe' }
2126
2407
  */
2127
2408
  function omit(object, callback, thisArg) {
2128
- var isFunc = typeof callback == 'function',
2409
+ var indexOf = getIndexOf(),
2410
+ isFunc = typeof callback == 'function',
2129
2411
  result = {};
2130
2412
 
2131
2413
  if (isFunc) {
@@ -2220,6 +2502,57 @@
2220
2502
  return result;
2221
2503
  }
2222
2504
 
2505
+ /**
2506
+ * An alternative to `_.reduce`, this method transforms an `object` to a new
2507
+ * `accumulator` object which is the result of running each of its elements
2508
+ * through the `callback`, with each `callback` execution potentially mutating
2509
+ * the `accumulator` object. The `callback` is bound to `thisArg` and invoked
2510
+ * with four arguments; (accumulator, value, key, object). Callbacks may exit
2511
+ * iteration early by explicitly returning `false`.
2512
+ *
2513
+ * @static
2514
+ * @memberOf _
2515
+ * @category Objects
2516
+ * @param {Array|Object} collection The collection to iterate over.
2517
+ * @param {Function} [callback=identity] The function called per iteration.
2518
+ * @param {Mixed} [accumulator] The custom accumulator value.
2519
+ * @param {Mixed} [thisArg] The `this` binding of `callback`.
2520
+ * @returns {Mixed} Returns the accumulated value.
2521
+ * @example
2522
+ *
2523
+ * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
2524
+ * num *= num;
2525
+ * if (num % 2) {
2526
+ * return result.push(num) < 3;
2527
+ * }
2528
+ * });
2529
+ * // => [1, 9, 25]
2530
+ *
2531
+ * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2532
+ * result[key] = num * 3;
2533
+ * });
2534
+ * // => { 'a': 3, 'b': 6, 'c': 9 }
2535
+ */
2536
+ function transform(object, callback, accumulator, thisArg) {
2537
+ var isArr = isArray(object);
2538
+ callback = lodash.createCallback(callback, thisArg, 4);
2539
+
2540
+ if (accumulator == null) {
2541
+ if (isArr) {
2542
+ accumulator = [];
2543
+ } else {
2544
+ var ctor = object && object.constructor,
2545
+ proto = ctor && ctor.prototype;
2546
+
2547
+ accumulator = createObject(proto);
2548
+ }
2549
+ }
2550
+ (isArr ? basicEach : forOwn)(object, function(value, index, object) {
2551
+ return callback(accumulator, value, index, object);
2552
+ });
2553
+ return accumulator;
2554
+ }
2555
+
2223
2556
  /**
2224
2557
  * Creates an array composed of the own enumerable property values of `object`.
2225
2558
  *
@@ -2312,17 +2645,18 @@
2312
2645
  */
2313
2646
  function contains(collection, target, fromIndex) {
2314
2647
  var index = -1,
2648
+ indexOf = getIndexOf(),
2315
2649
  length = collection ? collection.length : 0,
2316
2650
  result = false;
2317
2651
 
2318
2652
  fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2319
- if (typeof length == 'number') {
2653
+ if (length && typeof length == 'number') {
2320
2654
  result = (isString(collection)
2321
2655
  ? collection.indexOf(target, fromIndex)
2322
2656
  : indexOf(collection, target, fromIndex)
2323
2657
  ) > -1;
2324
2658
  } else {
2325
- each(collection, function(value) {
2659
+ basicEach(collection, function(value) {
2326
2660
  if (++index >= fromIndex) {
2327
2661
  return !(result = value === target);
2328
2662
  }
@@ -2430,7 +2764,7 @@
2430
2764
  }
2431
2765
  }
2432
2766
  } else {
2433
- each(collection, function(value, index, collection) {
2767
+ basicEach(collection, function(value, index, collection) {
2434
2768
  return (result = !!callback(value, index, collection));
2435
2769
  });
2436
2770
  }
@@ -2492,7 +2826,7 @@
2492
2826
  }
2493
2827
  }
2494
2828
  } else {
2495
- each(collection, function(value, index, collection) {
2829
+ basicEach(collection, function(value, index, collection) {
2496
2830
  if (callback(value, index, collection)) {
2497
2831
  result.push(value);
2498
2832
  }
@@ -2515,7 +2849,7 @@
2515
2849
  *
2516
2850
  * @static
2517
2851
  * @memberOf _
2518
- * @alias detect
2852
+ * @alias detect, findWhere
2519
2853
  * @category Collections
2520
2854
  * @param {Array|Object|String} collection The collection to iterate over.
2521
2855
  * @param {Function|Object|String} [callback=identity] The function called per
@@ -2559,7 +2893,7 @@
2559
2893
  }
2560
2894
  } else {
2561
2895
  var result;
2562
- each(collection, function(value, index, collection) {
2896
+ basicEach(collection, function(value, index, collection) {
2563
2897
  if (callback(value, index, collection)) {
2564
2898
  result = value;
2565
2899
  return false;
@@ -2602,7 +2936,7 @@
2602
2936
  }
2603
2937
  }
2604
2938
  } else {
2605
- each(collection, callback, thisArg);
2939
+ basicEach(collection, callback, thisArg);
2606
2940
  }
2607
2941
  return collection;
2608
2942
  }
@@ -2737,7 +3071,7 @@
2737
3071
  result[index] = callback(collection[index], index, collection);
2738
3072
  }
2739
3073
  } else {
2740
- each(collection, function(value, key, collection) {
3074
+ basicEach(collection, function(value, key, collection) {
2741
3075
  result[++index] = callback(value, key, collection);
2742
3076
  });
2743
3077
  }
@@ -2802,7 +3136,7 @@
2802
3136
  ? charAtCallback
2803
3137
  : lodash.createCallback(callback, thisArg);
2804
3138
 
2805
- each(collection, function(value, index, collection) {
3139
+ basicEach(collection, function(value, index, collection) {
2806
3140
  var current = callback(value, index, collection);
2807
3141
  if (current > computed) {
2808
3142
  computed = current;
@@ -2871,7 +3205,7 @@
2871
3205
  ? charAtCallback
2872
3206
  : lodash.createCallback(callback, thisArg);
2873
3207
 
2874
- each(collection, function(value, index, collection) {
3208
+ basicEach(collection, function(value, index, collection) {
2875
3209
  var current = callback(value, index, collection);
2876
3210
  if (current < computed) {
2877
3211
  computed = current;
@@ -2949,7 +3283,7 @@
2949
3283
  accumulator = callback(accumulator, collection[index], index, collection);
2950
3284
  }
2951
3285
  } else {
2952
- each(collection, function(value, index, collection) {
3286
+ basicEach(collection, function(value, index, collection) {
2953
3287
  accumulator = noaccum
2954
3288
  ? (noaccum = false, value)
2955
3289
  : callback(accumulator, value, index, collection)
@@ -3152,7 +3486,7 @@
3152
3486
  }
3153
3487
  }
3154
3488
  } else {
3155
- each(collection, function(value, index, collection) {
3489
+ basicEach(collection, function(value, index, collection) {
3156
3490
  return !(result = callback(value, index, collection));
3157
3491
  });
3158
3492
  }
@@ -3201,17 +3535,18 @@
3201
3535
 
3202
3536
  callback = lodash.createCallback(callback, thisArg);
3203
3537
  forEach(collection, function(value, key, collection) {
3204
- result[++index] = {
3205
- 'criteria': callback(value, key, collection),
3206
- 'index': index,
3207
- 'value': value
3208
- };
3538
+ var object = result[++index] = getObject();
3539
+ object.criteria = callback(value, key, collection);
3540
+ object.index = index;
3541
+ object.value = value;
3209
3542
  });
3210
3543
 
3211
3544
  length = result.length;
3212
3545
  result.sort(compareAscending);
3213
3546
  while (length--) {
3214
- result[length] = result[length].value;
3547
+ var object = result[length];
3548
+ result[length] = object.value;
3549
+ releaseObject(object);
3215
3550
  }
3216
3551
  return result;
3217
3552
  }
@@ -3311,17 +3646,31 @@
3311
3646
  */
3312
3647
  function difference(array) {
3313
3648
  var index = -1,
3649
+ indexOf = getIndexOf(),
3314
3650
  length = array ? array.length : 0,
3315
- flattened = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
3316
- contains = cachedContains(flattened),
3651
+ seen = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
3317
3652
  result = [];
3318
3653
 
3654
+ var isLarge = length >= largeArraySize && indexOf === basicIndexOf;
3655
+
3656
+ if (isLarge) {
3657
+ var cache = createCache(seen);
3658
+ if (cache) {
3659
+ indexOf = cacheIndexOf;
3660
+ seen = cache;
3661
+ } else {
3662
+ isLarge = false;
3663
+ }
3664
+ }
3319
3665
  while (++index < length) {
3320
3666
  var value = array[index];
3321
- if (!contains(value)) {
3667
+ if (indexOf(seen, value) < 0) {
3322
3668
  result.push(value);
3323
3669
  }
3324
3670
  }
3671
+ if (isLarge) {
3672
+ releaseObject(seen);
3673
+ }
3325
3674
  return result;
3326
3675
  }
3327
3676
 
@@ -3477,20 +3826,11 @@
3477
3826
  * _.flatten(stooges, 'quotes');
3478
3827
  * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
3479
3828
  */
3480
- function flatten(array, isShallow, callback, thisArg) {
3829
+ var flatten = overloadWrapper(function flatten(array, isShallow, callback) {
3481
3830
  var index = -1,
3482
3831
  length = array ? array.length : 0,
3483
3832
  result = [];
3484
3833
 
3485
- // juggle arguments
3486
- if (typeof isShallow != 'boolean' && isShallow != null) {
3487
- thisArg = callback;
3488
- callback = isShallow;
3489
- isShallow = false;
3490
- }
3491
- if (callback != null) {
3492
- callback = lodash.createCallback(callback, thisArg);
3493
- }
3494
3834
  while (++index < length) {
3495
3835
  var value = array[index];
3496
3836
  if (callback) {
@@ -3504,7 +3844,7 @@
3504
3844
  }
3505
3845
  }
3506
3846
  return result;
3507
- }
3847
+ });
3508
3848
 
3509
3849
  /**
3510
3850
  * Gets the index at which the first occurrence of `value` is found using
@@ -3531,21 +3871,14 @@
3531
3871
  * // => 2
3532
3872
  */
3533
3873
  function indexOf(array, value, fromIndex) {
3534
- var index = -1,
3535
- length = array ? array.length : 0;
3536
-
3537
3874
  if (typeof fromIndex == 'number') {
3538
- index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
3875
+ var length = array ? array.length : 0;
3876
+ fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
3539
3877
  } else if (fromIndex) {
3540
- index = sortedIndex(array, value);
3878
+ var index = sortedIndex(array, value);
3541
3879
  return array[index] === value ? index : -1;
3542
3880
  }
3543
- while (++index < length) {
3544
- if (array[index] === value) {
3545
- return index;
3546
- }
3547
- }
3548
- return -1;
3881
+ return array ? basicIndexOf(array, value, fromIndex) : -1;
3549
3882
  }
3550
3883
 
3551
3884
  /**
@@ -3641,35 +3974,45 @@
3641
3974
  function intersection(array) {
3642
3975
  var args = arguments,
3643
3976
  argsLength = args.length,
3644
- cache = { '0': {} },
3977
+ argsIndex = -1,
3978
+ caches = getArray(),
3645
3979
  index = -1,
3980
+ indexOf = getIndexOf(),
3646
3981
  length = array ? array.length : 0,
3647
- isLarge = length >= largeArraySize,
3648
3982
  result = [],
3649
- seen = result;
3983
+ seen = getArray();
3650
3984
 
3985
+ while (++argsIndex < argsLength) {
3986
+ var value = args[argsIndex];
3987
+ caches[argsIndex] = indexOf === basicIndexOf &&
3988
+ (value ? value.length : 0) >= largeArraySize &&
3989
+ createCache(argsIndex ? args[argsIndex] : seen);
3990
+ }
3651
3991
  outer:
3652
3992
  while (++index < length) {
3653
- var value = array[index];
3654
- if (isLarge) {
3655
- var key = keyPrefix + value;
3656
- var inited = cache[0][key]
3657
- ? !(seen = cache[0][key])
3658
- : (seen = cache[0][key] = []);
3659
- }
3660
- if (inited || indexOf(seen, value) < 0) {
3661
- if (isLarge) {
3662
- seen.push(value);
3663
- }
3664
- var argsIndex = argsLength;
3993
+ var cache = caches[0];
3994
+ value = array[index];
3995
+
3996
+ if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
3997
+ argsIndex = argsLength;
3998
+ (cache || seen).push(value);
3665
3999
  while (--argsIndex) {
3666
- if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex])))(value)) {
4000
+ cache = caches[argsIndex];
4001
+ if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
3667
4002
  continue outer;
3668
4003
  }
3669
4004
  }
3670
4005
  result.push(value);
3671
4006
  }
3672
4007
  }
4008
+ while (argsLength--) {
4009
+ cache = caches[argsLength];
4010
+ if (cache) {
4011
+ releaseObject(cache);
4012
+ }
4013
+ }
4014
+ releaseArray(caches);
4015
+ releaseArray(seen);
3673
4016
  return result;
3674
4017
  }
3675
4018
 
@@ -3998,7 +4341,7 @@
3998
4341
  * Creates a duplicate-value-free version of the `array` using strict equality
3999
4342
  * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
4000
4343
  * for `isSorted` will run a faster algorithm. If `callback` is passed, each
4001
- * element of `array` is passed through a `callback` before uniqueness is computed.
4344
+ * element of `array` is passed through the `callback` before uniqueness is computed.
4002
4345
  * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
4003
4346
  *
4004
4347
  * If a property name is passed for `callback`, the created "_.pluck" style
@@ -4027,50 +4370,42 @@
4027
4370
  * _.uniq([1, 1, 2, 2, 3], true);
4028
4371
  * // => [1, 2, 3]
4029
4372
  *
4030
- * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
4031
- * // => [1, 2, 3]
4373
+ * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
4374
+ * // => ['A', 'b', 'C']
4032
4375
  *
4033
- * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
4034
- * // => [1, 2, 3]
4376
+ * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
4377
+ * // => [1, 2.5, 3]
4035
4378
  *
4036
4379
  * // using "_.pluck" callback shorthand
4037
4380
  * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
4038
4381
  * // => [{ 'x': 1 }, { 'x': 2 }]
4039
4382
  */
4040
- function uniq(array, isSorted, callback, thisArg) {
4383
+ var uniq = overloadWrapper(function(array, isSorted, callback) {
4041
4384
  var index = -1,
4385
+ indexOf = getIndexOf(),
4042
4386
  length = array ? array.length : 0,
4043
- result = [],
4044
- seen = result;
4387
+ result = [];
4388
+
4389
+ var isLarge = !isSorted && length >= largeArraySize && indexOf === basicIndexOf,
4390
+ seen = (callback || isLarge) ? getArray() : result;
4045
4391
 
4046
- // juggle arguments
4047
- if (typeof isSorted != 'boolean' && isSorted != null) {
4048
- thisArg = callback;
4049
- callback = isSorted;
4050
- isSorted = false;
4051
- }
4052
- // init value cache for large arrays
4053
- var isLarge = !isSorted && length >= largeArraySize;
4054
4392
  if (isLarge) {
4055
- var cache = {};
4056
- }
4057
- if (callback != null) {
4058
- seen = [];
4059
- callback = lodash.createCallback(callback, thisArg);
4393
+ var cache = createCache(seen);
4394
+ if (cache) {
4395
+ indexOf = cacheIndexOf;
4396
+ seen = cache;
4397
+ } else {
4398
+ isLarge = false;
4399
+ seen = callback ? seen : (releaseArray(seen), result);
4400
+ }
4060
4401
  }
4061
4402
  while (++index < length) {
4062
4403
  var value = array[index],
4063
4404
  computed = callback ? callback(value, index, array) : value;
4064
4405
 
4065
- if (isLarge) {
4066
- var key = keyPrefix + computed;
4067
- var inited = cache[key]
4068
- ? !(seen = cache[key])
4069
- : (seen = cache[key] = []);
4070
- }
4071
4406
  if (isSorted
4072
4407
  ? !index || seen[seen.length - 1] !== computed
4073
- : inited || indexOf(seen, computed) < 0
4408
+ : indexOf(seen, computed) < 0
4074
4409
  ) {
4075
4410
  if (callback || isLarge) {
4076
4411
  seen.push(computed);
@@ -4078,8 +4413,14 @@
4078
4413
  result.push(value);
4079
4414
  }
4080
4415
  }
4416
+ if (isLarge) {
4417
+ releaseArray(seen.array);
4418
+ releaseObject(seen);
4419
+ } else if (callback) {
4420
+ releaseArray(seen);
4421
+ }
4081
4422
  return result;
4082
- }
4423
+ });
4083
4424
 
4084
4425
  /**
4085
4426
  * The inverse of `_.zip`, this method splits groups of elements into arrays
@@ -4097,17 +4438,11 @@
4097
4438
  */
4098
4439
  function unzip(array) {
4099
4440
  var index = -1,
4100
- length = array ? array.length : 0,
4101
- tupleLength = length ? max(pluck(array, 'length')) : 0,
4102
- result = Array(tupleLength);
4441
+ length = array ? max(pluck(array, 'length')) : 0,
4442
+ result = Array(length < 0 ? 0 : length);
4103
4443
 
4104
4444
  while (++index < length) {
4105
- var tupleIndex = -1,
4106
- tuple = array[index];
4107
-
4108
- while (++tupleIndex < tupleLength) {
4109
- (result[tupleIndex] || (result[tupleIndex] = Array(length)))[index] = tuple[tupleIndex];
4110
- }
4445
+ result[index] = pluck(array, index);
4111
4446
  }
4112
4447
  return result;
4113
4448
  }
@@ -4148,14 +4483,7 @@
4148
4483
  * // => [['moe', 30, true], ['larry', 40, false]]
4149
4484
  */
4150
4485
  function zip(array) {
4151
- var index = -1,
4152
- length = array ? max(pluck(arguments, 'length')) : 0,
4153
- result = Array(length);
4154
-
4155
- while (++index < length) {
4156
- result[index] = pluck(arguments, index);
4157
- }
4158
- return result;
4486
+ return array ? unzip(arguments) : [];
4159
4487
  }
4160
4488
 
4161
4489
  /**
@@ -4431,27 +4759,27 @@
4431
4759
  return result;
4432
4760
  };
4433
4761
  }
4434
- if (typeof thisArg != 'undefined') {
4435
- if (argCount === 1) {
4436
- return function(value) {
4437
- return func.call(thisArg, value);
4438
- };
4439
- }
4440
- if (argCount === 2) {
4441
- return function(a, b) {
4442
- return func.call(thisArg, a, b);
4443
- };
4444
- }
4445
- if (argCount === 4) {
4446
- return function(accumulator, value, index, collection) {
4447
- return func.call(thisArg, accumulator, value, index, collection);
4448
- };
4449
- }
4450
- return function(value, index, collection) {
4451
- return func.call(thisArg, value, index, collection);
4762
+ if (typeof thisArg == 'undefined' || (reThis && !reThis.test(fnToString.call(func)))) {
4763
+ return func;
4764
+ }
4765
+ if (argCount === 1) {
4766
+ return function(value) {
4767
+ return func.call(thisArg, value);
4768
+ };
4769
+ }
4770
+ if (argCount === 2) {
4771
+ return function(a, b) {
4772
+ return func.call(thisArg, a, b);
4452
4773
  };
4453
4774
  }
4454
- return func;
4775
+ if (argCount === 4) {
4776
+ return function(accumulator, value, index, collection) {
4777
+ return func.call(thisArg, accumulator, value, index, collection);
4778
+ };
4779
+ }
4780
+ return function(value, index, collection) {
4781
+ return func.call(thisArg, value, index, collection);
4782
+ };
4455
4783
  }
4456
4784
 
4457
4785
  /**
@@ -4472,6 +4800,7 @@
4472
4800
  * @param {Number} wait The number of milliseconds to delay.
4473
4801
  * @param {Object} options The options object.
4474
4802
  * [leading=false] A boolean to specify execution on the leading edge of the timeout.
4803
+ * [maxWait] The maximum time `func` is allowed to be delayed before it's called.
4475
4804
  * [trailing=true] A boolean to specify execution on the trailing edge of the timeout.
4476
4805
  * @returns {Function} Returns the new debounced function.
4477
4806
  * @example
@@ -4486,34 +4815,80 @@
4486
4815
  */
4487
4816
  function debounce(func, wait, options) {
4488
4817
  var args,
4489
- inited,
4490
4818
  result,
4491
4819
  thisArg,
4492
- timeoutId,
4820
+ callCount = 0,
4821
+ lastCalled = 0,
4822
+ maxWait = false,
4823
+ maxTimeoutId = null,
4824
+ timeoutId = null,
4493
4825
  trailing = true;
4494
4826
 
4827
+ function clear() {
4828
+ clearTimeout(maxTimeoutId);
4829
+ clearTimeout(timeoutId);
4830
+ callCount = 0;
4831
+ maxTimeoutId = timeoutId = null;
4832
+ }
4833
+
4495
4834
  function delayed() {
4496
- inited = timeoutId = null;
4497
- if (trailing) {
4835
+ var isCalled = trailing && (!leading || callCount > 1);
4836
+ clear();
4837
+ if (isCalled) {
4838
+ if (maxWait !== false) {
4839
+ lastCalled = new Date;
4840
+ }
4841
+ result = func.apply(thisArg, args);
4842
+ }
4843
+ }
4844
+
4845
+ function maxDelayed() {
4846
+ clear();
4847
+ if (trailing || (maxWait !== wait)) {
4848
+ lastCalled = new Date;
4498
4849
  result = func.apply(thisArg, args);
4499
4850
  }
4500
4851
  }
4852
+
4853
+ wait = nativeMax(0, wait || 0);
4501
4854
  if (options === true) {
4502
4855
  var leading = true;
4503
4856
  trailing = false;
4504
- } else if (options && objectTypes[typeof options]) {
4857
+ } else if (isObject(options)) {
4505
4858
  leading = options.leading;
4859
+ maxWait = 'maxWait' in options && nativeMax(wait, options.maxWait || 0);
4506
4860
  trailing = 'trailing' in options ? options.trailing : trailing;
4507
4861
  }
4508
4862
  return function() {
4509
4863
  args = arguments;
4510
4864
  thisArg = this;
4865
+ callCount++;
4866
+
4867
+ // avoid issues with Titanium and `undefined` timeout ids
4868
+ // https://github.com/appcelerator/titanium_mobile/blob/3_1_0_GA/android/titanium/src/java/ti/modules/titanium/TitaniumModule.java#L185-L192
4511
4869
  clearTimeout(timeoutId);
4512
4870
 
4513
- if (!inited && leading) {
4514
- inited = true;
4515
- result = func.apply(thisArg, args);
4871
+ if (maxWait === false) {
4872
+ if (leading && callCount < 2) {
4873
+ result = func.apply(thisArg, args);
4874
+ }
4516
4875
  } else {
4876
+ var now = new Date;
4877
+ if (!maxTimeoutId && !leading) {
4878
+ lastCalled = now;
4879
+ }
4880
+ var remaining = maxWait - (now - lastCalled);
4881
+ if (remaining <= 0) {
4882
+ clearTimeout(maxTimeoutId);
4883
+ maxTimeoutId = null;
4884
+ lastCalled = now;
4885
+ result = func.apply(thisArg, args);
4886
+ }
4887
+ else if (!maxTimeoutId) {
4888
+ maxTimeoutId = setTimeout(maxDelayed, remaining);
4889
+ }
4890
+ }
4891
+ if (wait !== maxWait) {
4517
4892
  timeoutId = setTimeout(delayed, wait);
4518
4893
  }
4519
4894
  return result;
@@ -4571,7 +4946,8 @@
4571
4946
  * passed, it will be used to determine the cache key for storing the result
4572
4947
  * based on the arguments passed to the memoized function. By default, the first
4573
4948
  * argument passed to the memoized function is used as the cache key. The `func`
4574
- * is executed with the `this` binding of the memoized function.
4949
+ * is executed with the `this` binding of the memoized function. The result
4950
+ * cache is exposed as the `cache` property on the memoized function.
4575
4951
  *
4576
4952
  * @static
4577
4953
  * @memberOf _
@@ -4586,13 +4962,16 @@
4586
4962
  * });
4587
4963
  */
4588
4964
  function memoize(func, resolver) {
4589
- var cache = {};
4590
- return function() {
4591
- var key = keyPrefix + (resolver ? resolver.apply(this, arguments) : arguments[0]);
4965
+ function memoized() {
4966
+ var cache = memoized.cache,
4967
+ key = keyPrefix + (resolver ? resolver.apply(this, arguments) : arguments[0]);
4968
+
4592
4969
  return hasOwnProperty.call(cache, key)
4593
4970
  ? cache[key]
4594
4971
  : (cache[key] = func.apply(this, arguments));
4595
- };
4972
+ }
4973
+ memoized.cache = {};
4974
+ return memoized;
4596
4975
  }
4597
4976
 
4598
4977
  /**
@@ -4712,47 +5091,23 @@
4712
5091
  * }));
4713
5092
  */
4714
5093
  function throttle(func, wait, options) {
4715
- var args,
4716
- result,
4717
- thisArg,
4718
- timeoutId,
4719
- lastCalled = 0,
4720
- leading = true,
5094
+ var leading = true,
4721
5095
  trailing = true;
4722
5096
 
4723
- function trailingCall() {
4724
- timeoutId = null;
4725
- if (trailing) {
4726
- lastCalled = new Date;
4727
- result = func.apply(thisArg, args);
4728
- }
4729
- }
4730
5097
  if (options === false) {
4731
5098
  leading = false;
4732
- } else if (options && objectTypes[typeof options]) {
5099
+ } else if (isObject(options)) {
4733
5100
  leading = 'leading' in options ? options.leading : leading;
4734
5101
  trailing = 'trailing' in options ? options.trailing : trailing;
4735
5102
  }
4736
- return function() {
4737
- var now = new Date;
4738
- if (!timeoutId && !leading) {
4739
- lastCalled = now;
4740
- }
4741
- var remaining = wait - (now - lastCalled);
4742
- args = arguments;
4743
- thisArg = this;
5103
+ options = getObject();
5104
+ options.leading = leading;
5105
+ options.maxWait = wait;
5106
+ options.trailing = trailing;
4744
5107
 
4745
- if (remaining <= 0) {
4746
- clearTimeout(timeoutId);
4747
- timeoutId = null;
4748
- lastCalled = now;
4749
- result = func.apply(thisArg, args);
4750
- }
4751
- else if (!timeoutId) {
4752
- timeoutId = setTimeout(trailingCall, remaining);
4753
- }
4754
- return result;
4755
- };
5108
+ var result = debounce(func, wait, options);
5109
+ releaseObject(options);
5110
+ return result;
4756
5111
  }
4757
5112
 
4758
5113
  /**
@@ -4805,7 +5160,7 @@
4805
5160
  }
4806
5161
 
4807
5162
  /**
4808
- * This function returns the first argument passed to it.
5163
+ * This method returns the first argument passed to it.
4809
5164
  *
4810
5165
  * @static
4811
5166
  * @memberOf _
@@ -4854,7 +5209,7 @@
4854
5209
 
4855
5210
  push.apply(args, arguments);
4856
5211
  var result = func.apply(lodash, args);
4857
- return (value && typeof value == 'object' && value == result)
5212
+ return (value && typeof value == 'object' && value === result)
4858
5213
  ? this
4859
5214
  : new lodashWrapper(result);
4860
5215
  };
@@ -4928,8 +5283,13 @@
4928
5283
  if (max == null) {
4929
5284
  max = min;
4930
5285
  min = 0;
5286
+ } else {
5287
+ max = +max || 0;
4931
5288
  }
4932
- return min + floor(nativeRandom() * ((+max || 0) - min + 1));
5289
+ var rand = nativeRandom();
5290
+ return (min % 1 || max % 1)
5291
+ ? min + nativeMin(rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1))), max)
5292
+ : min + floor(rand * (max - min + 1));
4933
5293
  }
4934
5294
 
4935
5295
  /**
@@ -5332,6 +5692,7 @@
5332
5692
  lodash.throttle = throttle;
5333
5693
  lodash.times = times;
5334
5694
  lodash.toArray = toArray;
5695
+ lodash.transform = transform;
5335
5696
  lodash.union = union;
5336
5697
  lodash.uniq = uniq;
5337
5698
  lodash.unzip = unzip;
@@ -5356,6 +5717,10 @@
5356
5717
  // add functions to `lodash.prototype`
5357
5718
  mixin(lodash);
5358
5719
 
5720
+ // add Underscore compat
5721
+ lodash.chain = lodash;
5722
+ lodash.prototype.chain = function() { return this; };
5723
+
5359
5724
  /*--------------------------------------------------------------------------*/
5360
5725
 
5361
5726
  // add functions that return unwrapped values when chaining
@@ -5407,6 +5772,7 @@
5407
5772
  lodash.all = every;
5408
5773
  lodash.any = some;
5409
5774
  lodash.detect = find;
5775
+ lodash.findWhere = find;
5410
5776
  lodash.foldl = reduce;
5411
5777
  lodash.foldr = reduceRight;
5412
5778
  lodash.include = contains;
@@ -5452,7 +5818,7 @@
5452
5818
  * @memberOf _
5453
5819
  * @type String
5454
5820
  */
5455
- lodash.VERSION = '1.2.1';
5821
+ lodash.VERSION = '1.3.1';
5456
5822
 
5457
5823
  // add "Chaining" functions to the wrapper
5458
5824
  lodash.prototype.toString = wrapperToString;
@@ -5460,7 +5826,7 @@
5460
5826
  lodash.prototype.valueOf = wrapperValueOf;
5461
5827
 
5462
5828
  // add `Array` functions that return unwrapped values
5463
- each(['join', 'pop', 'shift'], function(methodName) {
5829
+ basicEach(['join', 'pop', 'shift'], function(methodName) {
5464
5830
  var func = arrayRef[methodName];
5465
5831
  lodash.prototype[methodName] = function() {
5466
5832
  return func.apply(this.__wrapped__, arguments);
@@ -5468,7 +5834,7 @@
5468
5834
  });
5469
5835
 
5470
5836
  // add `Array` functions that return the wrapped value
5471
- each(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
5837
+ basicEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
5472
5838
  var func = arrayRef[methodName];
5473
5839
  lodash.prototype[methodName] = function() {
5474
5840
  func.apply(this.__wrapped__, arguments);
@@ -5477,7 +5843,7 @@
5477
5843
  });
5478
5844
 
5479
5845
  // add `Array` functions that return new wrapped values
5480
- each(['concat', 'slice', 'splice'], function(methodName) {
5846
+ basicEach(['concat', 'slice', 'splice'], function(methodName) {
5481
5847
  var func = arrayRef[methodName];
5482
5848
  lodash.prototype[methodName] = function() {
5483
5849
  return new lodashWrapper(func.apply(this.__wrapped__, arguments));
@@ -5487,7 +5853,7 @@
5487
5853
  // avoid array-like object bugs with `Array#shift` and `Array#splice`
5488
5854
  // in Firefox < 10 and IE < 9
5489
5855
  if (!support.spliceObjects) {
5490
- each(['pop', 'shift', 'splice'], function(methodName) {
5856
+ basicEach(['pop', 'shift', 'splice'], function(methodName) {
5491
5857
  var func = arrayRef[methodName],
5492
5858
  isSplice = methodName == 'splice';
5493
5859