Projekt

Obecné

Profil

Stáhnout (230 KB) Statistiky
| Větev: | Revize:
1
(function(global, factory) {
2
  /*jshint -W030 */
3
  'use strict';
4
  typeof exports === 'object' && typeof module !== 'undefined'
5
    ? factory(exports)
6
    : typeof define === 'function' && define.amd
7
    ? define(['exports'], factory)
8
    : global.async
9
    ? factory((global.neo_async = global.neo_async || {}))
10
    : factory((global.async = global.async || {}));
11
})(this, function(exports) {
12
  'use strict';
13

    
14
  var noop = function noop() {};
15
  var throwError = function throwError() {
16
    throw new Error('Callback was already called.');
17
  };
18

    
19
  var DEFAULT_TIMES = 5;
20
  var DEFAULT_INTERVAL = 0;
21

    
22
  var obj = 'object';
23
  var func = 'function';
24
  var isArray = Array.isArray;
25
  var nativeKeys = Object.keys;
26
  var nativePush = Array.prototype.push;
27
  var iteratorSymbol = typeof Symbol === func && Symbol.iterator;
28

    
29
  var nextTick, asyncNextTick, asyncSetImmediate;
30
  createImmediate();
31

    
32
  /**
33
   * @memberof async
34
   * @namespace each
35
   * @param {Array|Object} collection
36
   * @param {Function} iterator
37
   * @param {Function} callback
38
   * @example
39
   *
40
   * // array
41
   * var order = [];
42
   * var array = [1, 3, 2];
43
   * var iterator = function(num, done) {
44
   *   setTimeout(function() {
45
   *     order.push(num);
46
   *     done();
47
   *   }, num * 10);
48
   * };
49
   * async.each(array, iterator, function(err, res) {
50
   *   console.log(res); // undefined
51
   *   console.log(order); // [1, 2, 3]
52
   * });
53
   *
54
   * @example
55
   *
56
   * // array with index
57
   * var order = [];
58
   * var array = [1, 3, 2];
59
   * var iterator = function(num, index, done) {
60
   *   setTimeout(function() {
61
   *     order.push([num, index]);
62
   *     done();
63
   *   }, num * 10);
64
   * };
65
   * async.each(array, iterator, function(err, res) {
66
   *   console.log(res); // undefined
67
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
68
   * });
69
   *
70
   * @example
71
   *
72
   * // object
73
   * var order = [];
74
   * var object = { a: 1, b: 3, c: 2 };
75
   * var iterator = function(num, done) {
76
   *   setTimeout(function() {
77
   *     order.push(num);
78
   *     done();
79
   *   }, num * 10);
80
   * };
81
   * async.each(object, iterator, function(err, res) {
82
   *   console.log(res); // undefined
83
   *   console.log(order); // [1, 2, 3]
84
   * });
85
   *
86
   * @example
87
   *
88
   * // object with key
89
   * var order = [];
90
   * var object = { a: 1, b: 3, c: 2 };
91
   * var iterator = function(num, key, done) {
92
   *   setTimeout(function() {
93
   *     order.push([num, key]);
94
   *     done();
95
   *   }, num * 10);
96
   * };
97
   * async.each(object, iterator, function(err, res) {
98
   *   console.log(res); // undefined
99
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
100
   * });
101
   *
102
   * @example
103
   *
104
   * // break
105
   * var order = [];
106
   * var array = [1, 3, 2];
107
   * var iterator = function(num, done) {
108
   *   setTimeout(function() {
109
   *     order.push(num);
110
   *     done(null, num !== 2);
111
   *   }, num * 10);
112
   * };
113
   * async.each(array, iterator, function(err, res) {
114
   *   console.log(res); // undefined
115
   *   console.log(order); // [1, 2]
116
   * });
117
   *
118
   */
119
  var each = createEach(arrayEach, baseEach, symbolEach);
120

    
121
  /**
122
   * @memberof async
123
   * @namespace map
124
   * @param {Array|Object} collection
125
   * @param {Function} iterator
126
   * @param {Function} callback
127
   * @example
128
   *
129
   * // array
130
   * var order = [];
131
   * var array = [1, 3, 2];
132
   * var iterator = function(num, done) {
133
   *   setTimeout(function() {
134
   *     order.push(num);
135
   *     done(null, num);
136
   *   }, num * 10);
137
   * };
138
   * async.map(array, iterator, function(err, res) {
139
   *   console.log(res); // [1, 3, 2];
140
   *   console.log(order); // [1, 2, 3]
141
   * });
142
   *
143
   * @example
144
   *
145
   * // array with index
146
   * var order = [];
147
   * var array = [1, 3, 2];
148
   * var iterator = function(num, index, done) {
149
   *   setTimeout(function() {
150
   *     order.push([num, index]);
151
   *     done(null, num);
152
   *   }, num * 10);
153
   * };
154
   * async.map(array, iterator, function(err, res) {
155
   *   console.log(res); // [1, 3, 2]
156
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
157
   * });
158
   *
159
   * @example
160
   *
161
   * // object
162
   * var order = [];
163
   * var object = { a: 1, b: 3, c: 2 };
164
   * var iterator = function(num, done) {
165
   *   setTimeout(function() {
166
   *     order.push(num);
167
   *     done(null, num);
168
   *   }, num * 10);
169
   * };
170
   * async.map(object, iterator, function(err, res) {
171
   *   console.log(res); // [1, 3, 2]
172
   *   console.log(order); // [1, 2, 3]
173
   * });
174
   *
175
   * @example
176
   *
177
   * // object with key
178
   * var order = [];
179
   * var object = { a: 1, b: 3, c: 2 };
180
   * var iterator = function(num, key, done) {
181
   *   setTimeout(function() {
182
   *     order.push([num, key]);
183
   *     done(null, num);
184
   *   }, num * 10);
185
   * };
186
   * async.map(object, iterator, function(err, res) {
187
   *   console.log(res); // [1, 3, 2]
188
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
189
   * });
190
   *
191
   */
192
  var map = createMap(arrayEachIndex, baseEachIndex, symbolEachIndex, true);
193

    
194
  /**
195
   * @memberof async
196
   * @namespace mapValues
197
   * @param {Array|Object} collection
198
   * @param {Function} iterator
199
   * @param {Function} callback
200
   * @example
201
   *
202
   * // array
203
   * var order = [];
204
   * var array = [1, 3, 2];
205
   * var iterator = function(num, done) {
206
   *   setTimeout(function() {
207
   *     order.push(num);
208
   *     done(null, num);
209
   *   }, num * 10);
210
   * };
211
   * async.mapValues(array, iterator, function(err, res) {
212
   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
213
   *   console.log(order); // [1, 2, 3]
214
   * });
215
   *
216
   * @example
217
   *
218
   * // array with index
219
   * var order = [];
220
   * var array = [1, 3, 2];
221
   * var iterator = function(num, index, done) {
222
   *   setTimeout(function() {
223
   *     order.push([num, index]);
224
   *     done(null, num);
225
   *   }, num * 10);
226
   * };
227
   * async.mapValues(array, iterator, function(err, res) {
228
   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
229
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
230
   * });
231
   *
232
   * @example
233
   *
234
   * // object
235
   * var order = [];
236
   * var object = { a: 1, b: 3, c: 2 };
237
   * var iterator = function(num, done) {
238
   *   setTimeout(function() {
239
   *     order.push(num);
240
   *     done(null, num);
241
   *   }, num * 10);
242
   * };
243
   * async.mapValues(object, iterator, function(err, res) {
244
   *   console.log(res); // { a: 1, b: 3, c: 2 }
245
   *   console.log(order); // [1, 2, 3]
246
   * });
247
   *
248
   * @example
249
   *
250
   * // object with key
251
   * var order = [];
252
   * var object = { a: 1, b: 3, c: 2 };
253
   * var iterator = function(num, key, done) {
254
   *   setTimeout(function() {
255
   *     order.push([num, key]);
256
   *     done(null, num);
257
   *   }, num * 10);
258
   * };
259
   * async.mapValues(object, iterator, function(err, res) {
260
   *   console.log(res); // { a: 1, b: 3, c: 2 }
261
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
262
   * });
263
   *
264
   */
265
  var mapValues = createMap(arrayEachIndex, baseEachKey, symbolEachKey, false);
266

    
267
  /**
268
   * @memberof async
269
   * @namespace filter
270
   * @param {Array|Object} collection
271
   * @param {Function} iterator
272
   * @param {Function} callback
273
   * @example
274
   *
275
   * // array
276
   * var order = [];
277
   * var array = [1, 3, 2];
278
   * var iterator = function(num, done) {
279
   *   setTimeout(function() {
280
   *     order.push(num);
281
   *     done(null, num % 2);
282
   *   }, num * 10);
283
   * };
284
   * async.filter(array, iterator, function(err, res) {
285
   *   console.log(res); // [1, 3];
286
   *   console.log(order); // [1, 2, 3]
287
   * });
288
   *
289
   * @example
290
   *
291
   * // array with index
292
   * var order = [];
293
   * var array = [1, 3, 2];
294
   * var iterator = function(num, index, done) {
295
   *   setTimeout(function() {
296
   *     order.push([num, index]);
297
   *     done(null, num % 2);
298
   *   }, num * 10);
299
   * };
300
   * async.filter(array, iterator, function(err, res) {
301
   *   console.log(res); // [1, 3];
302
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
303
   * });
304
   *
305
   * @example
306
   *
307
   * // object
308
   * var order = [];
309
   * var object = { a: 1, b: 3, c: 2 };
310
   * var iterator = function(num, done) {
311
   *   setTimeout(function() {
312
   *     order.push(num);
313
   *     done(null, num % 2);
314
   *   }, num * 10);
315
   * };
316
   * async.filter(object, iterator, function(err, res) {
317
   *   console.log(res); // [1, 3];
318
   *   console.log(order); // [1, 2, 3]
319
   * });
320
   *
321
   * @example
322
   *
323
   * // object with key
324
   * var order = [];
325
   * var object = { a: 1, b: 3, c: 2 };
326
   * var iterator = function(num, key, done) {
327
   *   setTimeout(function() {
328
   *     order.push([num, key]);
329
   *     done(null, num % 2);
330
   *   }, num * 10);
331
   * };
332
   * async.filter(object, iterator, function(err, res) {
333
   *   console.log(res); // [1, 3];
334
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
335
   * });
336
   *
337
   */
338
  var filter = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, true);
339

    
340
  /**
341
   * @memberof async
342
   * @namespace filterSeries
343
   * @param {Array|Object} collection
344
   * @param {Function} iterator
345
   * @param {Function} callback
346
   * @example
347
   *
348
   * // array
349
   * var order = [];
350
   * var array = [1, 3, 2];
351
   * var iterator = function(num, done) {
352
   *   setTimeout(function() {
353
   *     order.push(num);
354
   *     done(null, num % 2);
355
   *   }, num * 10);
356
   * };
357
   * async.filterSeries(array, iterator, function(err, res) {
358
   *   console.log(res); // [1, 3];
359
   *   console.log(order); // [1, 3, 2]
360
   * });
361
   *
362
   * @example
363
   *
364
   * // array with index
365
   * var order = [];
366
   * var array = [1, 3, 2];
367
   * var iterator = function(num, index, done) {
368
   *   setTimeout(function() {
369
   *     order.push([num, index]);
370
   *     done(null, num % 2);
371
   *   }, num * 10);
372
   * };
373
   * async.filterSeries(array, iterator, function(err, res) {
374
   *   console.log(res); // [1, 3]
375
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
376
   * });
377
   *
378
   * @example
379
   *
380
   * // object
381
   * var order = [];
382
   * var object = { a: 1, b: 3, c: 2 };
383
   * var iterator = function(num, done) {
384
   *   setTimeout(function() {
385
   *     order.push(num);
386
   *     done(null, num % 2);
387
   *   }, num * 10);
388
   * };
389
   * async.filterSeries(object, iterator, function(err, res) {
390
   *   console.log(res); // [1, 3]
391
   *   console.log(order); // [1, 3, 2]
392
   * });
393
   *
394
   * @example
395
   *
396
   * // object with key
397
   * var order = [];
398
   * var object = { a: 1, b: 3, c: 2 };
399
   * var iterator = function(num, key, done) {
400
   *   setTimeout(function() {
401
   *     order.push([num, key]);
402
   *     done(null, num % 2);
403
   *   }, num * 10);
404
   * };
405
   * async.filterSeries(object, iterator, function(err, res) {
406
   *   console.log(res); // [1, 3]
407
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
408
   * });
409
   *
410
   */
411
  var filterSeries = createFilterSeries(true);
412

    
413
  /**
414
   * @memberof async
415
   * @namespace filterLimit
416
   * @param {Array|Object} collection
417
   * @param {number} limit - limit >= 1
418
   * @param {Function} iterator
419
   * @param {Function} callback
420
   * @example
421
   *
422
   * // array
423
   * var order = [];
424
   * var array = [1, 5, 3, 4, 2];
425
   * var iterator = function(num, done) {
426
   *   setTimeout(function() {
427
   *     order.push(num);
428
   *     done(null, num % 2);
429
   *   }, num * 10);
430
   * };
431
   * async.filterLimit(array, 2, iterator, function(err, res) {
432
   *   console.log(res); // [1, 5, 3]
433
   *   console.log(order); // [1, 3, 5, 2, 4]
434
   * });
435
   *
436
   * @example
437
   *
438
   * // array with index
439
   * var order = [];
440
   * var array = [1, 5, 3, 4, 2];
441
   * var iterator = function(num, index, done) {
442
   *   setTimeout(function() {
443
   *     order.push([num, index]);
444
   *     done(null, num % 2);
445
   *   }, num * 10);
446
   * };
447
   * async.filterLimit(array, 2, iterator, function(err, res) {
448
   *   console.log(res); // [1, 5, 3]
449
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
450
   * });
451
   *
452
   * @example
453
   *
454
   * // object
455
   * var order = [];
456
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
457
   * var iterator = function(num, done) {
458
   *   setTimeout(function() {
459
   *     order.push(num);
460
   *     done(null, num % 2);
461
   *   }, num * 10);
462
   * };
463
   * async.filterLimit(object, 2, iterator, function(err, res) {
464
   *   console.log(res); // [1, 5, 3]
465
   *   console.log(order); // [1, 3, 5, 2, 4]
466
   * });
467
   *
468
   * @example
469
   *
470
   * // object with key
471
   * var order = [];
472
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
473
   * var iterator = function(num, key, done) {
474
   *   setTimeout(function() {
475
   *     order.push([num, key]);
476
   *     done(null, num % 2);
477
   *   }, num * 10);
478
   * };
479
   * async.filterLimit(object, 2, iterator, function(err, res) {
480
   *   console.log(res); // [1, 5, 3]
481
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
482
   * });
483
   *
484
   */
485
  var filterLimit = createFilterLimit(true);
486

    
487
  /**
488
   * @memberof async
489
   * @namespace reject
490
   * @param {Array|Object} collection
491
   * @param {Function} iterator
492
   * @param {Function} callback
493
   * @example
494
   *
495
   * // array
496
   * var order = [];
497
   * var array = [1, 3, 2];
498
   * var iterator = function(num, done) {
499
   *   setTimeout(function() {
500
   *     order.push(num);
501
   *     done(null, num % 2);
502
   *   }, num * 10);
503
   * };
504
   * async.reject(array, iterator, function(err, res) {
505
   *   console.log(res); // [2];
506
   *   console.log(order); // [1, 2, 3]
507
   * });
508
   *
509
   * @example
510
   *
511
   * // array with index
512
   * var order = [];
513
   * var array = [1, 3, 2];
514
   * var iterator = function(num, index, done) {
515
   *   setTimeout(function() {
516
   *     order.push([num, index]);
517
   *     done(null, num % 2);
518
   *   }, num * 10);
519
   * };
520
   * async.reject(array, iterator, function(err, res) {
521
   *   console.log(res); // [2];
522
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
523
   * });
524
   *
525
   * @example
526
   *
527
   * // object
528
   * var order = [];
529
   * var object = { a: 1, b: 3, c: 2 };
530
   * var iterator = function(num, done) {
531
   *   setTimeout(function() {
532
   *     order.push(num);
533
   *     done(null, num % 2);
534
   *   }, num * 10);
535
   * };
536
   * async.reject(object, iterator, function(err, res) {
537
   *   console.log(res); // [2];
538
   *   console.log(order); // [1, 2, 3]
539
   * });
540
   *
541
   * @example
542
   *
543
   * // object with key
544
   * var order = [];
545
   * var object = { a: 1, b: 3, c: 2 };
546
   * var iterator = function(num, key, done) {
547
   *   setTimeout(function() {
548
   *     order.push([num, key]);
549
   *     done(null, num % 2);
550
   *   }, num * 10);
551
   * };
552
   * async.reject(object, iterator, function(err, res) {
553
   *   console.log(res); // [2];
554
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
555
   * });
556
   *
557
   */
558
  var reject = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, false);
559

    
560
  /**
561
   * @memberof async
562
   * @namespace rejectSeries
563
   * @param {Array|Object} collection
564
   * @param {Function} iterator
565
   * @param {Function} callback
566
   * @example
567
   *
568
   * // array
569
   * var order = [];
570
   * var array = [1, 3, 2];
571
   * var iterator = function(num, done) {
572
   *   setTimeout(function() {
573
   *     order.push(num);
574
   *     done(null, num % 2);
575
   *   }, num * 10);
576
   * };
577
   * async.rejectSeries(array, iterator, function(err, res) {
578
   *   console.log(res); // [2];
579
   *   console.log(order); // [1, 3, 2]
580
   * });
581
   *
582
   * @example
583
   *
584
   * // object
585
   * var order = [];
586
   * var object = { a: 1, b: 3, c: 2 };
587
   * var iterator = function(num, done) {
588
   *   setTimeout(function() {
589
   *     order.push(num);
590
   *     done(null, num % 2);
591
   *   }, num * 10);
592
   * };
593
   * async.rejectSeries(object, iterator, function(err, res) {
594
   *   console.log(res); // [2];
595
   *   console.log(order); // [1, 3, 2]
596
   * });
597
   *
598
   * @example
599
   *
600
   * // object with key
601
   * var order = [];
602
   * var object = { a: 1, b: 3, c: 2 };
603
   * var iterator = function(num, key, done) {
604
   *   setTimeout(function() {
605
   *     order.push([num, key]);
606
   *     done(null, num % 2);
607
   *   }, num * 10);
608
   * };
609
   * async.rejectSeries(object, iterator, function(err, res) {
610
   *   console.log(res); // [2];
611
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
612
   * });
613
   *
614
   */
615
  var rejectSeries = createFilterSeries(false);
616

    
617
  /**
618
   * @memberof async
619
   * @namespace rejectLimit
620
   * @param {Array|Object} collection
621
   * @param {number} limit - limit >= 1
622
   * @param {Function} iterator
623
   * @param {Function} callback
624
   * @example
625
   *
626
   * // array
627
   * var order = [];
628
   * var array = [1, 5, 3, 4, 2];
629
   * var iterator = function(num, done) {
630
   *   setTimeout(function() {
631
   *     order.push(num);
632
   *     done(null, num % 2);
633
   *   }, num * 10);
634
   * };
635
   * async.rejectLimit(array, 2, iterator, function(err, res) {
636
   *   console.log(res); // [4, 2]
637
   *   console.log(order); // [1, 3, 5, 2, 4]
638
   * });
639
   *
640
   * @example
641
   *
642
   * // array with index
643
   * var order = [];
644
   * var array = [1, 5, 3, 4, 2];
645
   * var iterator = function(num, index, done) {
646
   *   setTimeout(function() {
647
   *     order.push([num, index]);
648
   *     done(null, num % 2);
649
   *   }, num * 10);
650
   * };
651
   * async.rejectLimit(array, 2, iterator, function(err, res) {
652
   *   console.log(res); // [4, 2]
653
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
654
   * });
655
   *
656
   * @example
657
   *
658
   * // object
659
   * var order = [];
660
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
661
   * var iterator = function(num, done) {
662
   *   setTimeout(function() {
663
   *     order.push(num);
664
   *     done(null, num % 2);
665
   *   }, num * 10);
666
   * };
667
   * async.rejectLimit(object, 2, iterator, function(err, res) {
668
   *   console.log(res); // [4, 2]
669
   *   console.log(order); // [1, 3, 5, 2, 4]
670
   * });
671
   *
672
   * @example
673
   *
674
   * // object with key
675
   * var order = [];
676
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
677
   * var iterator = function(num, key, done) {
678
   *   setTimeout(function() {
679
   *     order.push([num, key]);
680
   *     done(null, num % 2);
681
   *   }, num * 10);
682
   * };
683
   * async.rejectLimit(object, 2, iterator, function(err, res) {
684
   *   console.log(res); // [4, 2]
685
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
686
   * });
687
   *
688
   */
689
  var rejectLimit = createFilterLimit(false);
690

    
691
  /**
692
   * @memberof async
693
   * @namespace detect
694
   * @param {Array|Object} collection
695
   * @param {Function} iterator
696
   * @param {Function} callback
697
   * @example
698
   *
699
   * // array
700
   * var order = [];
701
   * var array = [1, 3, 2];
702
   * var iterator = function(num, done) {
703
   *   setTimeout(function() {
704
   *     order.push(num);
705
   *     done(null, num % 2);
706
   *   }, num * 10);
707
   * };
708
   * async.detect(array, iterator, function(err, res) {
709
   *   console.log(res); // 1
710
   *   console.log(order); // [1]
711
   * });
712
   *
713
   * @example
714
   *
715
   * // array with index
716
   * var order = [];
717
   * var array = [1, 3, 2];
718
   * var iterator = function(num, index, done) {
719
   *   setTimeout(function() {
720
   *     order.push([num, index]);
721
   *     done(null, num % 2);
722
   *   }, num * 10);
723
   * };
724
   * async.detect(array, iterator, function(err, res) {
725
   *   console.log(res); // 1
726
   *   console.log(order); // [[1, 0]]
727
   * });
728
   *
729
   * @example
730
   *
731
   * // object
732
   * var order = [];
733
   * var object = { a: 1, b: 3, c: 2 };
734
   * var iterator = function(num, done) {
735
   *   setTimeout(function() {
736
   *     order.push(num);
737
   *     done(null, num % 2);
738
   *   }, num * 10);
739
   * };
740
   * async.detect(object, iterator, function(err, res) {
741
   *   console.log(res); // 1
742
   *   console.log(order); // [1]
743
   * });
744
   *
745
   * @example
746
   *
747
   * // object with key
748
   * var order = [];
749
   * var object = { a: 1, b: 3, c: 2 };
750
   * var iterator = function(num, key, done) {
751
   *   setTimeout(function() {
752
   *     order.push([num, key]);
753
   *     done(null, num % 2);
754
   *   }, num * 10);
755
   * };
756
   * async.detect(object, iterator, function(err, res) {
757
   *   console.log(res); // 1
758
   *   console.log(order); // [[1, 'a']]
759
   * });
760
   *
761
   */
762
  var detect = createDetect(arrayEachValue, baseEachValue, symbolEachValue, true);
763

    
764
  /**
765
   * @memberof async
766
   * @namespace detectSeries
767
   * @param {Array|Object} collection
768
   * @param {Function} iterator
769
   * @param {Function} callback
770
   * @example
771
   *
772
   * // array
773
   * var order = [];
774
   * var array = [1, 3, 2];
775
   * var iterator = function(num, done) {
776
   *   setTimeout(function() {
777
   *     order.push(num);
778
   *     done(null, num % 2);
779
   *   }, num * 10);
780
   * };
781
   * async.detectSeries(array, iterator, function(err, res) {
782
   *   console.log(res); // 1
783
   *   console.log(order); // [1]
784
   * });
785
   *
786
   * @example
787
   *
788
   * // array with index
789
   * var order = [];
790
   * var array = [1, 3, 2];
791
   * var iterator = function(num, index, done) {
792
   *   setTimeout(function() {
793
   *     order.push([num, index]);
794
   *     done(null, num % 2);
795
   *   }, num * 10);
796
   * };
797
   * async.detectSeries(array, iterator, function(err, res) {
798
   *   console.log(res); // 1
799
   *   console.log(order); // [[1, 0]]
800
   * });
801
   *
802
   * @example
803
   *
804
   * // object
805
   * var order = [];
806
   * var object = { a: 1, b: 3, c: 2 };
807
   * var iterator = function(num, done) {
808
   *   setTimeout(function() {
809
   *     order.push(num);
810
   *     done(null, num % 2);
811
   *   }, num * 10);
812
   * };
813
   * async.detectSeries(object, iterator, function(err, res) {
814
   *   console.log(res); // 1
815
   *   console.log(order); // [1]
816
   * });
817
   *
818
   * @example
819
   *
820
   * // object with key
821
   * var order = [];
822
   * var object = { a: 1, b: 3, c: 2 };
823
   * var iterator = function(num, key, done) {
824
   *   setTimeout(function() {
825
   *     order.push([num, key]);
826
   *     done(null, num % 2);
827
   *   }, num * 10);
828
   * };
829
   * async.detectSeries(object, iterator, function(err, res) {
830
   *   console.log(res); // 1
831
   *   console.log(order); // [[1, 'a']]
832
   * });
833
   *
834
   */
835
  var detectSeries = createDetectSeries(true);
836

    
837
  /**
838
   * @memberof async
839
   * @namespace detectLimit
840
   * @param {Array|Object} collection
841
   * @param {number} limit - limit >= 1
842
   * @param {Function} iterator
843
   * @param {Function} callback
844
   * @example
845
   *
846
   * // array
847
   * var order = [];
848
   * var array = [1, 5, 3, 4, 2];
849
   * var iterator = function(num, done) {
850
   *   setTimeout(function() {
851
   *     order.push(num);
852
   *     done(null, num % 2);
853
   *   }, num * 10);
854
   * };
855
   * async.detectLimit(array, 2, iterator, function(err, res) {
856
   *   console.log(res); // 1
857
   *   console.log(order); // [1]
858
   * });
859
   *
860
   * @example
861
   *
862
   * // array with index
863
   * var order = [];
864
   * var array = [1, 5, 3, 4, 2];
865
   * var iterator = function(num, index, done) {
866
   *   setTimeout(function() {
867
   *     order.push([num, index]);
868
   *     done(null, num % 2);
869
   *   }, num * 10);
870
   * };
871
   * async.detectLimit(array, 2, iterator, function(err, res) {
872
   *   console.log(res); // 1
873
   *   console.log(order); // [[1, 0]]
874
   * });
875
   *
876
   * @example
877
   *
878
   * // object
879
   * var order = [];
880
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
881
   * var iterator = function(num, done) {
882
   *   setTimeout(function() {
883
   *     order.push(num);
884
   *     done(null, num % 2);
885
   *   }, num * 10);
886
   * };
887
   * async.detectLimit(object, 2, iterator, function(err, res) {
888
   *   console.log(res); // 1
889
   *   console.log(order); // [1]
890
   * });
891
   *
892
   * @example
893
   *
894
   * // object with key
895
   * var order = [];
896
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
897
   * var iterator = function(num, key, done) {
898
   *   setTimeout(function() {
899
   *     order.push([num, key]);
900
   *     done(null, num % 2);
901
   *   }, num * 10);
902
   * };
903
   * async.detectLimit(object, 2, iterator, function(err, res) {
904
   *   console.log(res); // 1
905
   *   console.log(order); // [[1, 'a']]
906
   * });
907
   *
908
   */
909
  var detectLimit = createDetectLimit(true);
910

    
911
  /**
912
   * @memberof async
913
   * @namespace every
914
   * @param {Array|Object} collection
915
   * @param {Function} iterator
916
   * @param {Function} callback
917
   * @example
918
   *
919
   * // array
920
   * var order = [];
921
   * var array = [1, 3, 2];
922
   * var iterator = function(num, done) {
923
   *   setTimeout(function() {
924
   *     order.push(num);
925
   *     done(null, num % 2);
926
   *   }, num * 10);
927
   * };
928
   * async.every(array, iterator, function(err, res) {
929
   *   console.log(res); // false
930
   *   console.log(order); // [1, 2]
931
   * });
932
   *
933
   * @example
934
   *
935
   * // array with index
936
   * var order = [];
937
   * var array = [1, 3, 2];
938
   * var iterator = function(num, index, done) {
939
   *   setTimeout(function() {
940
   *     order.push([num, index]);
941
   *     done(null, num % 2);
942
   *   }, num * 10);
943
   * };
944
   * async.every(array, iterator, function(err, res) {
945
   *   console.log(res); // false
946
   *   console.log(order); // [[1, 0], [2, 2]]
947
   * });
948
   *
949
   * @example
950
   *
951
   * // object
952
   * var order = [];
953
   * var object = { a: 1, b: 3, c: 2 };
954
   * var iterator = function(num, done) {
955
   *   setTimeout(function() {
956
   *     order.push(num);
957
   *     done(null, num % 2);
958
   *   }, num * 10);
959
   * };
960
   * async.every(object, iterator, function(err, res) {
961
   *   console.log(res); // false
962
   *   console.log(order); // [1, 2]
963
   * });
964
   *
965
   * @example
966
   *
967
   * // object with key
968
   * var order = [];
969
   * var object = { a: 1, b: 3, c: 2 };
970
   * var iterator = function(num, key, done) {
971
   *   setTimeout(function() {
972
   *     order.push([num, key]);
973
   *     done(null, num % 2);
974
   *   }, num * 10);
975
   * };
976
   * async.every(object, iterator, function(err, res) {
977
   *   console.log(res); // false
978
   *   console.log(order); // [[1, 'a'], [2, 'c']]
979
   * });
980
   *
981
   */
982
  var every = createEvery(arrayEachValue, baseEachValue, symbolEachValue);
983

    
984
  /**
985
   * @memberof async
986
   * @namespace everySeries
987
   * @param {Array|Object} collection
988
   * @param {Function} iterator
989
   * @param {Function} callback
990
   * @example
991
   *
992
   * // array
993
   * var order = [];
994
   * var array = [1, 3, 2];
995
   * var iterator = function(num, done) {
996
   *   setTimeout(function() {
997
   *     order.push(num);
998
   *     done(null, num % 2);
999
   *   }, num * 10);
1000
   * };
1001
   * async.everySeries(array, iterator, function(err, res) {
1002
   *   console.log(res); // false
1003
   *   console.log(order); // [1, 3, 2]
1004
   * });
1005
   *
1006
   * @example
1007
   *
1008
   * // array with index
1009
   * var order = [];
1010
   * var array = [1, 3, 2];
1011
   * var iterator = function(num, index, done) {
1012
   *   setTimeout(function() {
1013
   *     order.push([num, index]);
1014
   *     done(null, num % 2);
1015
   *   }, num * 10);
1016
   * };
1017
   * async.everySeries(array, iterator, function(err, res) {
1018
   *   console.log(res); // false
1019
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
1020
   * });
1021
   *
1022
   * @example
1023
   *
1024
   * // object
1025
   * var order = [];
1026
   * var object = { a: 1, b: 3, c: 2 };
1027
   * var iterator = function(num, done) {
1028
   *   setTimeout(function() {
1029
   *     order.push(num);
1030
   *     done(null, num % 2);
1031
   *   }, num * 10);
1032
   * };
1033
   * async.everySeries(object, iterator, function(err, res) {
1034
   *   console.log(res); // false
1035
   *   console.log(order); // [1, 3, 2]
1036
   * });
1037
   *
1038
   * @example
1039
   *
1040
   * // object with key
1041
   * var order = [];
1042
   * var object = { a: 1, b: 3, c: 2 };
1043
   * var iterator = function(num, key, done) {
1044
   *   setTimeout(function() {
1045
   *     order.push([num, key]);
1046
   *     done(null, num % 2);
1047
   *   }, num * 10);
1048
   * };
1049
   * async.everySeries(object, iterator, function(err, res) {
1050
   *   console.log(res); // false
1051
   *   console.log(order); // [[1, 'a'], [3, 'b'] [2, 'c']]
1052
   * });
1053
   *
1054
   */
1055
  var everySeries = createEverySeries();
1056

    
1057
  /**
1058
   * @memberof async
1059
   * @namespace everyLimit
1060
   * @param {Array|Object} collection
1061
   * @param {number} limit - limit >= 1
1062
   * @param {Function} iterator
1063
   * @param {Function} callback
1064
   * @example
1065
   *
1066
   * // array
1067
   * var order = [];
1068
   * var array = [1, 5, 3, 4, 2];
1069
   * var iterator = function(num, done) {
1070
   *   setTimeout(function() {
1071
   *     order.push(num);
1072
   *     done(null, num % 2);
1073
   *   }, num * 10);
1074
   * };
1075
   * async.everyLimit(array, 2, iterator, function(err, res) {
1076
   *   console.log(res); // false
1077
   *   console.log(order); // [1, 3, 5, 2]
1078
   * });
1079
   *
1080
   * @example
1081
   *
1082
   * // array with index
1083
   * var order = [];
1084
   * var array = [1, 5, 3, 4, 2];
1085
   * var iterator = function(num, index, done) {
1086
   *   setTimeout(function() {
1087
   *     order.push([num, index]);
1088
   *     done(null, num % 2);
1089
   *   }, num * 10);
1090
   * };
1091
   * async.everyLimit(array, 2, iterator, function(err, res) {
1092
   *   console.log(res); // false
1093
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4]]
1094
   * });
1095
   *
1096
   * @example
1097
   *
1098
   * // object
1099
   * var order = [];
1100
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1101
   * var iterator = function(num, done) {
1102
   *   setTimeout(function() {
1103
   *     order.push(num);
1104
   *     done(null, num % 2);
1105
   *   }, num * 10);
1106
   * };
1107
   * async.everyLimit(object, 2, iterator, function(err, res) {
1108
   *   console.log(res); // false
1109
   *   console.log(order); // [1, 3, 5, 2]
1110
   * });
1111
   *
1112
   * @example
1113
   *
1114
   * // object with key
1115
   * var order = [];
1116
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1117
   * var iterator = function(num, key, done) {
1118
   *   setTimeout(function() {
1119
   *     order.push([num, key]);
1120
   *     done(null, num % 2);
1121
   *   }, num * 10);
1122
   * };
1123
   * async.everyLimit(object, 2, iterator, function(err, res) {
1124
   *   console.log(res); // false
1125
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e']]
1126
   * });
1127
   *
1128
   */
1129
  var everyLimit = createEveryLimit();
1130

    
1131
  /**
1132
   * @memberof async
1133
   * @namespace pick
1134
   * @param {Array|Object} collection
1135
   * @param {Function} iterator
1136
   * @param {Function} callback
1137
   * @example
1138
   *
1139
   * // array
1140
   * var order = [];
1141
   * var array = [1, 3, 2, 4];
1142
   * var iterator = function(num, done) {
1143
   *   setTimeout(function() {
1144
   *     order.push(num);
1145
   *     done(null, num % 2);
1146
   *   }, num * 10);
1147
   * };
1148
   * async.pick(array, iterator, function(err, res) {
1149
   *   console.log(res); // { '0': 1, '1': 3 }
1150
   *   console.log(order); // [1, 2, 3, 4]
1151
   * });
1152
   *
1153
   * @example
1154
   *
1155
   * // array with index
1156
   * var order = [];
1157
   * var array = [1, 3, 2, 4];
1158
   * var iterator = function(num, index, done) {
1159
   *   setTimeout(function() {
1160
   *     order.push([num, index]);
1161
   *     done(null, num % 2);
1162
   *   }, num * 10);
1163
   * };
1164
   * async.pick(array, iterator, function(err, res) {
1165
   *   console.log(res); // { '0': 1, '1': 3 }
1166
   *   console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]]
1167
   * });
1168
   *
1169
   * @example
1170
   *
1171
   * // object
1172
   * var order = [];
1173
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1174
   * var iterator = function(num, done) {
1175
   *   setTimeout(function() {
1176
   *     order.push(num);
1177
   *     done(null, num % 2);
1178
   *   }, num * 10);
1179
   * };
1180
   * async.pick(object, iterator, function(err, res) {
1181
   *   console.log(res); // { a: 1, b: 3 }
1182
   *   console.log(order); // [1, 2, 3, 4]
1183
   * });
1184
   *
1185
   * @example
1186
   *
1187
   * // object with key
1188
   * var order = [];
1189
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1190
   * var iterator = function(num, key, done) {
1191
   *   setTimeout(function() {
1192
   *     order.push([num, key]);
1193
   *     done(null, num % 2);
1194
   *   }, num * 10);
1195
   * };
1196
   * async.pick(object, iterator, function(err, res) {
1197
   *   console.log(res); // { a: 1, b: 3 }
1198
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
1199
   * });
1200
   *
1201
   */
1202
  var pick = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, true);
1203

    
1204
  /**
1205
   * @memberof async
1206
   * @namespace pickSeries
1207
   * @param {Array|Object} collection
1208
   * @param {Function} iterator
1209
   * @param {Function} callback
1210
   * @example
1211
   *
1212
   * // array
1213
   * var order = [];
1214
   * var array = [1, 3, 2, 4];
1215
   * var iterator = function(num, done) {
1216
   *   setTimeout(function() {
1217
   *     order.push(num);
1218
   *     done(null, num % 2);
1219
   *   }, num * 10);
1220
   * };
1221
   * async.pickSeries(array, iterator, function(err, res) {
1222
   *   console.log(res); // { '0': 1, '1': 3 }
1223
   *   console.log(order); // [1, 3, 2, 4]
1224
   * });
1225
   *
1226
   * @example
1227
   *
1228
   * // array with index
1229
   * var order = [];
1230
   * var array = [1, 3, 2, 4];
1231
   * var iterator = function(num, index, done) {
1232
   *   setTimeout(function() {
1233
   *     order.push([num, index]);
1234
   *     done(null, num % 2);
1235
   *   }, num * 10);
1236
   * };
1237
   * async.pickSeries(array, iterator, function(err, res) {
1238
   *   console.log(res); // { '0': 1, '1': 3 }
1239
   *   console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]]
1240
   * });
1241
   *
1242
   * @example
1243
   *
1244
   * // object
1245
   * var order = [];
1246
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1247
   * var iterator = function(num, done) {
1248
   *   setTimeout(function() {
1249
   *     order.push(num);
1250
   *     done(null, num % 2);
1251
   *   }, num * 10);
1252
   * };
1253
   * async.pickSeries(object, iterator, function(err, res) {
1254
   *   console.log(res); // { a: 1, b: 3 }
1255
   *   console.log(order); // [1, 3, 2, 4]
1256
   * });
1257
   *
1258
   * @example
1259
   *
1260
   * // object with key
1261
   * var order = [];
1262
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1263
   * var iterator = function(num, key, done) {
1264
   *   setTimeout(function() {
1265
   *     order.push([num, key]);
1266
   *     done(null, num % 2);
1267
   *   }, num * 10);
1268
   * };
1269
   * async.pickSeries(object, iterator, function(err, res) {
1270
   *   console.log(res); // { a: 1, b: 3 }
1271
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']]
1272
   * });
1273
   *
1274
   */
1275
  var pickSeries = createPickSeries(true);
1276

    
1277
  /**
1278
   * @memberof async
1279
   * @namespace pickLimit
1280
   * @param {Array|Object} collection
1281
   * @param {number} limit - limit >= 1
1282
   * @param {Function} iterator
1283
   * @param {Function} callback
1284
   * @example
1285
   *
1286
   * // array
1287
   * var order = [];
1288
   * var array = [1, 5, 3, 4, 2];
1289
   * var iterator = function(num, done) {
1290
   *   setTimeout(function() {
1291
   *     order.push(num);
1292
   *     done(null, num % 2);
1293
   *   }, num * 10);
1294
   * };
1295
   * async.pickLimit(array, 2, iterator, function(err, res) {
1296
   *   console.log(res); // { '0': 1, '1': 5, '2': 3 }
1297
   *   console.log(order); // [1, 3, 5, 2, 4]
1298
   * });
1299
   *
1300
   * @example
1301
   *
1302
   * // array with index
1303
   * var order = [];
1304
   * var array = [1, 5, 3, 4, 2];
1305
   * var iterator = function(num, index, done) {
1306
   *   setTimeout(function() {
1307
   *     order.push([num, index]);
1308
   *     done(null, num % 2);
1309
   *   }, num * 10);
1310
   * };
1311
   * async.pickLimit(array, 2, iterator, function(err, res) {
1312
   *   console.log(res); // { '0': 1, '1': 5, '2': 3 }
1313
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
1314
   * });
1315
   *
1316
   * @example
1317
   *
1318
   * // object
1319
   * var order = [];
1320
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1321
   * var iterator = function(num, done) {
1322
   *   setTimeout(function() {
1323
   *     order.push(num);
1324
   *     done(null, num % 2);
1325
   *   }, num * 10);
1326
   * };
1327
   * async.pickLimit(object, 2, iterator, function(err, res) {
1328
   *   console.log(res); // { a: 1, b: 5, c: 3 }
1329
   *   console.log(order); // [1, 3, 5, 2, 4]
1330
   * });
1331
   *
1332
   * @example
1333
   *
1334
   * // object with key
1335
   * var order = [];
1336
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1337
   * var iterator = function(num, key, done) {
1338
   *   setTimeout(function() {
1339
   *     order.push([num, key]);
1340
   *     done(null, num % 2);
1341
   *   }, num * 10);
1342
   * };
1343
   * async.pickLimit(object, 2, iterator, function(err, res) {
1344
   *   console.log(res); // { a: 1, b: 5, c: 3 }
1345
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
1346
   * });
1347
   *
1348
   */
1349
  var pickLimit = createPickLimit(true);
1350

    
1351
  /**
1352
   * @memberof async
1353
   * @namespace omit
1354
   * @param {Array|Object} collection
1355
   * @param {Function} iterator
1356
   * @param {Function} callback
1357
   * @example
1358
   *
1359
   * // array
1360
   * var order = [];
1361
   * var array = [1, 3, 2, 4];
1362
   * var iterator = function(num, done) {
1363
   *   setTimeout(function() {
1364
   *     order.push(num);
1365
   *     done(null, num % 2);
1366
   *   }, num * 10);
1367
   * };
1368
   * async.omit(array, iterator, function(err, res) {
1369
   *   console.log(res); // { '2': 2, '3': 4 }
1370
   *   console.log(order); // [1, 2, 3, 4]
1371
   * });
1372
   *
1373
   * @example
1374
   *
1375
   * // array with index
1376
   * var order = [];
1377
   * var array = [1, 3, 2, 4];
1378
   * var iterator = function(num, index, done) {
1379
   *   setTimeout(function() {
1380
   *     order.push([num, index]);
1381
   *     done(null, num % 2);
1382
   *   }, num * 10);
1383
   * };
1384
   * async.omit(array, iterator, function(err, res) {
1385
   *   console.log(res); // { '2': 2, '3': 4 }
1386
   *   console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]]
1387
   * });
1388
   *
1389
   * @example
1390
   *
1391
   * // object
1392
   * var order = [];
1393
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1394
   * var iterator = function(num, done) {
1395
   *   setTimeout(function() {
1396
   *     order.push(num);
1397
   *     done(null, num % 2);
1398
   *   }, num * 10);
1399
   * };
1400
   * async.omit(object, iterator, function(err, res) {
1401
   *   console.log(res); // { c: 2, d: 4 }
1402
   *   console.log(order); // [1, 2, 3, 4]
1403
   * });
1404
   *
1405
   * @example
1406
   *
1407
   * // object with key
1408
   * var order = [];
1409
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1410
   * var iterator = function(num, key, done) {
1411
   *   setTimeout(function() {
1412
   *     order.push([num, key]);
1413
   *     done(null, num % 2);
1414
   *   }, num * 10);
1415
   * };
1416
   * async.omit(object, iterator, function(err, res) {
1417
   *   console.log(res); // { c: 2, d: 4 }
1418
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
1419
   * });
1420
   *
1421
   */
1422
  var omit = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, false);
1423

    
1424
  /**
1425
   * @memberof async
1426
   * @namespace omitSeries
1427
   * @param {Array|Object} collection
1428
   * @param {Function} iterator
1429
   * @param {Function} callback
1430
   * @example
1431
   *
1432
   * // array
1433
   * var order = [];
1434
   * var array = [1, 3, 2, 4];
1435
   * var iterator = function(num, done) {
1436
   *   setTimeout(function() {
1437
   *     order.push(num);
1438
   *     done(null, num % 2);
1439
   *   }, num * 10);
1440
   * };
1441
   * async.omitSeries(array, iterator, function(err, res) {
1442
   *   console.log(res); // { '2': 2, '3': 4 }
1443
   *   console.log(order); // [1, 3, 2, 4]
1444
   * });
1445
   *
1446
   * @example
1447
   *
1448
   * // array with index
1449
   * var order = [];
1450
   * var array = [1, 3, 2, 4];
1451
   * var iterator = function(num, index, done) {
1452
   *   setTimeout(function() {
1453
   *     order.push([num, index]);
1454
   *     done(null, num % 2);
1455
   *   }, num * 10);
1456
   * };
1457
   * async.omitSeries(array, iterator, function(err, res) {
1458
   *   console.log(res); // { '2': 2, '3': 4 }
1459
   *   console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]]
1460
   * });
1461
   *
1462
   * @example
1463
   *
1464
   * // object
1465
   * var order = [];
1466
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1467
   * var iterator = function(num, done) {
1468
   *   setTimeout(function() {
1469
   *     order.push(num);
1470
   *     done(null, num % 2);
1471
   *   }, num * 10);
1472
   * };
1473
   * async.omitSeries(object, iterator, function(err, res) {
1474
   *   console.log(res); // { c: 2, d: 4 }
1475
   *   console.log(order); // [1, 3, 2, 4]
1476
   * });
1477
   *
1478
   * @example
1479
   *
1480
   * // object with key
1481
   * var order = [];
1482
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1483
   * var iterator = function(num, key, done) {
1484
   *   setTimeout(function() {
1485
   *     order.push([num, key]);
1486
   *     done(null, num % 2);
1487
   *   }, num * 10);
1488
   * };
1489
   * async.omitSeries(object, iterator, function(err, res) {
1490
   *   console.log(res); // { c: 2, d: 4 }
1491
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']]
1492
   * });
1493
   *
1494
   */
1495
  var omitSeries = createPickSeries(false);
1496

    
1497
  /**
1498
   * @memberof async
1499
   * @namespace omitLimit
1500
   * @param {Array|Object} collection
1501
   * @param {number} limit - limit >= 1
1502
   * @param {Function} iterator
1503
   * @param {Function} callback
1504
   * @example
1505
   *
1506
   * // array
1507
   * var order = [];
1508
   * var array = [1, 5, 3, 4, 2];
1509
   * var iterator = function(num, done) {
1510
   *   setTimeout(function() {
1511
   *     order.push(num);
1512
   *     done(null, num % 2);
1513
   *   }, num * 10);
1514
   * };
1515
   * async.omitLimit(array, 2, iterator, function(err, res) {
1516
   *   console.log(res); // { '3': 4, '4': 2 }
1517
   *   console.log(order); // [1, 3, 5, 2, 4]
1518
   * });
1519
   *
1520
   * @example
1521
   *
1522
   * // array with index
1523
   * var order = [];
1524
   * var array = [1, 5, 3, 4, 2];
1525
   * var iterator = function(num, index, done) {
1526
   *   setTimeout(function() {
1527
   *     order.push([num, index]);
1528
   *     done(null, num % 2);
1529
   *   }, num * 10);
1530
   * };
1531
   * async.omitLimit(array, 2, iterator, function(err, res) {
1532
   *   console.log(res); // { '3': 4, '4': 2 }
1533
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
1534
   * });
1535
   *
1536
   * @example
1537
   *
1538
   * // object
1539
   * var order = [];
1540
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1541
   * var iterator = function(num, done) {
1542
   *   setTimeout(function() {
1543
   *     order.push(num);
1544
   *     done(null, num % 2);
1545
   *   }, num * 10);
1546
   * };
1547
   * async.omitLimit(object, 2, iterator, function(err, res) {
1548
   *   console.log(res); // { d: 4, e: 2 }
1549
   *   console.log(order); // [1, 3, 5, 2, 4]
1550
   * });
1551
   *
1552
   * @example
1553
   *
1554
   * // object with key
1555
   * var order = [];
1556
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1557
   * var iterator = function(num, key, done) {
1558
   *   setTimeout(function() {
1559
   *     order.push([num, key]);
1560
   *     done(null, num % 2);
1561
   *   }, num * 10);
1562
   * };
1563
   * async.omitLimit(object, 2, iterator, function(err, res) {
1564
   *   console.log(res); // { d: 4, e: 2 }
1565
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
1566
   * });
1567
   *
1568
   */
1569
  var omitLimit = createPickLimit(false);
1570

    
1571
  /**
1572
   * @memberof async
1573
   * @namespace transform
1574
   * @param {Array|Object} collection
1575
   * @param {Array|Object|Function} [accumulator]
1576
   * @param {Function} [iterator]
1577
   * @param {Function} [callback]
1578
   * @example
1579
   *
1580
   * // array
1581
   * var order = [];
1582
   * var collection = [1, 3, 2, 4];
1583
   * var iterator = function(result, num, done) {
1584
   *   setTimeout(function() {
1585
   *     order.push(num);
1586
   *     result.push(num)
1587
   *     done();
1588
   *   }, num * 10);
1589
   * };
1590
   * async.transform(collection, iterator, function(err, res) {
1591
   *   console.log(res); // [1, 2, 3, 4]
1592
   *   console.log(order); // [1, 2, 3, 4]
1593
   * });
1594
   *
1595
   * @example
1596
   *
1597
   * // array with index and accumulator
1598
   * var order = [];
1599
   * var collection = [1, 3, 2, 4];
1600
   * var iterator = function(result, num, index, done) {
1601
   *   setTimeout(function() {
1602
   *     order.push([num, index]);
1603
   *     result[index] = num;
1604
   *     done();
1605
   *   }, num * 10);
1606
   * };
1607
   * async.transform(collection, {}, iterator, function(err, res) {
1608
   *   console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 }
1609
   *   console.log(order); // [[1, 0], [2, 2], [3, 1], [4, 3]]
1610
   * });
1611
   *
1612
   * @example
1613
   *
1614
   * // object with accumulator
1615
   * var order = [];
1616
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1617
   * var iterator = function(result, num, done) {
1618
   *   setTimeout(function() {
1619
   *     order.push(num);
1620
   *     result.push(num);
1621
   *     done();
1622
   *   }, num * 10);
1623
   * };
1624
   * async.transform(collection, [], iterator, function(err, res) {
1625
   *   console.log(res); // [1, 2, 3, 4]
1626
   *   console.log(order); // [1, 2, 3, 4]
1627
   * });
1628
   *
1629
   * @example
1630
   *
1631
   * // object with key
1632
   * var order = [];
1633
   * var object = { a: 1, b: 3, c: 2, d: 4 };
1634
   * var iterator = function(result, num, key, done) {
1635
   *   setTimeout(function() {
1636
   *     order.push([num, key]);
1637
   *     result[key] = num;
1638
   *     done();
1639
   *   }, num * 10);
1640
   * };
1641
   * async.transform(collection, iterator, function(err, res) {
1642
   *   console.log(res); //  { a: 1, b: 3, c: 2, d: 4 }
1643
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
1644
   * });
1645
   *
1646
   */
1647
  var transform = createTransform(arrayEachResult, baseEachResult, symbolEachResult);
1648

    
1649
  /**
1650
   * @memberof async
1651
   * @namespace sortBy
1652
   * @param {Array|Object} collection
1653
   * @param {Function} iterator
1654
   * @param {Function} callback
1655
   * @example
1656
   *
1657
   * // array
1658
   * var order = [];
1659
   * var array = [1, 3, 2];
1660
   * var iterator = function(num, done) {
1661
   *   setTimeout(function() {
1662
   *     order.push(num);
1663
   *     done(null, num);
1664
   *   }, num * 10);
1665
   * };
1666
   * async.sortBy(array, iterator, function(err, res) {
1667
   *   console.log(res); // [1, 2, 3];
1668
   *   console.log(order); // [1, 2, 3]
1669
   * });
1670
   *
1671
   * @example
1672
   *
1673
   * // array with index
1674
   * var order = [];
1675
   * var array = [1, 3, 2];
1676
   * var iterator = function(num, index, done) {
1677
   *   setTimeout(function() {
1678
   *     order.push([num, index]);
1679
   *     done(null, num);
1680
   *   }, num * 10);
1681
   * };
1682
   * async.sortBy(array, iterator, function(err, res) {
1683
   *   console.log(res); // [1, 2, 3]
1684
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
1685
   * });
1686
   *
1687
   * @example
1688
   *
1689
   * // object
1690
   * var order = [];
1691
   * var object = { a: 1, b: 3, c: 2 };
1692
   * var iterator = function(num, done) {
1693
   *   setTimeout(function() {
1694
   *     order.push(num);
1695
   *     done(null, num);
1696
   *   }, num * 10);
1697
   * };
1698
   * async.sortBy(object, iterator, function(err, res) {
1699
   *   console.log(res); // [1, 2, 3]
1700
   *   console.log(order); // [1, 2, 3]
1701
   * });
1702
   *
1703
   * @example
1704
   *
1705
   * // object with key
1706
   * var order = [];
1707
   * var object = { a: 1, b: 3, c: 2 };
1708
   * var iterator = function(num, key, done) {
1709
   *   setTimeout(function() {
1710
   *     order.push([num, key]);
1711
   *     done(null, num);
1712
   *   }, num * 10);
1713
   * };
1714
   * async.sortBy(object, iterator, function(err, res) {
1715
   *   console.log(res); // [1, 2, 3]
1716
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
1717
   * });
1718
   *
1719
   */
1720
  var sortBy = createSortBy(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue);
1721

    
1722
  /**
1723
   * @memberof async
1724
   * @namespace concat
1725
   * @param {Array|Object} collection
1726
   * @param {Function} iterator
1727
   * @param {Function} callback
1728
   * @example
1729
   *
1730
   * // array
1731
   * var order = [];
1732
   * var array = [1, 3, 2];
1733
   * var iterator = function(num, done) {
1734
   *   setTimeout(function() {
1735
   *     order.push(num);
1736
   *     done(null, [num]);
1737
   *   }, num * 10);
1738
   * };
1739
   * async.concat(array, iterator, function(err, res) {
1740
   *   console.log(res); // [1, 2, 3];
1741
   *   console.log(order); // [1, 2, 3]
1742
   * });
1743
   *
1744
   * @example
1745
   *
1746
   * // array with index
1747
   * var order = [];
1748
   * var array = [1, 3, 2];
1749
   * var iterator = function(num, index, done) {
1750
   *   setTimeout(function() {
1751
   *     order.push([num, index]);
1752
   *     done(null, [num]);
1753
   *   }, num * 10);
1754
   * };
1755
   * async.concat(array, iterator, function(err, res) {
1756
   *   console.log(res); // [1, 2, 3]
1757
   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
1758
   * });
1759
   *
1760
   * @example
1761
   *
1762
   * // object
1763
   * var order = [];
1764
   * var object = { a: 1, b: 3, c: 2 };
1765
   * var iterator = function(num, done) {
1766
   *   setTimeout(function() {
1767
   *     order.push(num);
1768
   *     done(null, [num]);
1769
   *   }, num * 10);
1770
   * };
1771
   * async.concat(object, iterator, function(err, res) {
1772
   *   console.log(res); // [1, 2, 3]
1773
   *   console.log(order); // [1, 2, 3]
1774
   * });
1775
   *
1776
   * @example
1777
   *
1778
   * // object with key
1779
   * var order = [];
1780
   * var object = { a: 1, b: 3, c: 2 };
1781
   * var iterator = function(num, key, done) {
1782
   *   setTimeout(function() {
1783
   *     order.push([num, key]);
1784
   *     done(null, [num]);
1785
   *   }, num * 10);
1786
   * };
1787
   * async.concat(object, iterator, function(err, res) {
1788
   *   console.log(res); // [1, 2, 3]
1789
   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
1790
   * });
1791
   *
1792
   */
1793
  var concat = createConcat(arrayEachIndex, baseEachIndex, symbolEachIndex);
1794

    
1795
  /**
1796
   * @memberof async
1797
   * @namespace groupBy
1798
   * @param {Array|Object} collection
1799
   * @param {Function} iterator
1800
   * @param {Function} callback
1801
   * @example
1802
   *
1803
   * // array
1804
   * var order = [];
1805
   * var array = [4.2, 6.4, 6.1];
1806
   * var iterator = function(num, done) {
1807
   *   setTimeout(function() {
1808
   *     order.push(num);
1809
   *     done(null, Math.floor(num));
1810
   *   }, num * 10);
1811
   * };
1812
   * async.groupBy(array, iterator, function(err, res) {
1813
   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1814
   *   console.log(order); // [4.2, 6.1, 6.4]
1815
   * });
1816
   *
1817
   * @example
1818
   *
1819
   * // array with index
1820
   * var order = [];
1821
   * var array = [4.2, 6.4, 6.1];
1822
   * var iterator = function(num, index, done) {
1823
   *   setTimeout(function() {
1824
   *     order.push([num, index]);
1825
   *     done(null, Math.floor(num));
1826
   *   }, num * 10);
1827
   * };
1828
   * async.groupBy(array, iterator, function(err, res) {
1829
   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1830
   *   console.log(order); // [[4.2, 0], [6.1, 2], [6.4, 1]]
1831
   * });
1832
   *
1833
   * @example
1834
   *
1835
   * // object
1836
   * var order = [];
1837
   * var object = { a: 4.2, b: 6.4, c: 6.1 };
1838
   * var iterator = function(num, done) {
1839
   *   setTimeout(function() {
1840
   *     order.push(num);
1841
   *     done(null, Math.floor(num));
1842
   *   }, num * 10);
1843
   * };
1844
   * async.groupBy(object, iterator, function(err, res) {
1845
   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1846
   *   console.log(order); // [4.2, 6.1, 6.4]
1847
   * });
1848
   *
1849
   * @example
1850
   *
1851
   * // object with key
1852
   * var order = [];
1853
   * var object = { a: 4.2, b: 6.4, c: 6.1 };
1854
   * var iterator = function(num, key, done) {
1855
   *   setTimeout(function() {
1856
   *     order.push([num, key]);
1857
   *     done(null, Math.floor(num));
1858
   *   }, num * 10);
1859
   * };
1860
   * async.groupBy(object, iterator, function(err, res) {
1861
   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1862
   *   console.log(order); // [[4.2, 'a'], [6.1, 'c'], [6.4, 'b']]
1863
   * });
1864
   *
1865
   */
1866
  var groupBy = createGroupBy(arrayEachValue, baseEachValue, symbolEachValue);
1867

    
1868
  /**
1869
   * @memberof async
1870
   * @namespace parallel
1871
   * @param {Array|Object} tasks - functions
1872
   * @param {Function} callback
1873
   * @example
1874
   *
1875
   * var order = [];
1876
   * var tasks = [
1877
   *  function(done) {
1878
   *    setTimeout(function() {
1879
   *      order.push(1);
1880
   *      done(null, 1);
1881
   *    }, 10);
1882
   *  },
1883
   *  function(done) {
1884
   *    setTimeout(function() {
1885
   *      order.push(2);
1886
   *      done(null, 2);
1887
   *    }, 30);
1888
   *  },
1889
   *  function(done) {
1890
   *    setTimeout(function() {
1891
   *      order.push(3);
1892
   *      done(null, 3);
1893
   *    }, 40);
1894
   *  },
1895
   *  function(done) {
1896
   *    setTimeout(function() {
1897
   *      order.push(4);
1898
   *      done(null, 4);
1899
   *    }, 20);
1900
   *  }
1901
   * ];
1902
   * async.parallel(tasks, function(err, res) {
1903
   *   console.log(res); // [1, 2, 3, 4];
1904
   *   console.log(order); // [1, 4, 2, 3]
1905
   * });
1906
   *
1907
   * @example
1908
   *
1909
   * var order = [];
1910
   * var tasks = {
1911
   *   'a': function(done) {
1912
   *     setTimeout(function() {
1913
   *       order.push(1);
1914
   *       done(null, 1);
1915
   *     }, 10);
1916
   *   },
1917
   *   'b': function(done) {
1918
   *     setTimeout(function() {
1919
   *       order.push(2);
1920
   *       done(null, 2);
1921
   *     }, 30);
1922
   *   },
1923
   *   'c': function(done) {
1924
   *     setTimeout(function() {
1925
   *       order.push(3);
1926
   *       done(null, 3);
1927
   *     }, 40);
1928
   *   },
1929
   *   'd': function(done) {
1930
   *     setTimeout(function() {
1931
   *       order.push(4);
1932
   *       done(null, 4);
1933
   *     }, 20);
1934
   *   }
1935
   * };
1936
   * async.parallel(tasks, function(err, res) {
1937
   *   console.log(res); // { a: 1, b: 2, c: 3, d:4 }
1938
   *   console.log(order); // [1, 4, 2, 3]
1939
   * });
1940
   *
1941
   */
1942
  var parallel = createParallel(arrayEachFunc, baseEachFunc);
1943

    
1944
  /**
1945
   * @memberof async
1946
   * @namespace applyEach
1947
   */
1948
  var applyEach = createApplyEach(map);
1949

    
1950
  /**
1951
   * @memberof async
1952
   * @namespace applyEachSeries
1953
   */
1954
  var applyEachSeries = createApplyEach(mapSeries);
1955

    
1956
  /**
1957
   * @memberof async
1958
   * @namespace log
1959
   */
1960
  var log = createLogger('log');
1961

    
1962
  /**
1963
   * @memberof async
1964
   * @namespace dir
1965
   */
1966
  var dir = createLogger('dir');
1967

    
1968
  /**
1969
   * @version 2.6.1
1970
   * @namespace async
1971
   */
1972
  var index = {
1973
    VERSION: '2.6.1',
1974

    
1975
    // Collections
1976
    each: each,
1977
    eachSeries: eachSeries,
1978
    eachLimit: eachLimit,
1979
    forEach: each,
1980
    forEachSeries: eachSeries,
1981
    forEachLimit: eachLimit,
1982
    eachOf: each,
1983
    eachOfSeries: eachSeries,
1984
    eachOfLimit: eachLimit,
1985
    forEachOf: each,
1986
    forEachOfSeries: eachSeries,
1987
    forEachOfLimit: eachLimit,
1988
    map: map,
1989
    mapSeries: mapSeries,
1990
    mapLimit: mapLimit,
1991
    mapValues: mapValues,
1992
    mapValuesSeries: mapValuesSeries,
1993
    mapValuesLimit: mapValuesLimit,
1994
    filter: filter,
1995
    filterSeries: filterSeries,
1996
    filterLimit: filterLimit,
1997
    select: filter,
1998
    selectSeries: filterSeries,
1999
    selectLimit: filterLimit,
2000
    reject: reject,
2001
    rejectSeries: rejectSeries,
2002
    rejectLimit: rejectLimit,
2003
    detect: detect,
2004
    detectSeries: detectSeries,
2005
    detectLimit: detectLimit,
2006
    find: detect,
2007
    findSeries: detectSeries,
2008
    findLimit: detectLimit,
2009
    pick: pick,
2010
    pickSeries: pickSeries,
2011
    pickLimit: pickLimit,
2012
    omit: omit,
2013
    omitSeries: omitSeries,
2014
    omitLimit: omitLimit,
2015
    reduce: reduce,
2016
    inject: reduce,
2017
    foldl: reduce,
2018
    reduceRight: reduceRight,
2019
    foldr: reduceRight,
2020
    transform: transform,
2021
    transformSeries: transformSeries,
2022
    transformLimit: transformLimit,
2023
    sortBy: sortBy,
2024
    sortBySeries: sortBySeries,
2025
    sortByLimit: sortByLimit,
2026
    some: some,
2027
    someSeries: someSeries,
2028
    someLimit: someLimit,
2029
    any: some,
2030
    anySeries: someSeries,
2031
    anyLimit: someLimit,
2032
    every: every,
2033
    everySeries: everySeries,
2034
    everyLimit: everyLimit,
2035
    all: every,
2036
    allSeries: everySeries,
2037
    allLimit: everyLimit,
2038
    concat: concat,
2039
    concatSeries: concatSeries,
2040
    concatLimit: concatLimit,
2041
    groupBy: groupBy,
2042
    groupBySeries: groupBySeries,
2043
    groupByLimit: groupByLimit,
2044

    
2045
    // Control Flow
2046
    parallel: parallel,
2047
    series: series,
2048
    parallelLimit: parallelLimit,
2049
    tryEach: tryEach,
2050
    waterfall: waterfall,
2051
    angelFall: angelFall,
2052
    angelfall: angelFall,
2053
    whilst: whilst,
2054
    doWhilst: doWhilst,
2055
    until: until,
2056
    doUntil: doUntil,
2057
    during: during,
2058
    doDuring: doDuring,
2059
    forever: forever,
2060
    compose: compose,
2061
    seq: seq,
2062
    applyEach: applyEach,
2063
    applyEachSeries: applyEachSeries,
2064
    queue: queue,
2065
    priorityQueue: priorityQueue,
2066
    cargo: cargo,
2067
    auto: auto,
2068
    autoInject: autoInject,
2069
    retry: retry,
2070
    retryable: retryable,
2071
    iterator: iterator,
2072
    times: times,
2073
    timesSeries: timesSeries,
2074
    timesLimit: timesLimit,
2075
    race: race,
2076

    
2077
    // Utils
2078
    apply: apply,
2079
    nextTick: asyncNextTick,
2080
    setImmediate: asyncSetImmediate,
2081
    memoize: memoize,
2082
    unmemoize: unmemoize,
2083
    ensureAsync: ensureAsync,
2084
    constant: constant,
2085
    asyncify: asyncify,
2086
    wrapSync: asyncify,
2087
    log: log,
2088
    dir: dir,
2089
    reflect: reflect,
2090
    reflectAll: reflectAll,
2091
    timeout: timeout,
2092
    createLogger: createLogger,
2093

    
2094
    // Mode
2095
    safe: safe,
2096
    fast: fast
2097
  };
2098

    
2099
  exports['default'] = index;
2100
  baseEachSync(
2101
    index,
2102
    function(func, key) {
2103
      exports[key] = func;
2104
    },
2105
    nativeKeys(index)
2106
  );
2107

    
2108
  /**
2109
   * @private
2110
   */
2111
  function createImmediate(safeMode) {
2112
    var delay = function delay(fn) {
2113
      var args = slice(arguments, 1);
2114
      setTimeout(function() {
2115
        fn.apply(null, args);
2116
      });
2117
    };
2118
    asyncSetImmediate = typeof setImmediate === func ? setImmediate : delay;
2119
    if (typeof process === obj && typeof process.nextTick === func) {
2120
      nextTick = /^v0.10/.test(process.version) ? asyncSetImmediate : process.nextTick;
2121
      asyncNextTick = /^v0/.test(process.version) ? asyncSetImmediate : process.nextTick;
2122
    } else {
2123
      asyncNextTick = nextTick = asyncSetImmediate;
2124
    }
2125
    if (safeMode === false) {
2126
      nextTick = function(cb) {
2127
        cb();
2128
      };
2129
    }
2130
  }
2131

    
2132
  /* sync functions based on lodash */
2133

    
2134
  /**
2135
   * Converts `arguments` to an array.
2136
   *
2137
   * @private
2138
   * @param {Array} array = The array to slice.
2139
   */
2140
  function createArray(array) {
2141
    var index = -1;
2142
    var size = array.length;
2143
    var result = Array(size);
2144

    
2145
    while (++index < size) {
2146
      result[index] = array[index];
2147
    }
2148
    return result;
2149
  }
2150

    
2151
  /**
2152
   * Create an array from `start`
2153
   *
2154
   * @private
2155
   * @param {Array} array - The array to slice.
2156
   * @param {number} start - The start position.
2157
   */
2158
  function slice(array, start) {
2159
    var end = array.length;
2160
    var index = -1;
2161
    var size = end - start;
2162
    if (size <= 0) {
2163
      return [];
2164
    }
2165
    var result = Array(size);
2166

    
2167
    while (++index < size) {
2168
      result[index] = array[index + start];
2169
    }
2170
    return result;
2171
  }
2172

    
2173
  /**
2174
   * @private
2175
   * @param {Object} object
2176
   */
2177
  function objectClone(object) {
2178
    var keys = nativeKeys(object);
2179
    var size = keys.length;
2180
    var index = -1;
2181
    var result = {};
2182

    
2183
    while (++index < size) {
2184
      var key = keys[index];
2185
      result[key] = object[key];
2186
    }
2187
    return result;
2188
  }
2189

    
2190
  /**
2191
   * Create an array with all falsey values removed.
2192
   *
2193
   * @private
2194
   * @param {Array} array - The array to compact.
2195
   */
2196
  function compact(array) {
2197
    var index = -1;
2198
    var size = array.length;
2199
    var result = [];
2200

    
2201
    while (++index < size) {
2202
      var value = array[index];
2203
      if (value) {
2204
        result[result.length] = value;
2205
      }
2206
    }
2207
    return result;
2208
  }
2209

    
2210
  /**
2211
   * Create an array of reverse sequence.
2212
   *
2213
   * @private
2214
   * @param {Array} array - The array to reverse.
2215
   */
2216
  function reverse(array) {
2217
    var index = -1;
2218
    var size = array.length;
2219
    var result = Array(size);
2220
    var resIndex = size;
2221

    
2222
    while (++index < size) {
2223
      result[--resIndex] = array[index];
2224
    }
2225
    return result;
2226
  }
2227

    
2228
  /**
2229
   * Checks if key exists in object property.
2230
   *
2231
   * @private
2232
   * @param {Object} object - The object to inspect.
2233
   * @param {string} key - The key to check.
2234
   */
2235
  function has(object, key) {
2236
    return object.hasOwnProperty(key);
2237
  }
2238

    
2239
  /**
2240
   * Check if target exists in array.
2241
   * @private
2242
   * @param {Array} array
2243
   * @param {*} target
2244
   */
2245
  function notInclude(array, target) {
2246
    var index = -1;
2247
    var size = array.length;
2248

    
2249
    while (++index < size) {
2250
      if (array[index] === target) {
2251
        return false;
2252
      }
2253
    }
2254
    return true;
2255
  }
2256

    
2257
  /**
2258
   * @private
2259
   * @param {Array} array - The array to iterate over.
2260
   * @param {Function} iterator - The function invoked per iteration.
2261
   */
2262
  function arrayEachSync(array, iterator) {
2263
    var index = -1;
2264
    var size = array.length;
2265

    
2266
    while (++index < size) {
2267
      iterator(array[index], index);
2268
    }
2269
    return array;
2270
  }
2271

    
2272
  /**
2273
   * @private
2274
   * @param {Object} object - The object to iterate over.
2275
   * @param {Function} iterator - The function invoked per iteration.
2276
   * @param {Array} keys
2277
   */
2278
  function baseEachSync(object, iterator, keys) {
2279
    var index = -1;
2280
    var size = keys.length;
2281

    
2282
    while (++index < size) {
2283
      var key = keys[index];
2284
      iterator(object[key], key);
2285
    }
2286
    return object;
2287
  }
2288

    
2289
  /**
2290
   * @private
2291
   * @param {number} n
2292
   * @param {Function} iterator
2293
   */
2294
  function timesSync(n, iterator) {
2295
    var index = -1;
2296
    while (++index < n) {
2297
      iterator(index);
2298
    }
2299
  }
2300

    
2301
  /**
2302
   * @private
2303
   * @param {Array} array
2304
   * @param {number[]} criteria
2305
   */
2306
  function sortByCriteria(array, criteria) {
2307
    var l = array.length;
2308
    var indices = Array(l);
2309
    var i;
2310
    for (i = 0; i < l; i++) {
2311
      indices[i] = i;
2312
    }
2313
    quickSort(criteria, 0, l - 1, indices);
2314
    var result = Array(l);
2315
    for (var n = 0; n < l; n++) {
2316
      i = indices[n];
2317
      result[n] = i === undefined ? array[n] : array[i];
2318
    }
2319
    return result;
2320
  }
2321

    
2322
  function partition(array, i, j, mid, indices) {
2323
    var l = i;
2324
    var r = j;
2325
    while (l <= r) {
2326
      i = l;
2327
      while (l < r && array[l] < mid) {
2328
        l++;
2329
      }
2330
      while (r >= i && array[r] >= mid) {
2331
        r--;
2332
      }
2333
      if (l > r) {
2334
        break;
2335
      }
2336
      swap(array, indices, l++, r--);
2337
    }
2338
    return l;
2339
  }
2340

    
2341
  function swap(array, indices, l, r) {
2342
    var n = array[l];
2343
    array[l] = array[r];
2344
    array[r] = n;
2345
    var i = indices[l];
2346
    indices[l] = indices[r];
2347
    indices[r] = i;
2348
  }
2349

    
2350
  function quickSort(array, i, j, indices) {
2351
    if (i === j) {
2352
      return;
2353
    }
2354
    var k = i;
2355
    while (++k <= j && array[i] === array[k]) {
2356
      var l = k - 1;
2357
      if (indices[l] > indices[k]) {
2358
        var index = indices[l];
2359
        indices[l] = indices[k];
2360
        indices[k] = index;
2361
      }
2362
    }
2363
    if (k > j) {
2364
      return;
2365
    }
2366
    var p = array[i] > array[k] ? i : k;
2367
    k = partition(array, i, j, array[p], indices);
2368
    quickSort(array, i, k - 1, indices);
2369
    quickSort(array, k, j, indices);
2370
  }
2371

    
2372
  /**
2373
   * @Private
2374
   */
2375
  function makeConcatResult(array) {
2376
    var result = [];
2377
    arrayEachSync(array, function(value) {
2378
      if (value === noop) {
2379
        return;
2380
      }
2381
      if (isArray(value)) {
2382
        nativePush.apply(result, value);
2383
      } else {
2384
        result.push(value);
2385
      }
2386
    });
2387
    return result;
2388
  }
2389

    
2390
  /* async functions */
2391

    
2392
  /**
2393
   * @private
2394
   */
2395
  function arrayEach(array, iterator, callback) {
2396
    var index = -1;
2397
    var size = array.length;
2398

    
2399
    if (iterator.length === 3) {
2400
      while (++index < size) {
2401
        iterator(array[index], index, onlyOnce(callback));
2402
      }
2403
    } else {
2404
      while (++index < size) {
2405
        iterator(array[index], onlyOnce(callback));
2406
      }
2407
    }
2408
  }
2409

    
2410
  /**
2411
   * @private
2412
   */
2413
  function baseEach(object, iterator, callback, keys) {
2414
    var key;
2415
    var index = -1;
2416
    var size = keys.length;
2417

    
2418
    if (iterator.length === 3) {
2419
      while (++index < size) {
2420
        key = keys[index];
2421
        iterator(object[key], key, onlyOnce(callback));
2422
      }
2423
    } else {
2424
      while (++index < size) {
2425
        iterator(object[keys[index]], onlyOnce(callback));
2426
      }
2427
    }
2428
  }
2429

    
2430
  /**
2431
   * @private
2432
   */
2433
  function symbolEach(collection, iterator, callback) {
2434
    var iter = collection[iteratorSymbol]();
2435
    var index = 0;
2436
    var item;
2437
    if (iterator.length === 3) {
2438
      while ((item = iter.next()).done === false) {
2439
        iterator(item.value, index++, onlyOnce(callback));
2440
      }
2441
    } else {
2442
      while ((item = iter.next()).done === false) {
2443
        index++;
2444
        iterator(item.value, onlyOnce(callback));
2445
      }
2446
    }
2447
    return index;
2448
  }
2449

    
2450
  /**
2451
   * @private
2452
   */
2453
  function arrayEachResult(array, result, iterator, callback) {
2454
    var index = -1;
2455
    var size = array.length;
2456

    
2457
    if (iterator.length === 4) {
2458
      while (++index < size) {
2459
        iterator(result, array[index], index, onlyOnce(callback));
2460
      }
2461
    } else {
2462
      while (++index < size) {
2463
        iterator(result, array[index], onlyOnce(callback));
2464
      }
2465
    }
2466
  }
2467

    
2468
  /**
2469
   * @private
2470
   */
2471
  function baseEachResult(object, result, iterator, callback, keys) {
2472
    var key;
2473
    var index = -1;
2474
    var size = keys.length;
2475

    
2476
    if (iterator.length === 4) {
2477
      while (++index < size) {
2478
        key = keys[index];
2479
        iterator(result, object[key], key, onlyOnce(callback));
2480
      }
2481
    } else {
2482
      while (++index < size) {
2483
        iterator(result, object[keys[index]], onlyOnce(callback));
2484
      }
2485
    }
2486
  }
2487

    
2488
  /**
2489
   * @private
2490
   */
2491
  function symbolEachResult(collection, result, iterator, callback) {
2492
    var item;
2493
    var index = 0;
2494
    var iter = collection[iteratorSymbol]();
2495

    
2496
    if (iterator.length === 4) {
2497
      while ((item = iter.next()).done === false) {
2498
        iterator(result, item.value, index++, onlyOnce(callback));
2499
      }
2500
    } else {
2501
      while ((item = iter.next()).done === false) {
2502
        index++;
2503
        iterator(result, item.value, onlyOnce(callback));
2504
      }
2505
    }
2506
    return index;
2507
  }
2508

    
2509
  /**
2510
   * @private
2511
   */
2512
  function arrayEachFunc(array, createCallback) {
2513
    var index = -1;
2514
    var size = array.length;
2515

    
2516
    while (++index < size) {
2517
      array[index](createCallback(index));
2518
    }
2519
  }
2520

    
2521
  /**
2522
   * @private
2523
   */
2524
  function baseEachFunc(object, createCallback, keys) {
2525
    var key;
2526
    var index = -1;
2527
    var size = keys.length;
2528

    
2529
    while (++index < size) {
2530
      key = keys[index];
2531
      object[key](createCallback(key));
2532
    }
2533
  }
2534

    
2535
  /**
2536
   * @private
2537
   */
2538
  function arrayEachIndex(array, iterator, createCallback) {
2539
    var index = -1;
2540
    var size = array.length;
2541

    
2542
    if (iterator.length === 3) {
2543
      while (++index < size) {
2544
        iterator(array[index], index, createCallback(index));
2545
      }
2546
    } else {
2547
      while (++index < size) {
2548
        iterator(array[index], createCallback(index));
2549
      }
2550
    }
2551
  }
2552

    
2553
  /**
2554
   * @private
2555
   */
2556
  function baseEachIndex(object, iterator, createCallback, keys) {
2557
    var key;
2558
    var index = -1;
2559
    var size = keys.length;
2560

    
2561
    if (iterator.length === 3) {
2562
      while (++index < size) {
2563
        key = keys[index];
2564
        iterator(object[key], key, createCallback(index));
2565
      }
2566
    } else {
2567
      while (++index < size) {
2568
        iterator(object[keys[index]], createCallback(index));
2569
      }
2570
    }
2571
  }
2572

    
2573
  /**
2574
   * @private
2575
   */
2576
  function symbolEachIndex(collection, iterator, createCallback) {
2577
    var item;
2578
    var index = 0;
2579
    var iter = collection[iteratorSymbol]();
2580

    
2581
    if (iterator.length === 3) {
2582
      while ((item = iter.next()).done === false) {
2583
        iterator(item.value, index, createCallback(index++));
2584
      }
2585
    } else {
2586
      while ((item = iter.next()).done === false) {
2587
        iterator(item.value, createCallback(index++));
2588
      }
2589
    }
2590
    return index;
2591
  }
2592

    
2593
  /**
2594
   * @private
2595
   */
2596
  function baseEachKey(object, iterator, createCallback, keys) {
2597
    var key;
2598
    var index = -1;
2599
    var size = keys.length;
2600

    
2601
    if (iterator.length === 3) {
2602
      while (++index < size) {
2603
        key = keys[index];
2604
        iterator(object[key], key, createCallback(key));
2605
      }
2606
    } else {
2607
      while (++index < size) {
2608
        key = keys[index];
2609
        iterator(object[key], createCallback(key));
2610
      }
2611
    }
2612
  }
2613

    
2614
  /**
2615
   * @private
2616
   */
2617
  function symbolEachKey(collection, iterator, createCallback) {
2618
    var item;
2619
    var index = 0;
2620
    var iter = collection[iteratorSymbol]();
2621

    
2622
    if (iterator.length === 3) {
2623
      while ((item = iter.next()).done === false) {
2624
        iterator(item.value, index, createCallback(index++));
2625
      }
2626
    } else {
2627
      while ((item = iter.next()).done === false) {
2628
        iterator(item.value, createCallback(index++));
2629
      }
2630
    }
2631
    return index;
2632
  }
2633

    
2634
  /**
2635
   * @private
2636
   */
2637
  function arrayEachValue(array, iterator, createCallback) {
2638
    var value;
2639
    var index = -1;
2640
    var size = array.length;
2641

    
2642
    if (iterator.length === 3) {
2643
      while (++index < size) {
2644
        value = array[index];
2645
        iterator(value, index, createCallback(value));
2646
      }
2647
    } else {
2648
      while (++index < size) {
2649
        value = array[index];
2650
        iterator(value, createCallback(value));
2651
      }
2652
    }
2653
  }
2654

    
2655
  /**
2656
   * @private
2657
   */
2658
  function baseEachValue(object, iterator, createCallback, keys) {
2659
    var key, value;
2660
    var index = -1;
2661
    var size = keys.length;
2662

    
2663
    if (iterator.length === 3) {
2664
      while (++index < size) {
2665
        key = keys[index];
2666
        value = object[key];
2667
        iterator(value, key, createCallback(value));
2668
      }
2669
    } else {
2670
      while (++index < size) {
2671
        value = object[keys[index]];
2672
        iterator(value, createCallback(value));
2673
      }
2674
    }
2675
  }
2676

    
2677
  /**
2678
   * @private
2679
   */
2680
  function symbolEachValue(collection, iterator, createCallback) {
2681
    var value, item;
2682
    var index = 0;
2683
    var iter = collection[iteratorSymbol]();
2684

    
2685
    if (iterator.length === 3) {
2686
      while ((item = iter.next()).done === false) {
2687
        value = item.value;
2688
        iterator(value, index++, createCallback(value));
2689
      }
2690
    } else {
2691
      while ((item = iter.next()).done === false) {
2692
        index++;
2693
        value = item.value;
2694
        iterator(value, createCallback(value));
2695
      }
2696
    }
2697
    return index;
2698
  }
2699

    
2700
  /**
2701
   * @private
2702
   */
2703
  function arrayEachIndexValue(array, iterator, createCallback) {
2704
    var value;
2705
    var index = -1;
2706
    var size = array.length;
2707

    
2708
    if (iterator.length === 3) {
2709
      while (++index < size) {
2710
        value = array[index];
2711
        iterator(value, index, createCallback(index, value));
2712
      }
2713
    } else {
2714
      while (++index < size) {
2715
        value = array[index];
2716
        iterator(value, createCallback(index, value));
2717
      }
2718
    }
2719
  }
2720

    
2721
  /**
2722
   * @private
2723
   */
2724
  function baseEachIndexValue(object, iterator, createCallback, keys) {
2725
    var key, value;
2726
    var index = -1;
2727
    var size = keys.length;
2728

    
2729
    if (iterator.length === 3) {
2730
      while (++index < size) {
2731
        key = keys[index];
2732
        value = object[key];
2733
        iterator(value, key, createCallback(index, value));
2734
      }
2735
    } else {
2736
      while (++index < size) {
2737
        value = object[keys[index]];
2738
        iterator(value, createCallback(index, value));
2739
      }
2740
    }
2741
  }
2742

    
2743
  /**
2744
   * @private
2745
   */
2746
  function symbolEachIndexValue(collection, iterator, createCallback) {
2747
    var value, item;
2748
    var index = 0;
2749
    var iter = collection[iteratorSymbol]();
2750

    
2751
    if (iterator.length === 3) {
2752
      while ((item = iter.next()).done === false) {
2753
        value = item.value;
2754
        iterator(value, index, createCallback(index++, value));
2755
      }
2756
    } else {
2757
      while ((item = iter.next()).done === false) {
2758
        value = item.value;
2759
        iterator(value, createCallback(index++, value));
2760
      }
2761
    }
2762
    return index;
2763
  }
2764

    
2765
  /**
2766
   * @private
2767
   */
2768
  function baseEachKeyValue(object, iterator, createCallback, keys) {
2769
    var key, value;
2770
    var index = -1;
2771
    var size = keys.length;
2772

    
2773
    if (iterator.length === 3) {
2774
      while (++index < size) {
2775
        key = keys[index];
2776
        value = object[key];
2777
        iterator(value, key, createCallback(key, value));
2778
      }
2779
    } else {
2780
      while (++index < size) {
2781
        key = keys[index];
2782
        value = object[key];
2783
        iterator(value, createCallback(key, value));
2784
      }
2785
    }
2786
  }
2787

    
2788
  /**
2789
   * @private
2790
   */
2791
  function symbolEachKeyValue(collection, iterator, createCallback) {
2792
    var value, item;
2793
    var index = 0;
2794
    var iter = collection[iteratorSymbol]();
2795

    
2796
    if (iterator.length === 3) {
2797
      while ((item = iter.next()).done === false) {
2798
        value = item.value;
2799
        iterator(value, index, createCallback(index++, value));
2800
      }
2801
    } else {
2802
      while ((item = iter.next()).done === false) {
2803
        value = item.value;
2804
        iterator(value, createCallback(index++, value));
2805
      }
2806
    }
2807
    return index;
2808
  }
2809

    
2810
  /**
2811
   * @private
2812
   * @param {Function} func
2813
   */
2814
  function onlyOnce(func) {
2815
    return function(err, res) {
2816
      var fn = func;
2817
      func = throwError;
2818
      fn(err, res);
2819
    };
2820
  }
2821

    
2822
  /**
2823
   * @private
2824
   * @param {Function} func
2825
   */
2826
  function once(func) {
2827
    return function(err, res) {
2828
      var fn = func;
2829
      func = noop;
2830
      fn(err, res);
2831
    };
2832
  }
2833

    
2834
  /**
2835
   * @private
2836
   * @param {Function} arrayEach
2837
   * @param {Function} baseEach
2838
   */
2839
  function createEach(arrayEach, baseEach, symbolEach) {
2840
    return function each(collection, iterator, callback) {
2841
      callback = once(callback || noop);
2842
      var size, keys;
2843
      var completed = 0;
2844
      if (isArray(collection)) {
2845
        size = collection.length;
2846
        arrayEach(collection, iterator, done);
2847
      } else if (!collection) {
2848
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
2849
        size = symbolEach(collection, iterator, done);
2850
        size && size === completed && callback(null);
2851
      } else if (typeof collection === obj) {
2852
        keys = nativeKeys(collection);
2853
        size = keys.length;
2854
        baseEach(collection, iterator, done, keys);
2855
      }
2856
      if (!size) {
2857
        callback(null);
2858
      }
2859

    
2860
      function done(err, bool) {
2861
        if (err) {
2862
          callback = once(callback);
2863
          callback(err);
2864
        } else if (++completed === size) {
2865
          callback(null);
2866
        } else if (bool === false) {
2867
          callback = once(callback);
2868
          callback(null);
2869
        }
2870
      }
2871
    };
2872
  }
2873

    
2874
  /**
2875
   * @private
2876
   * @param {Function} arrayEach
2877
   * @param {Function} baseEach
2878
   * @param {Function} symbolEach
2879
   */
2880
  function createMap(arrayEach, baseEach, symbolEach, useArray) {
2881
    var init, clone;
2882
    if (useArray) {
2883
      init = Array;
2884
      clone = createArray;
2885
    } else {
2886
      init = function() {
2887
        return {};
2888
      };
2889
      clone = objectClone;
2890
    }
2891

    
2892
    return function(collection, iterator, callback) {
2893
      callback = callback || noop;
2894
      var size, keys, result;
2895
      var completed = 0;
2896

    
2897
      if (isArray(collection)) {
2898
        size = collection.length;
2899
        result = init(size);
2900
        arrayEach(collection, iterator, createCallback);
2901
      } else if (!collection) {
2902
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
2903
        // TODO: size could be changed
2904
        result = init(0);
2905
        size = symbolEach(collection, iterator, createCallback);
2906
        size && size === completed && callback(null, result);
2907
      } else if (typeof collection === obj) {
2908
        keys = nativeKeys(collection);
2909
        size = keys.length;
2910
        result = init(size);
2911
        baseEach(collection, iterator, createCallback, keys);
2912
      }
2913
      if (!size) {
2914
        callback(null, init());
2915
      }
2916

    
2917
      function createCallback(key) {
2918
        return function done(err, res) {
2919
          if (key === null) {
2920
            throwError();
2921
          }
2922
          if (err) {
2923
            key = null;
2924
            callback = once(callback);
2925
            callback(err, clone(result));
2926
            return;
2927
          }
2928
          result[key] = res;
2929
          key = null;
2930
          if (++completed === size) {
2931
            callback(null, result);
2932
          }
2933
        };
2934
      }
2935
    };
2936
  }
2937

    
2938
  /**
2939
   * @private
2940
   * @param {Function} arrayEach
2941
   * @param {Function} baseEach
2942
   * @param {Function} symbolEach
2943
   * @param {boolean} bool
2944
   */
2945
  function createFilter(arrayEach, baseEach, symbolEach, bool) {
2946
    return function(collection, iterator, callback) {
2947
      callback = callback || noop;
2948
      var size, keys, result;
2949
      var completed = 0;
2950

    
2951
      if (isArray(collection)) {
2952
        size = collection.length;
2953
        result = Array(size);
2954
        arrayEach(collection, iterator, createCallback);
2955
      } else if (!collection) {
2956
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
2957
        result = [];
2958
        size = symbolEach(collection, iterator, createCallback);
2959
        size && size === completed && callback(null, compact(result));
2960
      } else if (typeof collection === obj) {
2961
        keys = nativeKeys(collection);
2962
        size = keys.length;
2963
        result = Array(size);
2964
        baseEach(collection, iterator, createCallback, keys);
2965
      }
2966
      if (!size) {
2967
        return callback(null, []);
2968
      }
2969

    
2970
      function createCallback(index, value) {
2971
        return function done(err, res) {
2972
          if (index === null) {
2973
            throwError();
2974
          }
2975
          if (err) {
2976
            index = null;
2977
            callback = once(callback);
2978
            callback(err);
2979
            return;
2980
          }
2981
          if (!!res === bool) {
2982
            result[index] = value;
2983
          }
2984
          index = null;
2985
          if (++completed === size) {
2986
            callback(null, compact(result));
2987
          }
2988
        };
2989
      }
2990
    };
2991
  }
2992

    
2993
  /**
2994
   * @private
2995
   * @param {boolean} bool
2996
   */
2997
  function createFilterSeries(bool) {
2998
    return function(collection, iterator, callback) {
2999
      callback = onlyOnce(callback || noop);
3000
      var size, key, value, keys, iter, item, iterate;
3001
      var sync = false;
3002
      var completed = 0;
3003
      var result = [];
3004

    
3005
      if (isArray(collection)) {
3006
        size = collection.length;
3007
        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3008
      } else if (!collection) {
3009
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
3010
        size = Infinity;
3011
        iter = collection[iteratorSymbol]();
3012
        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3013
      } else if (typeof collection === obj) {
3014
        keys = nativeKeys(collection);
3015
        size = keys.length;
3016
        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3017
      }
3018
      if (!size) {
3019
        return callback(null, []);
3020
      }
3021
      iterate();
3022

    
3023
      function arrayIterator() {
3024
        value = collection[completed];
3025
        iterator(value, done);
3026
      }
3027

    
3028
      function arrayIteratorWithIndex() {
3029
        value = collection[completed];
3030
        iterator(value, completed, done);
3031
      }
3032

    
3033
      function symbolIterator() {
3034
        item = iter.next();
3035
        value = item.value;
3036
        item.done ? callback(null, result) : iterator(value, done);
3037
      }
3038

    
3039
      function symbolIteratorWithKey() {
3040
        item = iter.next();
3041
        value = item.value;
3042
        item.done ? callback(null, result) : iterator(value, completed, done);
3043
      }
3044

    
3045
      function objectIterator() {
3046
        key = keys[completed];
3047
        value = collection[key];
3048
        iterator(value, done);
3049
      }
3050

    
3051
      function objectIteratorWithKey() {
3052
        key = keys[completed];
3053
        value = collection[key];
3054
        iterator(value, key, done);
3055
      }
3056

    
3057
      function done(err, res) {
3058
        if (err) {
3059
          callback(err);
3060
          return;
3061
        }
3062
        if (!!res === bool) {
3063
          result[result.length] = value;
3064
        }
3065
        if (++completed === size) {
3066
          iterate = throwError;
3067
          callback(null, result);
3068
        } else if (sync) {
3069
          nextTick(iterate);
3070
        } else {
3071
          sync = true;
3072
          iterate();
3073
        }
3074
        sync = false;
3075
      }
3076
    };
3077
  }
3078

    
3079
  /**
3080
   * @private
3081
   * @param {boolean} bool
3082
   */
3083
  function createFilterLimit(bool) {
3084
    return function(collection, limit, iterator, callback) {
3085
      callback = callback || noop;
3086
      var size, index, key, value, keys, iter, item, iterate, result;
3087
      var sync = false;
3088
      var started = 0;
3089
      var completed = 0;
3090

    
3091
      if (isArray(collection)) {
3092
        size = collection.length;
3093
        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3094
      } else if (!collection) {
3095
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
3096
        size = Infinity;
3097
        result = [];
3098
        iter = collection[iteratorSymbol]();
3099
        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3100
      } else if (typeof collection === obj) {
3101
        keys = nativeKeys(collection);
3102
        size = keys.length;
3103
        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3104
      }
3105
      if (!size || isNaN(limit) || limit < 1) {
3106
        return callback(null, []);
3107
      }
3108
      result = result || Array(size);
3109
      timesSync(limit > size ? size : limit, iterate);
3110

    
3111
      function arrayIterator() {
3112
        index = started++;
3113
        if (index < size) {
3114
          value = collection[index];
3115
          iterator(value, createCallback(value, index));
3116
        }
3117
      }
3118

    
3119
      function arrayIteratorWithIndex() {
3120
        index = started++;
3121
        if (index < size) {
3122
          value = collection[index];
3123
          iterator(value, index, createCallback(value, index));
3124
        }
3125
      }
3126

    
3127
      function symbolIterator() {
3128
        item = iter.next();
3129
        if (item.done === false) {
3130
          value = item.value;
3131
          iterator(value, createCallback(value, started++));
3132
        } else if (completed === started && iterator !== noop) {
3133
          iterator = noop;
3134
          callback(null, compact(result));
3135
        }
3136
      }
3137

    
3138
      function symbolIteratorWithKey() {
3139
        item = iter.next();
3140
        if (item.done === false) {
3141
          value = item.value;
3142
          iterator(value, started, createCallback(value, started++));
3143
        } else if (completed === started && iterator !== noop) {
3144
          iterator = noop;
3145
          callback(null, compact(result));
3146
        }
3147
      }
3148

    
3149
      function objectIterator() {
3150
        index = started++;
3151
        if (index < size) {
3152
          value = collection[keys[index]];
3153
          iterator(value, createCallback(value, index));
3154
        }
3155
      }
3156

    
3157
      function objectIteratorWithKey() {
3158
        index = started++;
3159
        if (index < size) {
3160
          key = keys[index];
3161
          value = collection[key];
3162
          iterator(value, key, createCallback(value, index));
3163
        }
3164
      }
3165

    
3166
      function createCallback(value, index) {
3167
        return function(err, res) {
3168
          if (index === null) {
3169
            throwError();
3170
          }
3171
          if (err) {
3172
            index = null;
3173
            iterate = noop;
3174
            callback = once(callback);
3175
            callback(err);
3176
            return;
3177
          }
3178
          if (!!res === bool) {
3179
            result[index] = value;
3180
          }
3181
          index = null;
3182
          if (++completed === size) {
3183
            callback = onlyOnce(callback);
3184
            callback(null, compact(result));
3185
          } else if (sync) {
3186
            nextTick(iterate);
3187
          } else {
3188
            sync = true;
3189
            iterate();
3190
          }
3191
          sync = false;
3192
        };
3193
      }
3194
    };
3195
  }
3196

    
3197
  /**
3198
   * @memberof async
3199
   * @namespace eachSeries
3200
   * @param {Array|Object} collection
3201
   * @param {Function} iterator
3202
   * @param {Function} callback
3203
   * @example
3204
   *
3205
   * // array
3206
   * var order = [];
3207
   * var array = [1, 3, 2];
3208
   * var iterator = function(num, done) {
3209
   *   setTimeout(function() {
3210
   *     order.push(num);
3211
   *     done();
3212
   *   }, num * 10);
3213
   * };
3214
   * async.eachSeries(array, iterator, function(err, res) {
3215
   *   console.log(res); // undefined
3216
   *   console.log(order); // [1, 3, 2]
3217
   * });
3218
   *
3219
   * @example
3220
   *
3221
   * // array with index
3222
   * var order = [];
3223
   * var array = [1, 3, 2];
3224
   * var iterator = function(num, index, done) {
3225
   *   setTimeout(function() {
3226
   *     order.push([num, index]);
3227
   *     done();
3228
   *   }, num * 10);
3229
   * };
3230
   * async.eachSeries(array, iterator, function(err, res) {
3231
   *   console.log(res); // undefined
3232
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
3233
   * });
3234
   *
3235
   * @example
3236
   *
3237
   * // object
3238
   * var order = [];
3239
   * var object = { a: 1, b: 3, c: 2 };
3240
   * var iterator = function(num, done) {
3241
   *   setTimeout(function() {
3242
   *     order.push(num);
3243
   *     done();
3244
   *   }, num * 10);
3245
   * };
3246
   * async.eachSeries(object, iterator, function(err, res) {
3247
   *   console.log(res); // undefined
3248
   *   console.log(order); // [1, 3, 2]
3249
   * });
3250
   *
3251
   * @example
3252
   *
3253
   * // object with key
3254
   * var order = [];
3255
   * var object = { a: 1, b: 3, c: 2 };
3256
   * var iterator = function(num, key, done) {
3257
   *   setTimeout(function() {
3258
   *     order.push([num, key]);
3259
   *     done();
3260
   *   }, num * 10);
3261
   * };
3262
   * async.eachSeries(object, iterator, function(err, res) {
3263
   *   console.log(res); // undefined
3264
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b']]
3265
   * });
3266
   *
3267
   * @example
3268
   *
3269
   * // break
3270
   * var order = [];
3271
   * var array = [1, 3, 2];
3272
   * var iterator = function(num, done) {
3273
   *   setTimeout(function() {
3274
   *     order.push(num);
3275
   *     done(null, num !== 3);
3276
   *   }, num * 10);
3277
   * };
3278
   * async.eachSeries(array, iterator, function(err, res) {
3279
   *   console.log(res); // undefined
3280
   *   console.log(order); // [1, 3]
3281
   * });
3282
   */
3283
  function eachSeries(collection, iterator, callback) {
3284
    callback = onlyOnce(callback || noop);
3285
    var size, key, keys, iter, item, iterate;
3286
    var sync = false;
3287
    var completed = 0;
3288

    
3289
    if (isArray(collection)) {
3290
      size = collection.length;
3291
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3292
    } else if (!collection) {
3293
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
3294
      size = Infinity;
3295
      iter = collection[iteratorSymbol]();
3296
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3297
    } else if (typeof collection === obj) {
3298
      keys = nativeKeys(collection);
3299
      size = keys.length;
3300
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3301
    }
3302
    if (!size) {
3303
      return callback(null);
3304
    }
3305
    iterate();
3306

    
3307
    function arrayIterator() {
3308
      iterator(collection[completed], done);
3309
    }
3310

    
3311
    function arrayIteratorWithIndex() {
3312
      iterator(collection[completed], completed, done);
3313
    }
3314

    
3315
    function symbolIterator() {
3316
      item = iter.next();
3317
      item.done ? callback(null) : iterator(item.value, done);
3318
    }
3319

    
3320
    function symbolIteratorWithKey() {
3321
      item = iter.next();
3322
      item.done ? callback(null) : iterator(item.value, completed, done);
3323
    }
3324

    
3325
    function objectIterator() {
3326
      iterator(collection[keys[completed]], done);
3327
    }
3328

    
3329
    function objectIteratorWithKey() {
3330
      key = keys[completed];
3331
      iterator(collection[key], key, done);
3332
    }
3333

    
3334
    function done(err, bool) {
3335
      if (err) {
3336
        callback(err);
3337
      } else if (++completed === size || bool === false) {
3338
        iterate = throwError;
3339
        callback(null);
3340
      } else if (sync) {
3341
        nextTick(iterate);
3342
      } else {
3343
        sync = true;
3344
        iterate();
3345
      }
3346
      sync = false;
3347
    }
3348
  }
3349

    
3350
  /**
3351
   * @memberof async
3352
   * @namespace eachLimit
3353
   * @param {Array|Object} collection
3354
   * @param {number} limit - limit >= 1
3355
   * @param {Function} iterator
3356
   * @param {Function} callback
3357
   * @example
3358
   *
3359
   * // array
3360
   * var order = [];
3361
   * var array = [1, 5, 3, 4, 2];
3362
   * var iterator = function(num, done) {
3363
   *   setTimeout(function() {
3364
   *     order.push(num);
3365
   *     done();
3366
   *   }, num * 10);
3367
   * };
3368
   * async.eachLimit(array, 2, iterator, function(err, res) {
3369
   *   console.log(res); // undefined
3370
   *   console.log(order); // [1, 3, 5, 2, 4]
3371
   * });
3372
   *
3373
   * @example
3374
   *
3375
   * // array with index
3376
   * var order = [];
3377
   * var array = [1, 5, 3, 4, 2];
3378
   * var iterator = function(num, index, done) {
3379
   *   setTimeout(function() {
3380
   *     order.push([num, index]);
3381
   *     done();
3382
   *   }, num * 10);
3383
   * };
3384
   * async.eachLimit(array, 2, iterator, function(err, res) {
3385
   *   console.log(res); // undefined
3386
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
3387
   * });
3388
   *
3389
   * @example
3390
   *
3391
   * // object
3392
   * var order = [];
3393
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3394
   * var iterator = function(num, done) {
3395
   *   setTimeout(function() {
3396
   *     order.push(num);
3397
   *     done();
3398
   *   }, num * 10);
3399
   * };
3400
   * async.eachLimit(object, 2, iterator, function(err, res) {
3401
   *   console.log(res); // undefined
3402
   *   console.log(order); // [1, 3, 5, 2, 4]
3403
   * });
3404
   *
3405
   * @example
3406
   *
3407
   * // object with key
3408
   * var order = [];
3409
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3410
   * var iterator = function(num, key, done) {
3411
   *   setTimeout(function() {
3412
   *     order.push([num, key]);
3413
   *     done();
3414
   *   }, num * 10);
3415
   * };
3416
   * async.eachLimit(object, 2, iterator, function(err, res) {
3417
   *   console.log(res); // undefined
3418
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
3419
   * });
3420
   *
3421
   * @example
3422
   *
3423
   * // break
3424
   * var order = [];
3425
   * var array = [1, 5, 3, 4, 2];
3426
   * var iterator = function(num, done) {
3427
   *   setTimeout(function() {
3428
   *     order.push(num);
3429
   *     done(null, num !== 5);
3430
   *   }, num * 10);
3431
   * };
3432
   * async.eachLimit(array, 2, iterator, function(err, res) {
3433
   *   console.log(res); // undefined
3434
   *   console.log(order); // [1, 3, 5]
3435
   * });
3436
   *
3437
   */
3438
  function eachLimit(collection, limit, iterator, callback) {
3439
    callback = callback || noop;
3440
    var size, index, key, keys, iter, item, iterate;
3441
    var sync = false;
3442
    var started = 0;
3443
    var completed = 0;
3444

    
3445
    if (isArray(collection)) {
3446
      size = collection.length;
3447
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3448
    } else if (!collection) {
3449
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
3450
      size = Infinity;
3451
      iter = collection[iteratorSymbol]();
3452
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3453
    } else if (typeof collection === obj) {
3454
      keys = nativeKeys(collection);
3455
      size = keys.length;
3456
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3457
    } else {
3458
      return callback(null);
3459
    }
3460
    if (!size || isNaN(limit) || limit < 1) {
3461
      return callback(null);
3462
    }
3463
    timesSync(limit > size ? size : limit, iterate);
3464

    
3465
    function arrayIterator() {
3466
      if (started < size) {
3467
        iterator(collection[started++], done);
3468
      }
3469
    }
3470

    
3471
    function arrayIteratorWithIndex() {
3472
      index = started++;
3473
      if (index < size) {
3474
        iterator(collection[index], index, done);
3475
      }
3476
    }
3477

    
3478
    function symbolIterator() {
3479
      item = iter.next();
3480
      if (item.done === false) {
3481
        started++;
3482
        iterator(item.value, done);
3483
      } else if (completed === started && iterator !== noop) {
3484
        iterator = noop;
3485
        callback(null);
3486
      }
3487
    }
3488

    
3489
    function symbolIteratorWithKey() {
3490
      item = iter.next();
3491
      if (item.done === false) {
3492
        iterator(item.value, started++, done);
3493
      } else if (completed === started && iterator !== noop) {
3494
        iterator = noop;
3495
        callback(null);
3496
      }
3497
    }
3498

    
3499
    function objectIterator() {
3500
      if (started < size) {
3501
        iterator(collection[keys[started++]], done);
3502
      }
3503
    }
3504

    
3505
    function objectIteratorWithKey() {
3506
      index = started++;
3507
      if (index < size) {
3508
        key = keys[index];
3509
        iterator(collection[key], key, done);
3510
      }
3511
    }
3512

    
3513
    function done(err, bool) {
3514
      if (err || bool === false) {
3515
        iterate = noop;
3516
        callback = once(callback);
3517
        callback(err);
3518
      } else if (++completed === size) {
3519
        iterator = noop;
3520
        iterate = throwError;
3521
        callback = onlyOnce(callback);
3522
        callback(null);
3523
      } else if (sync) {
3524
        nextTick(iterate);
3525
      } else {
3526
        sync = true;
3527
        iterate();
3528
      }
3529
      sync = false;
3530
    }
3531
  }
3532

    
3533
  /**
3534
   * @memberof async
3535
   * @namespace mapSeries
3536
   * @param {Array|Object} collection
3537
   * @param {Function} iterator
3538
   * @param {Function} callback
3539
   * @example
3540
   *
3541
   * // array
3542
   * var order = [];
3543
   * var array = [1, 3, 2];
3544
   * var iterator = function(num, done) {
3545
   *   setTimeout(function() {
3546
   *     order.push(num);
3547
   *     done(null, num);
3548
   *   }, num * 10);
3549
   * };
3550
   * async.mapSeries(array, iterator, function(err, res) {
3551
   *   console.log(res); // [1, 3, 2];
3552
   *   console.log(order); // [1, 3, 2]
3553
   * });
3554
   *
3555
   * @example
3556
   *
3557
   * // array with index
3558
   * var order = [];
3559
   * var array = [1, 3, 2];
3560
   * var iterator = function(num, index, done) {
3561
   *   setTimeout(function() {
3562
   *     order.push([num, index]);
3563
   *     done(null, num);
3564
   *   }, num * 10);
3565
   * };
3566
   * async.mapSeries(array, iterator, function(err, res) {
3567
   *   console.log(res); // [1, 3, 2]
3568
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
3569
   * });
3570
   *
3571
   * @example
3572
   *
3573
   * // object
3574
   * var order = [];
3575
   * var object = { a: 1, b: 3, c: 2 };
3576
   * var iterator = function(num, done) {
3577
   *   setTimeout(function() {
3578
   *     order.push(num);
3579
   *     done(null, num);
3580
   *   }, num * 10);
3581
   * };
3582
   * async.mapSeries(object, iterator, function(err, res) {
3583
   *   console.log(res); // [1, 3, 2]
3584
   *   console.log(order); // [1, 3, 2]
3585
   * });
3586
   *
3587
   * @example
3588
   *
3589
   * // object with key
3590
   * var order = [];
3591
   * var object = { a: 1, b: 3, c: 2 };
3592
   * var iterator = function(num, key, done) {
3593
   *   setTimeout(function() {
3594
   *     order.push([num, key]);
3595
   *     done(null, num);
3596
   *   }, num * 10);
3597
   * };
3598
   * async.mapSeries(object, iterator, function(err, res) {
3599
   *   console.log(res); // [1, 3, 2]
3600
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
3601
   * });
3602
   *
3603
   */
3604
  function mapSeries(collection, iterator, callback) {
3605
    callback = callback || noop;
3606
    var size, key, keys, iter, item, result, iterate;
3607
    var sync = false;
3608
    var completed = 0;
3609

    
3610
    if (isArray(collection)) {
3611
      size = collection.length;
3612
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3613
    } else if (!collection) {
3614
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
3615
      size = Infinity;
3616
      result = [];
3617
      iter = collection[iteratorSymbol]();
3618
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3619
    } else if (typeof collection === obj) {
3620
      keys = nativeKeys(collection);
3621
      size = keys.length;
3622
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3623
    }
3624
    if (!size) {
3625
      return callback(null, []);
3626
    }
3627
    result = result || Array(size);
3628
    iterate();
3629

    
3630
    function arrayIterator() {
3631
      iterator(collection[completed], done);
3632
    }
3633

    
3634
    function arrayIteratorWithIndex() {
3635
      iterator(collection[completed], completed, done);
3636
    }
3637

    
3638
    function symbolIterator() {
3639
      item = iter.next();
3640
      item.done ? callback(null, result) : iterator(item.value, done);
3641
    }
3642

    
3643
    function symbolIteratorWithKey() {
3644
      item = iter.next();
3645
      item.done ? callback(null, result) : iterator(item.value, completed, done);
3646
    }
3647

    
3648
    function objectIterator() {
3649
      iterator(collection[keys[completed]], done);
3650
    }
3651

    
3652
    function objectIteratorWithKey() {
3653
      key = keys[completed];
3654
      iterator(collection[key], key, done);
3655
    }
3656

    
3657
    function done(err, res) {
3658
      if (err) {
3659
        iterate = throwError;
3660
        callback = onlyOnce(callback);
3661
        callback(err, createArray(result));
3662
        return;
3663
      }
3664
      result[completed] = res;
3665
      if (++completed === size) {
3666
        iterate = throwError;
3667
        callback(null, result);
3668
        callback = throwError;
3669
      } else if (sync) {
3670
        nextTick(iterate);
3671
      } else {
3672
        sync = true;
3673
        iterate();
3674
      }
3675
      sync = false;
3676
    }
3677
  }
3678

    
3679
  /**
3680
   * @memberof async
3681
   * @namespace mapLimit
3682
   * @param {Array|Object} collection
3683
   * @param {number} limit - limit >= 1
3684
   * @param {Function} iterator
3685
   * @param {Function} callback
3686
   * @example
3687
   *
3688
   * // array
3689
   * var order = [];
3690
   * var array = [1, 5, 3, 4, 2];
3691
   * var iterator = function(num, done) {
3692
   *   setTimeout(function() {
3693
   *     order.push(num);
3694
   *     done(null, num);
3695
   *   }, num * 10);
3696
   * };
3697
   * async.mapLimit(array, 2, iterator, function(err, res) {
3698
   *   console.log(res); // [1, 5, 3, 4, 2]
3699
   *   console.log(order); // [1, 3, 5, 2, 4]
3700
   * });
3701
   *
3702
   * @example
3703
   *
3704
   * // array with index
3705
   * var order = [];
3706
   * var array = [1, 5, 3, 4, 2];
3707
   * var iterator = function(num, index, done) {
3708
   *   setTimeout(function() {
3709
   *     order.push([num, index]);
3710
   *     done(null, num);
3711
   *   }, num * 10);
3712
   * };
3713
   * async.mapLimit(array, 2, iterator, function(err, res) {
3714
   *   console.log(res); // [1, 5, 3, 4, 2]
3715
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
3716
   * });
3717
   *
3718
   * @example
3719
   *
3720
   * // object
3721
   * var order = [];
3722
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3723
   * var iterator = function(num, done) {
3724
   *   setTimeout(function() {
3725
   *     order.push(num);
3726
   *     done(null, num);
3727
   *   }, num * 10);
3728
   * };
3729
   * async.mapLimit(object, 2, iterator, function(err, res) {
3730
   *   console.log(res); // [1, 5, 3, 4, 2]
3731
   *   console.log(order); // [1, 3, 5, 2, 4]
3732
   * });
3733
   *
3734
   * @example
3735
   *
3736
   * // object with key
3737
   * var order = [];
3738
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3739
   * var iterator = function(num, key, done) {
3740
   *   setTimeout(function() {
3741
   *     order.push([num, key]);
3742
   *     done(null, num);
3743
   *   }, num * 10);
3744
   * };
3745
   * async.mapLimit(object, 2, iterator, function(err, res) {
3746
   *   console.log(res); // [1, 5, 3, 4, 2]
3747
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
3748
   * });
3749
   *
3750
   */
3751
  function mapLimit(collection, limit, iterator, callback) {
3752
    callback = callback || noop;
3753
    var size, index, key, keys, iter, item, result, iterate;
3754
    var sync = false;
3755
    var started = 0;
3756
    var completed = 0;
3757

    
3758
    if (isArray(collection)) {
3759
      size = collection.length;
3760
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3761
    } else if (!collection) {
3762
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
3763
      size = Infinity;
3764
      result = [];
3765
      iter = collection[iteratorSymbol]();
3766
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3767
    } else if (typeof collection === obj) {
3768
      keys = nativeKeys(collection);
3769
      size = keys.length;
3770
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3771
    }
3772
    if (!size || isNaN(limit) || limit < 1) {
3773
      return callback(null, []);
3774
    }
3775
    result = result || Array(size);
3776
    timesSync(limit > size ? size : limit, iterate);
3777

    
3778
    function arrayIterator() {
3779
      index = started++;
3780
      if (index < size) {
3781
        iterator(collection[index], createCallback(index));
3782
      }
3783
    }
3784

    
3785
    function arrayIteratorWithIndex() {
3786
      index = started++;
3787
      if (index < size) {
3788
        iterator(collection[index], index, createCallback(index));
3789
      }
3790
    }
3791

    
3792
    function symbolIterator() {
3793
      item = iter.next();
3794
      if (item.done === false) {
3795
        iterator(item.value, createCallback(started++));
3796
      } else if (completed === started && iterator !== noop) {
3797
        iterator = noop;
3798
        callback(null, result);
3799
      }
3800
    }
3801

    
3802
    function symbolIteratorWithKey() {
3803
      item = iter.next();
3804
      if (item.done === false) {
3805
        iterator(item.value, started, createCallback(started++));
3806
      } else if (completed === started && iterator !== noop) {
3807
        iterator = noop;
3808
        callback(null, result);
3809
      }
3810
    }
3811

    
3812
    function objectIterator() {
3813
      index = started++;
3814
      if (index < size) {
3815
        iterator(collection[keys[index]], createCallback(index));
3816
      }
3817
    }
3818

    
3819
    function objectIteratorWithKey() {
3820
      index = started++;
3821
      if (index < size) {
3822
        key = keys[index];
3823
        iterator(collection[key], key, createCallback(index));
3824
      }
3825
    }
3826

    
3827
    function createCallback(index) {
3828
      return function(err, res) {
3829
        if (index === null) {
3830
          throwError();
3831
        }
3832
        if (err) {
3833
          index = null;
3834
          iterate = noop;
3835
          callback = once(callback);
3836
          callback(err, createArray(result));
3837
          return;
3838
        }
3839
        result[index] = res;
3840
        index = null;
3841
        if (++completed === size) {
3842
          iterate = throwError;
3843
          callback(null, result);
3844
          callback = throwError;
3845
        } else if (sync) {
3846
          nextTick(iterate);
3847
        } else {
3848
          sync = true;
3849
          iterate();
3850
        }
3851
        sync = false;
3852
      };
3853
    }
3854
  }
3855

    
3856
  /**
3857
   * @memberof async
3858
   * @namespace mapValuesSeries
3859
   * @param {Array|Object} collection
3860
   * @param {Function} iterator
3861
   * @param {Function} callback
3862
   * @example
3863
   *
3864
   * // array
3865
   * var order = [];
3866
   * var array = [1, 3, 2];
3867
   * var iterator = function(num, done) {
3868
   *   setTimeout(function() {
3869
   *     order.push(num);
3870
   *     done(null, num);
3871
   *   }, num * 10);
3872
   * };
3873
   * async.mapValuesSeries(array, iterator, function(err, res) {
3874
   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
3875
   *   console.log(order); // [1, 3, 2]
3876
   * });
3877
   *
3878
   * @example
3879
   *
3880
   * // array with index
3881
   * var order = [];
3882
   * var array = [1, 3, 2];
3883
   * var iterator = function(num, index, done) {
3884
   *   setTimeout(function() {
3885
   *     order.push([num, index]);
3886
   *     done(null, num);
3887
   *   }, num * 10);
3888
   * };
3889
   * async.mapValuesSeries(array, iterator, function(err, res) {
3890
   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
3891
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
3892
   * });
3893
   *
3894
   * @example
3895
   *
3896
   * // object
3897
   * var order = [];
3898
   * var object = { a: 1, b: 3, c: 2 };
3899
   * var iterator = function(num, done) {
3900
   *   setTimeout(function() {
3901
   *     order.push(num);
3902
   *     done(null, num);
3903
   *   }, num * 10);
3904
   * };
3905
   * async.mapValuesSeries(object, iterator, function(err, res) {
3906
   *   console.log(res); // { a: 1, b: 3, c: 2 }
3907
   *   console.log(order); // [1, 3, 2]
3908
   * });
3909
   *
3910
   * @example
3911
   *
3912
   * // object with key
3913
   * var order = [];
3914
   * var object = { a: 1, b: 3, c: 2 };
3915
   * var iterator = function(num, key, done) {
3916
   *   setTimeout(function() {
3917
   *     order.push([num, key]);
3918
   *     done(null, num);
3919
   *   }, num * 10);
3920
   * };
3921
   * async.mapValuesSeries(object, iterator, function(err, res) {
3922
   *   console.log(res); // { a: 1, b: 3, c: 2 }
3923
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
3924
   * });
3925
   *
3926
   */
3927
  function mapValuesSeries(collection, iterator, callback) {
3928
    callback = callback || noop;
3929
    var size, key, keys, iter, item, iterate;
3930
    var sync = false;
3931
    var result = {};
3932
    var completed = 0;
3933

    
3934
    if (isArray(collection)) {
3935
      size = collection.length;
3936
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3937
    } else if (!collection) {
3938
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
3939
      size = Infinity;
3940
      iter = collection[iteratorSymbol]();
3941
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3942
    } else if (typeof collection === obj) {
3943
      keys = nativeKeys(collection);
3944
      size = keys.length;
3945
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3946
    }
3947
    if (!size) {
3948
      return callback(null, result);
3949
    }
3950
    iterate();
3951

    
3952
    function arrayIterator() {
3953
      key = completed;
3954
      iterator(collection[completed], done);
3955
    }
3956

    
3957
    function arrayIteratorWithIndex() {
3958
      key = completed;
3959
      iterator(collection[completed], completed, done);
3960
    }
3961

    
3962
    function symbolIterator() {
3963
      key = completed;
3964
      item = iter.next();
3965
      item.done ? callback(null, result) : iterator(item.value, done);
3966
    }
3967

    
3968
    function symbolIteratorWithKey() {
3969
      key = completed;
3970
      item = iter.next();
3971
      item.done ? callback(null, result) : iterator(item.value, completed, done);
3972
    }
3973

    
3974
    function objectIterator() {
3975
      key = keys[completed];
3976
      iterator(collection[key], done);
3977
    }
3978

    
3979
    function objectIteratorWithKey() {
3980
      key = keys[completed];
3981
      iterator(collection[key], key, done);
3982
    }
3983

    
3984
    function done(err, res) {
3985
      if (err) {
3986
        iterate = throwError;
3987
        callback = onlyOnce(callback);
3988
        callback(err, objectClone(result));
3989
        return;
3990
      }
3991
      result[key] = res;
3992
      if (++completed === size) {
3993
        iterate = throwError;
3994
        callback(null, result);
3995
        callback = throwError;
3996
      } else if (sync) {
3997
        nextTick(iterate);
3998
      } else {
3999
        sync = true;
4000
        iterate();
4001
      }
4002
      sync = false;
4003
    }
4004
  }
4005

    
4006
  /**
4007
   * @memberof async
4008
   * @namespace mapValuesLimit
4009
   * @param {Array|Object} collection
4010
   * @param {number} limit - limit >= 1
4011
   * @param {Function} iterator
4012
   * @param {Function} callback
4013
   * @example
4014
   *
4015
   * // array
4016
   * var order = [];
4017
   * var array = [1, 5, 3, 4, 2];
4018
   * var iterator = function(num, done) {
4019
   *   setTimeout(function() {
4020
   *     order.push(num);
4021
   *     done(null, num);
4022
   *   }, num * 10);
4023
   * };
4024
   * async.mapValuesLimit(array, 2, iterator, function(err, res) {
4025
   *   console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
4026
   *   console.log(order); // [1, 3, 5, 2, 4]
4027
   * });
4028
   *
4029
   * @example
4030
   *
4031
   * // array with index
4032
   * var order = [];
4033
   * var array = [1, 5, 3, 4, 2];
4034
   * var iterator = function(num, index, done) {
4035
   *   setTimeout(function() {
4036
   *     order.push([num, index]);
4037
   *     done(null, num);
4038
   *   }, num * 10);
4039
   * };
4040
   * async.mapValuesLimit(array, 2, iterator, function(err, res) {
4041
   *   console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
4042
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
4043
   * });
4044
   *
4045
   * @example
4046
   *
4047
   * // object
4048
   * var order = [];
4049
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
4050
   * var iterator = function(num, done) {
4051
   *   setTimeout(function() {
4052
   *     order.push(num);
4053
   *     done(null, num);
4054
   *   }, num * 10);
4055
   * };
4056
   * async.mapValuesLimit(object, 2, iterator, function(err, res) {
4057
   *   console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }
4058
   *   console.log(order); // [1, 3, 5, 2, 4]
4059
   * });
4060
   *
4061
   * @example
4062
   *
4063
   * // object with key
4064
   * var order = [];
4065
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
4066
   * var iterator = function(num, key, done) {
4067
   *   setTimeout(function() {
4068
   *     order.push([num, key]);
4069
   *     done(null, num);
4070
   *   }, num * 10);
4071
   * };
4072
   * async.mapValuesLimit(object, 2, iterator, function(err, res) {
4073
   *   console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }
4074
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
4075
   * });
4076
   *
4077
   */
4078
  function mapValuesLimit(collection, limit, iterator, callback) {
4079
    callback = callback || noop;
4080
    var size, index, key, keys, iter, item, iterate;
4081
    var sync = false;
4082
    var result = {};
4083
    var started = 0;
4084
    var completed = 0;
4085

    
4086
    if (isArray(collection)) {
4087
      size = collection.length;
4088
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4089
    } else if (!collection) {
4090
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
4091
      size = Infinity;
4092
      iter = collection[iteratorSymbol]();
4093
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4094
    } else if (typeof collection === obj) {
4095
      keys = nativeKeys(collection);
4096
      size = keys.length;
4097
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4098
    }
4099
    if (!size || isNaN(limit) || limit < 1) {
4100
      return callback(null, result);
4101
    }
4102
    timesSync(limit > size ? size : limit, iterate);
4103

    
4104
    function arrayIterator() {
4105
      index = started++;
4106
      if (index < size) {
4107
        iterator(collection[index], createCallback(index));
4108
      }
4109
    }
4110

    
4111
    function arrayIteratorWithIndex() {
4112
      index = started++;
4113
      if (index < size) {
4114
        iterator(collection[index], index, createCallback(index));
4115
      }
4116
    }
4117

    
4118
    function symbolIterator() {
4119
      item = iter.next();
4120
      if (item.done === false) {
4121
        iterator(item.value, createCallback(started++));
4122
      } else if (completed === started && iterator !== noop) {
4123
        iterator = noop;
4124
        callback(null, result);
4125
      }
4126
    }
4127

    
4128
    function symbolIteratorWithKey() {
4129
      item = iter.next();
4130
      if (item.done === false) {
4131
        iterator(item.value, started, createCallback(started++));
4132
      } else if (completed === started && iterator !== noop) {
4133
        iterator = noop;
4134
        callback(null, result);
4135
      }
4136
    }
4137

    
4138
    function objectIterator() {
4139
      index = started++;
4140
      if (index < size) {
4141
        key = keys[index];
4142
        iterator(collection[key], createCallback(key));
4143
      }
4144
    }
4145

    
4146
    function objectIteratorWithKey() {
4147
      index = started++;
4148
      if (index < size) {
4149
        key = keys[index];
4150
        iterator(collection[key], key, createCallback(key));
4151
      }
4152
    }
4153

    
4154
    function createCallback(key) {
4155
      return function(err, res) {
4156
        if (key === null) {
4157
          throwError();
4158
        }
4159
        if (err) {
4160
          key = null;
4161
          iterate = noop;
4162
          callback = once(callback);
4163
          callback(err, objectClone(result));
4164
          return;
4165
        }
4166
        result[key] = res;
4167
        key = null;
4168
        if (++completed === size) {
4169
          callback(null, result);
4170
        } else if (sync) {
4171
          nextTick(iterate);
4172
        } else {
4173
          sync = true;
4174
          iterate();
4175
        }
4176
        sync = false;
4177
      };
4178
    }
4179
  }
4180

    
4181
  /**
4182
   * @private
4183
   * @param {Function} arrayEach
4184
   * @param {Function} baseEach
4185
   * @param {Function} symbolEach
4186
   * @param {boolean} bool
4187
   */
4188
  function createDetect(arrayEach, baseEach, symbolEach, bool) {
4189
    return function(collection, iterator, callback) {
4190
      callback = callback || noop;
4191
      var size, keys;
4192
      var completed = 0;
4193

    
4194
      if (isArray(collection)) {
4195
        size = collection.length;
4196
        arrayEach(collection, iterator, createCallback);
4197
      } else if (!collection) {
4198
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4199
        size = symbolEach(collection, iterator, createCallback);
4200
        size && size === completed && callback(null);
4201
      } else if (typeof collection === obj) {
4202
        keys = nativeKeys(collection);
4203
        size = keys.length;
4204
        baseEach(collection, iterator, createCallback, keys);
4205
      }
4206
      if (!size) {
4207
        callback(null);
4208
      }
4209

    
4210
      function createCallback(value) {
4211
        var called = false;
4212
        return function done(err, res) {
4213
          if (called) {
4214
            throwError();
4215
          }
4216
          called = true;
4217
          if (err) {
4218
            callback = once(callback);
4219
            callback(err);
4220
          } else if (!!res === bool) {
4221
            callback = once(callback);
4222
            callback(null, value);
4223
          } else if (++completed === size) {
4224
            callback(null);
4225
          }
4226
        };
4227
      }
4228
    };
4229
  }
4230

    
4231
  /**
4232
   * @private
4233
   * @param {boolean} bool
4234
   */
4235
  function createDetectSeries(bool) {
4236
    return function(collection, iterator, callback) {
4237
      callback = onlyOnce(callback || noop);
4238
      var size, key, value, keys, iter, item, iterate;
4239
      var sync = false;
4240
      var completed = 0;
4241

    
4242
      if (isArray(collection)) {
4243
        size = collection.length;
4244
        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4245
      } else if (!collection) {
4246
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4247
        size = Infinity;
4248
        iter = collection[iteratorSymbol]();
4249
        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4250
      } else if (typeof collection === obj) {
4251
        keys = nativeKeys(collection);
4252
        size = keys.length;
4253
        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4254
      }
4255
      if (!size) {
4256
        return callback(null);
4257
      }
4258
      iterate();
4259

    
4260
      function arrayIterator() {
4261
        value = collection[completed];
4262
        iterator(value, done);
4263
      }
4264

    
4265
      function arrayIteratorWithIndex() {
4266
        value = collection[completed];
4267
        iterator(value, completed, done);
4268
      }
4269

    
4270
      function symbolIterator() {
4271
        item = iter.next();
4272
        value = item.value;
4273
        item.done ? callback(null) : iterator(value, done);
4274
      }
4275

    
4276
      function symbolIteratorWithKey() {
4277
        item = iter.next();
4278
        value = item.value;
4279
        item.done ? callback(null) : iterator(value, completed, done);
4280
      }
4281

    
4282
      function objectIterator() {
4283
        value = collection[keys[completed]];
4284
        iterator(value, done);
4285
      }
4286

    
4287
      function objectIteratorWithKey() {
4288
        key = keys[completed];
4289
        value = collection[key];
4290
        iterator(value, key, done);
4291
      }
4292

    
4293
      function done(err, res) {
4294
        if (err) {
4295
          callback(err);
4296
        } else if (!!res === bool) {
4297
          iterate = throwError;
4298
          callback(null, value);
4299
        } else if (++completed === size) {
4300
          iterate = throwError;
4301
          callback(null);
4302
        } else if (sync) {
4303
          nextTick(iterate);
4304
        } else {
4305
          sync = true;
4306
          iterate();
4307
        }
4308
        sync = false;
4309
      }
4310
    };
4311
  }
4312

    
4313
  /**
4314
   * @private
4315
   * @param {boolean} bool
4316
   */
4317
  function createDetectLimit(bool) {
4318
    return function(collection, limit, iterator, callback) {
4319
      callback = callback || noop;
4320
      var size, index, key, value, keys, iter, item, iterate;
4321
      var sync = false;
4322
      var started = 0;
4323
      var completed = 0;
4324

    
4325
      if (isArray(collection)) {
4326
        size = collection.length;
4327
        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4328
      } else if (!collection) {
4329
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4330
        size = Infinity;
4331
        iter = collection[iteratorSymbol]();
4332
        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4333
      } else if (typeof collection === obj) {
4334
        keys = nativeKeys(collection);
4335
        size = keys.length;
4336
        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4337
      }
4338
      if (!size || isNaN(limit) || limit < 1) {
4339
        return callback(null);
4340
      }
4341
      timesSync(limit > size ? size : limit, iterate);
4342

    
4343
      function arrayIterator() {
4344
        index = started++;
4345
        if (index < size) {
4346
          value = collection[index];
4347
          iterator(value, createCallback(value));
4348
        }
4349
      }
4350

    
4351
      function arrayIteratorWithIndex() {
4352
        index = started++;
4353
        if (index < size) {
4354
          value = collection[index];
4355
          iterator(value, index, createCallback(value));
4356
        }
4357
      }
4358

    
4359
      function symbolIterator() {
4360
        item = iter.next();
4361
        if (item.done === false) {
4362
          started++;
4363
          value = item.value;
4364
          iterator(value, createCallback(value));
4365
        } else if (completed === started && iterator !== noop) {
4366
          iterator = noop;
4367
          callback(null);
4368
        }
4369
      }
4370

    
4371
      function symbolIteratorWithKey() {
4372
        item = iter.next();
4373
        if (item.done === false) {
4374
          value = item.value;
4375
          iterator(value, started++, createCallback(value));
4376
        } else if (completed === started && iterator !== noop) {
4377
          iterator = noop;
4378
          callback(null);
4379
        }
4380
      }
4381

    
4382
      function objectIterator() {
4383
        index = started++;
4384
        if (index < size) {
4385
          value = collection[keys[index]];
4386
          iterator(value, createCallback(value));
4387
        }
4388
      }
4389

    
4390
      function objectIteratorWithKey() {
4391
        if (started < size) {
4392
          key = keys[started++];
4393
          value = collection[key];
4394
          iterator(value, key, createCallback(value));
4395
        }
4396
      }
4397

    
4398
      function createCallback(value) {
4399
        var called = false;
4400
        return function(err, res) {
4401
          if (called) {
4402
            throwError();
4403
          }
4404
          called = true;
4405
          if (err) {
4406
            iterate = noop;
4407
            callback = once(callback);
4408
            callback(err);
4409
          } else if (!!res === bool) {
4410
            iterate = noop;
4411
            callback = once(callback);
4412
            callback(null, value);
4413
          } else if (++completed === size) {
4414
            callback(null);
4415
          } else if (sync) {
4416
            nextTick(iterate);
4417
          } else {
4418
            sync = true;
4419
            iterate();
4420
          }
4421
          sync = false;
4422
        };
4423
      }
4424
    };
4425
  }
4426

    
4427
  /**
4428
   * @private
4429
   * @param {Function} arrayEach
4430
   * @param {Function} baseEach
4431
   * @param {Function} symbolEach
4432
   * @param {boolean} bool
4433
   */
4434
  function createPick(arrayEach, baseEach, symbolEach, bool) {
4435
    return function(collection, iterator, callback) {
4436
      callback = callback || noop;
4437
      var size, keys;
4438
      var completed = 0;
4439
      var result = {};
4440

    
4441
      if (isArray(collection)) {
4442
        size = collection.length;
4443
        arrayEach(collection, iterator, createCallback);
4444
      } else if (!collection) {
4445
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4446
        size = symbolEach(collection, iterator, createCallback);
4447
        size && size === completed && callback(null, result);
4448
      } else if (typeof collection === obj) {
4449
        keys = nativeKeys(collection);
4450
        size = keys.length;
4451
        baseEach(collection, iterator, createCallback, keys);
4452
      }
4453
      if (!size) {
4454
        return callback(null, {});
4455
      }
4456

    
4457
      function createCallback(key, value) {
4458
        return function done(err, res) {
4459
          if (key === null) {
4460
            throwError();
4461
          }
4462
          if (err) {
4463
            key = null;
4464
            callback = once(callback);
4465
            callback(err, objectClone(result));
4466
            return;
4467
          }
4468
          if (!!res === bool) {
4469
            result[key] = value;
4470
          }
4471
          key = null;
4472
          if (++completed === size) {
4473
            callback(null, result);
4474
          }
4475
        };
4476
      }
4477
    };
4478
  }
4479

    
4480
  /**
4481
   * @private
4482
   * @param {boolean} bool
4483
   */
4484
  function createPickSeries(bool) {
4485
    return function(collection, iterator, callback) {
4486
      callback = onlyOnce(callback || noop);
4487
      var size, key, value, keys, iter, item, iterate;
4488
      var sync = false;
4489
      var result = {};
4490
      var completed = 0;
4491

    
4492
      if (isArray(collection)) {
4493
        size = collection.length;
4494
        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4495
      } else if (!collection) {
4496
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4497
        size = Infinity;
4498
        iter = collection[iteratorSymbol]();
4499
        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4500
      } else if (typeof collection === obj) {
4501
        keys = nativeKeys(collection);
4502
        size = keys.length;
4503
        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4504
      }
4505
      if (!size) {
4506
        return callback(null, {});
4507
      }
4508
      iterate();
4509

    
4510
      function arrayIterator() {
4511
        key = completed;
4512
        value = collection[completed];
4513
        iterator(value, done);
4514
      }
4515

    
4516
      function arrayIteratorWithIndex() {
4517
        key = completed;
4518
        value = collection[completed];
4519
        iterator(value, completed, done);
4520
      }
4521

    
4522
      function symbolIterator() {
4523
        key = completed;
4524
        item = iter.next();
4525
        value = item.value;
4526
        item.done ? callback(null, result) : iterator(value, done);
4527
      }
4528

    
4529
      function symbolIteratorWithKey() {
4530
        key = completed;
4531
        item = iter.next();
4532
        value = item.value;
4533
        item.done ? callback(null, result) : iterator(value, key, done);
4534
      }
4535

    
4536
      function objectIterator() {
4537
        key = keys[completed];
4538
        value = collection[key];
4539
        iterator(value, done);
4540
      }
4541

    
4542
      function objectIteratorWithKey() {
4543
        key = keys[completed];
4544
        value = collection[key];
4545
        iterator(value, key, done);
4546
      }
4547

    
4548
      function done(err, res) {
4549
        if (err) {
4550
          callback(err, result);
4551
          return;
4552
        }
4553
        if (!!res === bool) {
4554
          result[key] = value;
4555
        }
4556
        if (++completed === size) {
4557
          iterate = throwError;
4558
          callback(null, result);
4559
        } else if (sync) {
4560
          nextTick(iterate);
4561
        } else {
4562
          sync = true;
4563
          iterate();
4564
        }
4565
        sync = false;
4566
      }
4567
    };
4568
  }
4569

    
4570
  /**
4571
   * @private
4572
   * @param {boolean} bool
4573
   */
4574
  function createPickLimit(bool) {
4575
    return function(collection, limit, iterator, callback) {
4576
      callback = callback || noop;
4577
      var size, index, key, value, keys, iter, item, iterate;
4578
      var sync = false;
4579
      var result = {};
4580
      var started = 0;
4581
      var completed = 0;
4582

    
4583
      if (isArray(collection)) {
4584
        size = collection.length;
4585
        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4586
      } else if (!collection) {
4587
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4588
        size = Infinity;
4589
        iter = collection[iteratorSymbol]();
4590
        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4591
      } else if (typeof collection === obj) {
4592
        keys = nativeKeys(collection);
4593
        size = keys.length;
4594
        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4595
      }
4596
      if (!size || isNaN(limit) || limit < 1) {
4597
        return callback(null, {});
4598
      }
4599
      timesSync(limit > size ? size : limit, iterate);
4600

    
4601
      function arrayIterator() {
4602
        index = started++;
4603
        if (index < size) {
4604
          value = collection[index];
4605
          iterator(value, createCallback(value, index));
4606
        }
4607
      }
4608

    
4609
      function arrayIteratorWithIndex() {
4610
        index = started++;
4611
        if (index < size) {
4612
          value = collection[index];
4613
          iterator(value, index, createCallback(value, index));
4614
        }
4615
      }
4616

    
4617
      function symbolIterator() {
4618
        item = iter.next();
4619
        if (item.done === false) {
4620
          value = item.value;
4621
          iterator(value, createCallback(value, started++));
4622
        } else if (completed === started && iterator !== noop) {
4623
          iterator = noop;
4624
          callback(null, result);
4625
        }
4626
      }
4627

    
4628
      function symbolIteratorWithKey() {
4629
        item = iter.next();
4630
        if (item.done === false) {
4631
          value = item.value;
4632
          iterator(value, started, createCallback(value, started++));
4633
        } else if (completed === started && iterator !== noop) {
4634
          iterator = noop;
4635
          callback(null, result);
4636
        }
4637
      }
4638

    
4639
      function objectIterator() {
4640
        if (started < size) {
4641
          key = keys[started++];
4642
          value = collection[key];
4643
          iterator(value, createCallback(value, key));
4644
        }
4645
      }
4646

    
4647
      function objectIteratorWithKey() {
4648
        if (started < size) {
4649
          key = keys[started++];
4650
          value = collection[key];
4651
          iterator(value, key, createCallback(value, key));
4652
        }
4653
      }
4654

    
4655
      function createCallback(value, key) {
4656
        return function(err, res) {
4657
          if (key === null) {
4658
            throwError();
4659
          }
4660
          if (err) {
4661
            key = null;
4662
            iterate = noop;
4663
            callback = once(callback);
4664
            callback(err, objectClone(result));
4665
            return;
4666
          }
4667
          if (!!res === bool) {
4668
            result[key] = value;
4669
          }
4670
          key = null;
4671
          if (++completed === size) {
4672
            iterate = throwError;
4673
            callback = onlyOnce(callback);
4674
            callback(null, result);
4675
          } else if (sync) {
4676
            nextTick(iterate);
4677
          } else {
4678
            sync = true;
4679
            iterate();
4680
          }
4681
          sync = false;
4682
        };
4683
      }
4684
    };
4685
  }
4686

    
4687
  /**
4688
   * @memberof async
4689
   * @namespace reduce
4690
   * @param {Array|Object} collection
4691
   * @param {*} result
4692
   * @param {Function} iterator
4693
   * @param {Function} callback
4694
   * @example
4695
   *
4696
   * // array
4697
   * var order = [];
4698
   * var collection = [1, 3, 2, 4];
4699
   * var iterator = function(result, num, done) {
4700
   *   setTimeout(function() {
4701
   *     order.push(num);
4702
   *     done(null, result + num);
4703
   *   }, num * 10);
4704
   * };
4705
   * async.reduce(collection, 0, iterator, function(err, res) {
4706
   *   console.log(res); // 10
4707
   *   console.log(order); // [1, 3, 2, 4]
4708
   * });
4709
   *
4710
   * @example
4711
   *
4712
   * // array with index
4713
   * var order = [];
4714
   * var collection = [1, 3, 2, 4];
4715
   * var iterator = function(result, num, index, done) {
4716
   *   setTimeout(function() {
4717
   *     order.push([num, index]);
4718
   *     done(null, result + num);
4719
   *   }, num * 10);
4720
   * };
4721
   * async.reduce(collection, '', iterator, function(err, res) {
4722
   *   console.log(res); // '1324'
4723
   *   console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]]
4724
   * });
4725
   *
4726
   * @example
4727
   *
4728
   * // object
4729
   * var order = [];
4730
   * var object = { a: 1, b: 3, c: 2, d: 4 };
4731
   * var iterator = function(result, num, done) {
4732
   *   setTimeout(function() {
4733
   *     order.push(num);
4734
   *     done(null, result + num);
4735
   *   }, num * 10);
4736
   * };
4737
   * async.reduce(collection, '', iterator, function(err, res) {
4738
   *   console.log(res); // '1324'
4739
   *   console.log(order); // [1, 3, 2, 4]
4740
   * });
4741
   *
4742
   * @example
4743
   *
4744
   * // object with key
4745
   * var order = [];
4746
   * var object = { a: 1, b: 3, c: 2, d: 4 };
4747
   * var iterator = function(result, num, key, done) {
4748
   *   setTimeout(function() {
4749
   *     order.push([num, key]);
4750
   *     done(null, result + num);
4751
   *   }, num * 10);
4752
   * };
4753
   * async.reduce(collection, 0, iterator, function(err, res) {
4754
   *   console.log(res); // 10
4755
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']]
4756
   * });
4757
   *
4758
   */
4759
  function reduce(collection, result, iterator, callback) {
4760
    callback = onlyOnce(callback || noop);
4761
    var size, key, keys, iter, item, iterate;
4762
    var sync = false;
4763
    var completed = 0;
4764

    
4765
    if (isArray(collection)) {
4766
      size = collection.length;
4767
      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
4768
    } else if (!collection) {
4769
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
4770
      size = Infinity;
4771
      iter = collection[iteratorSymbol]();
4772
      iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
4773
    } else if (typeof collection === obj) {
4774
      keys = nativeKeys(collection);
4775
      size = keys.length;
4776
      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
4777
    }
4778
    if (!size) {
4779
      return callback(null, result);
4780
    }
4781
    iterate(result);
4782

    
4783
    function arrayIterator(result) {
4784
      iterator(result, collection[completed], done);
4785
    }
4786

    
4787
    function arrayIteratorWithIndex(result) {
4788
      iterator(result, collection[completed], completed, done);
4789
    }
4790

    
4791
    function symbolIterator(result) {
4792
      item = iter.next();
4793
      item.done ? callback(null, result) : iterator(result, item.value, done);
4794
    }
4795

    
4796
    function symbolIteratorWithKey(result) {
4797
      item = iter.next();
4798
      item.done ? callback(null, result) : iterator(result, item.value, completed, done);
4799
    }
4800

    
4801
    function objectIterator(result) {
4802
      iterator(result, collection[keys[completed]], done);
4803
    }
4804

    
4805
    function objectIteratorWithKey(result) {
4806
      key = keys[completed];
4807
      iterator(result, collection[key], key, done);
4808
    }
4809

    
4810
    function done(err, result) {
4811
      if (err) {
4812
        callback(err, result);
4813
      } else if (++completed === size) {
4814
        iterator = throwError;
4815
        callback(null, result);
4816
      } else if (sync) {
4817
        nextTick(function() {
4818
          iterate(result);
4819
        });
4820
      } else {
4821
        sync = true;
4822
        iterate(result);
4823
      }
4824
      sync = false;
4825
    }
4826
  }
4827

    
4828
  /**
4829
   * @memberof async
4830
   * @namespace reduceRight
4831
   * @param {Array|Object} collection
4832
   * @param {*} result
4833
   * @param {Function} iterator
4834
   * @param {Function} callback
4835
   * @example
4836
   *
4837
   * // array
4838
   * var order = [];
4839
   * var collection = [1, 3, 2, 4];
4840
   * var iterator = function(result, num, done) {
4841
   *   setTimeout(function() {
4842
   *     order.push(num);
4843
   *     done(null, result + num);
4844
   *   }, num * 10);
4845
   * };
4846
   * async.reduceRight(collection, 0, iterator, function(err, res) {
4847
   *   console.log(res); // 10
4848
   *   console.log(order); // [4, 2, 3, 1]
4849
   * });
4850
   *
4851
   * @example
4852
   *
4853
   * // array with index
4854
   * var order = [];
4855
   * var collection = [1, 3, 2, 4];
4856
   * var iterator = function(result, num, index, done) {
4857
   *   setTimeout(function() {
4858
   *     order.push([num, index]);
4859
   *     done(null, result + num);
4860
   *   }, num * 10);
4861
   * };
4862
   * async.reduceRight(collection, '', iterator, function(err, res) {
4863
   *   console.log(res); // '4231'
4864
   *   console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]]
4865
   * });
4866
   *
4867
   * @example
4868
   *
4869
   * // object
4870
   * var order = [];
4871
   * var object = { a: 1, b: 3, c: 2, d: 4 };
4872
   * var iterator = function(result, num, done) {
4873
   *   setTimeout(function() {
4874
   *     order.push(num);
4875
   *     done(null, result + num);
4876
   *   }, num * 10);
4877
   * };
4878
   * async.reduceRight(collection, '', iterator, function(err, res) {
4879
   *   console.log(res); // '4231'
4880
   *   console.log(order); // [4, 2, 3, 1]
4881
   * });
4882
   *
4883
   * @example
4884
   *
4885
   * // object with key
4886
   * var order = [];
4887
   * var object = { a: 1, b: 3, c: 2, d: 4 };
4888
   * var iterator = function(result, num, key, done) {
4889
   *   setTimeout(function() {
4890
   *     order.push([num, key]);
4891
   *     done(null, result + num);
4892
   *   }, num * 10);
4893
   * };
4894
   * async.reduceRight(collection, 0, iterator, function(err, res) {
4895
   *   console.log(res); // 10
4896
   *   console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]]
4897
   * });
4898
   *
4899
   */
4900
  function reduceRight(collection, result, iterator, callback) {
4901
    callback = onlyOnce(callback || noop);
4902
    var resIndex, index, key, keys, iter, item, col, iterate;
4903
    var sync = false;
4904

    
4905
    if (isArray(collection)) {
4906
      resIndex = collection.length;
4907
      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
4908
    } else if (!collection) {
4909
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
4910
      col = [];
4911
      iter = collection[iteratorSymbol]();
4912
      index = -1;
4913
      while ((item = iter.next()).done === false) {
4914
        col[++index] = item.value;
4915
      }
4916
      collection = col;
4917
      resIndex = col.length;
4918
      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
4919
    } else if (typeof collection === obj) {
4920
      keys = nativeKeys(collection);
4921
      resIndex = keys.length;
4922
      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
4923
    }
4924
    if (!resIndex) {
4925
      return callback(null, result);
4926
    }
4927
    iterate(result);
4928

    
4929
    function arrayIterator(result) {
4930
      iterator(result, collection[--resIndex], done);
4931
    }
4932

    
4933
    function arrayIteratorWithIndex(result) {
4934
      iterator(result, collection[--resIndex], resIndex, done);
4935
    }
4936

    
4937
    function objectIterator(result) {
4938
      iterator(result, collection[keys[--resIndex]], done);
4939
    }
4940

    
4941
    function objectIteratorWithKey(result) {
4942
      key = keys[--resIndex];
4943
      iterator(result, collection[key], key, done);
4944
    }
4945

    
4946
    function done(err, result) {
4947
      if (err) {
4948
        callback(err, result);
4949
      } else if (resIndex === 0) {
4950
        iterate = throwError;
4951
        callback(null, result);
4952
      } else if (sync) {
4953
        nextTick(function() {
4954
          iterate(result);
4955
        });
4956
      } else {
4957
        sync = true;
4958
        iterate(result);
4959
      }
4960
      sync = false;
4961
    }
4962
  }
4963

    
4964
  /**
4965
   * @private
4966
   * @param {Function} arrayEach
4967
   * @param {Function} baseEach
4968
   * @param {Function} symbolEach
4969
   */
4970
  function createTransform(arrayEach, baseEach, symbolEach) {
4971
    return function transform(collection, accumulator, iterator, callback) {
4972
      if (arguments.length === 3) {
4973
        callback = iterator;
4974
        iterator = accumulator;
4975
        accumulator = undefined;
4976
      }
4977
      callback = callback || noop;
4978
      var size, keys, result;
4979
      var completed = 0;
4980

    
4981
      if (isArray(collection)) {
4982
        size = collection.length;
4983
        result = accumulator !== undefined ? accumulator : [];
4984
        arrayEach(collection, result, iterator, done);
4985
      } else if (!collection) {
4986
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
4987
        result = accumulator !== undefined ? accumulator : {};
4988
        size = symbolEach(collection, result, iterator, done);
4989
        size && size === completed && callback(null, result);
4990
      } else if (typeof collection === obj) {
4991
        keys = nativeKeys(collection);
4992
        size = keys.length;
4993
        result = accumulator !== undefined ? accumulator : {};
4994
        baseEach(collection, result, iterator, done, keys);
4995
      }
4996
      if (!size) {
4997
        callback(null, accumulator !== undefined ? accumulator : result || {});
4998
      }
4999

    
5000
      function done(err, bool) {
5001
        if (err) {
5002
          callback = once(callback);
5003
          callback(err, isArray(result) ? createArray(result) : objectClone(result));
5004
        } else if (++completed === size) {
5005
          callback(null, result);
5006
        } else if (bool === false) {
5007
          callback = once(callback);
5008
          callback(null, isArray(result) ? createArray(result) : objectClone(result));
5009
        }
5010
      }
5011
    };
5012
  }
5013

    
5014
  /**
5015
   * @memberof async
5016
   * @namespace transformSeries
5017
   * @param {Array|Object} collection
5018
   * @param {Array|Object|Function} [accumulator]
5019
   * @param {Function} [iterator]
5020
   * @param {Function} [callback]
5021
   * @example
5022
   *
5023
   * // array
5024
   * var order = [];
5025
   * var collection = [1, 3, 2, 4];
5026
   * var iterator = function(result, num, done) {
5027
   *   setTimeout(function() {
5028
   *     order.push(num);
5029
   *     result.push(num)
5030
   *     done();
5031
   *   }, num * 10);
5032
   * };
5033
   * async.transformSeries(collection, iterator, function(err, res) {
5034
   *   console.log(res); // [1, 3, 2, 4]
5035
   *   console.log(order); // [1, 3, 2, 4]
5036
   * });
5037
   *
5038
   * @example
5039
   *
5040
   * // array with index and accumulator
5041
   * var order = [];
5042
   * var collection = [1, 3, 2, 4];
5043
   * var iterator = function(result, num, index, done) {
5044
   *   setTimeout(function() {
5045
   *     order.push([num, index]);
5046
   *     result[index] = num;
5047
   *     done();
5048
   *   }, num * 10);
5049
   * };
5050
   * async.transformSeries(collection, {}, iterator, function(err, res) {
5051
   *   console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 }
5052
   *   console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]]
5053
   * });
5054
   *
5055
   * @example
5056
   *
5057
   * // object with accumulator
5058
   * var order = [];
5059
   * var object = { a: 1, b: 3, c: 2, d: 4 };
5060
   * var iterator = function(result, num, done) {
5061
   *   setTimeout(function() {
5062
   *     order.push(num);
5063
   *     result.push(num);
5064
   *     done();
5065
   *   }, num * 10);
5066
   * };
5067
   * async.transformSeries(collection, [], iterator, function(err, res) {
5068
   *   console.log(res); // [1, 3, 2, 4]
5069
   *   console.log(order); // [1, 3, 2, 4]
5070
   * });
5071
   *
5072
   * @example
5073
   *
5074
   * // object with key
5075
   * var order = [];
5076
   * var object = { a: 1, b: 3, c: 2, d: 4 };
5077
   * var iterator = function(result, num, key, done) {
5078
   *   setTimeout(function() {
5079
   *     order.push([num, key]);
5080
   *     result[key] = num;
5081
   *     done();
5082
   *   }, num * 10);
5083
   * };
5084
   * async.transformSeries(collection, iterator, function(err, res) {
5085
   *   console.log(res); //  { a: 1, b: 3, c: 2, d: 4 }
5086
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']]
5087
   * });
5088
   *
5089
   */
5090
  function transformSeries(collection, accumulator, iterator, callback) {
5091
    if (arguments.length === 3) {
5092
      callback = iterator;
5093
      iterator = accumulator;
5094
      accumulator = undefined;
5095
    }
5096
    callback = onlyOnce(callback || noop);
5097
    var size, key, keys, iter, item, iterate, result;
5098
    var sync = false;
5099
    var completed = 0;
5100

    
5101
    if (isArray(collection)) {
5102
      size = collection.length;
5103
      result = accumulator !== undefined ? accumulator : [];
5104
      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
5105
    } else if (!collection) {
5106
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
5107
      size = Infinity;
5108
      iter = collection[iteratorSymbol]();
5109
      result = accumulator !== undefined ? accumulator : {};
5110
      iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
5111
    } else if (typeof collection === obj) {
5112
      keys = nativeKeys(collection);
5113
      size = keys.length;
5114
      result = accumulator !== undefined ? accumulator : {};
5115
      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
5116
    }
5117
    if (!size) {
5118
      return callback(null, accumulator !== undefined ? accumulator : result || {});
5119
    }
5120
    iterate();
5121

    
5122
    function arrayIterator() {
5123
      iterator(result, collection[completed], done);
5124
    }
5125

    
5126
    function arrayIteratorWithIndex() {
5127
      iterator(result, collection[completed], completed, done);
5128
    }
5129

    
5130
    function symbolIterator() {
5131
      item = iter.next();
5132
      item.done ? callback(null, result) : iterator(result, item.value, done);
5133
    }
5134

    
5135
    function symbolIteratorWithKey() {
5136
      item = iter.next();
5137
      item.done ? callback(null, result) : iterator(result, item.value, completed, done);
5138
    }
5139

    
5140
    function objectIterator() {
5141
      iterator(result, collection[keys[completed]], done);
5142
    }
5143

    
5144
    function objectIteratorWithKey() {
5145
      key = keys[completed];
5146
      iterator(result, collection[key], key, done);
5147
    }
5148

    
5149
    function done(err, bool) {
5150
      if (err) {
5151
        callback(err, result);
5152
      } else if (++completed === size || bool === false) {
5153
        iterate = throwError;
5154
        callback(null, result);
5155
      } else if (sync) {
5156
        nextTick(iterate);
5157
      } else {
5158
        sync = true;
5159
        iterate();
5160
      }
5161
      sync = false;
5162
    }
5163
  }
5164

    
5165
  /**
5166
   * @memberof async
5167
   * @namespace transformLimit
5168
   * @param {Array|Object} collection
5169
   * @param {number} limit - limit >= 1
5170
   * @param {Array|Object|Function} [accumulator]
5171
   * @param {Function} [iterator]
5172
   * @param {Function} [callback]
5173
   * @example
5174
   *
5175
   * // array
5176
   * var order = [];
5177
   * var array = [1, 5, 3, 4, 2];
5178
   * var iterator = function(result, num, done) {
5179
   *   setTimeout(function() {
5180
   *     order.push(num);
5181
   *     result.push(num);
5182
   *     done();
5183
   *   }, num * 10);
5184
   * };
5185
   * async.transformLimit(array, 2, iterator, function(err, res) {
5186
   *   console.log(res); // [1, 3, 5, 2, 4]
5187
   *   console.log(order); // [1, 3, 5, 2, 4]
5188
   * });
5189
   *
5190
   * @example
5191
   *
5192
   * // array with index and accumulator
5193
   * var order = [];
5194
   * var array = [1, 5, 3, 4, 2];
5195
   * var iterator = function(result, num, index, done) {
5196
   *   setTimeout(function() {
5197
   *     order.push([num, index]);
5198
   *     result[index] = key;
5199
   *     done();
5200
   *   }, num * 10);
5201
   * };
5202
   * async.transformLimit(array, 2, {}, iterator, function(err, res) {
5203
   *   console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
5204
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
5205
   * });
5206
   *
5207
   * @example
5208
   *
5209
   * // object with accumulator
5210
   * var order = [];
5211
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5212
   * var iterator = function(result, num, done) {
5213
   *   setTimeout(function() {
5214
   *     order.push(num);
5215
   *     result.push(num);
5216
   *     done();
5217
   *   }, num * 10);
5218
   * };
5219
   * async.transformLimit(object, 2, [], iterator, function(err, res) {
5220
   *   console.log(res); // [1, 3, 5, 2, 4]
5221
   *   console.log(order); // [1, 3, 5, 2, 4]
5222
   * });
5223
   *
5224
   * @example
5225
   *
5226
   * // object with key
5227
   * var order = [];
5228
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5229
   * var iterator = function(result, num, key, done) {
5230
   *   setTimeout(function() {
5231
   *     order.push([num, key]);
5232
   *     result[key] = num;
5233
   *     done();
5234
   *   }, num * 10);
5235
   * };
5236
   * async.transformLimit(object, 2, iterator, function(err, res) {
5237
   *   console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 };
5238
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
5239
   * });
5240
   *
5241
   */
5242
  function transformLimit(collection, limit, accumulator, iterator, callback) {
5243
    if (arguments.length === 4) {
5244
      callback = iterator;
5245
      iterator = accumulator;
5246
      accumulator = undefined;
5247
    }
5248
    callback = callback || noop;
5249
    var size, index, key, keys, iter, item, iterate, result;
5250
    var sync = false;
5251
    var started = 0;
5252
    var completed = 0;
5253

    
5254
    if (isArray(collection)) {
5255
      size = collection.length;
5256
      result = accumulator !== undefined ? accumulator : [];
5257
      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
5258
    } else if (!collection) {
5259
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
5260
      size = Infinity;
5261
      iter = collection[iteratorSymbol]();
5262
      result = accumulator !== undefined ? accumulator : {};
5263
      iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
5264
    } else if (typeof collection === obj) {
5265
      keys = nativeKeys(collection);
5266
      size = keys.length;
5267
      result = accumulator !== undefined ? accumulator : {};
5268
      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
5269
    }
5270
    if (!size || isNaN(limit) || limit < 1) {
5271
      return callback(null, accumulator !== undefined ? accumulator : result || {});
5272
    }
5273
    timesSync(limit > size ? size : limit, iterate);
5274

    
5275
    function arrayIterator() {
5276
      index = started++;
5277
      if (index < size) {
5278
        iterator(result, collection[index], onlyOnce(done));
5279
      }
5280
    }
5281

    
5282
    function arrayIteratorWithIndex() {
5283
      index = started++;
5284
      if (index < size) {
5285
        iterator(result, collection[index], index, onlyOnce(done));
5286
      }
5287
    }
5288

    
5289
    function symbolIterator() {
5290
      item = iter.next();
5291
      if (item.done === false) {
5292
        started++;
5293
        iterator(result, item.value, onlyOnce(done));
5294
      } else if (completed === started && iterator !== noop) {
5295
        iterator = noop;
5296
        callback(null, result);
5297
      }
5298
    }
5299

    
5300
    function symbolIteratorWithKey() {
5301
      item = iter.next();
5302
      if (item.done === false) {
5303
        iterator(result, item.value, started++, onlyOnce(done));
5304
      } else if (completed === started && iterator !== noop) {
5305
        iterator = noop;
5306
        callback(null, result);
5307
      }
5308
    }
5309

    
5310
    function objectIterator() {
5311
      index = started++;
5312
      if (index < size) {
5313
        iterator(result, collection[keys[index]], onlyOnce(done));
5314
      }
5315
    }
5316

    
5317
    function objectIteratorWithKey() {
5318
      index = started++;
5319
      if (index < size) {
5320
        key = keys[index];
5321
        iterator(result, collection[key], key, onlyOnce(done));
5322
      }
5323
    }
5324

    
5325
    function done(err, bool) {
5326
      if (err || bool === false) {
5327
        iterate = noop;
5328
        callback(err || null, isArray(result) ? createArray(result) : objectClone(result));
5329
        callback = noop;
5330
      } else if (++completed === size) {
5331
        iterator = noop;
5332
        callback(null, result);
5333
      } else if (sync) {
5334
        nextTick(iterate);
5335
      } else {
5336
        sync = true;
5337
        iterate();
5338
      }
5339
      sync = false;
5340
    }
5341
  }
5342

    
5343
  /**
5344
   * @private
5345
   * @param {function} arrayEach
5346
   * @param {function} baseEach
5347
   * @param {function} symbolEach
5348
   */
5349
  function createSortBy(arrayEach, baseEach, symbolEach) {
5350
    return function sortBy(collection, iterator, callback) {
5351
      callback = callback || noop;
5352
      var size, array, criteria;
5353
      var completed = 0;
5354

    
5355
      if (isArray(collection)) {
5356
        size = collection.length;
5357
        array = Array(size);
5358
        criteria = Array(size);
5359
        arrayEach(collection, iterator, createCallback);
5360
      } else if (!collection) {
5361
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
5362
        array = [];
5363
        criteria = [];
5364
        size = symbolEach(collection, iterator, createCallback);
5365
        size && size === completed && callback(null, sortByCriteria(array, criteria));
5366
      } else if (typeof collection === obj) {
5367
        var keys = nativeKeys(collection);
5368
        size = keys.length;
5369
        array = Array(size);
5370
        criteria = Array(size);
5371
        baseEach(collection, iterator, createCallback, keys);
5372
      }
5373
      if (!size) {
5374
        callback(null, []);
5375
      }
5376

    
5377
      function createCallback(index, value) {
5378
        var called = false;
5379
        array[index] = value;
5380
        return function done(err, criterion) {
5381
          if (called) {
5382
            throwError();
5383
          }
5384
          called = true;
5385
          criteria[index] = criterion;
5386
          if (err) {
5387
            callback = once(callback);
5388
            callback(err);
5389
          } else if (++completed === size) {
5390
            callback(null, sortByCriteria(array, criteria));
5391
          }
5392
        };
5393
      }
5394
    };
5395
  }
5396

    
5397
  /**
5398
   * @memberof async
5399
   * @namespace sortBySeries
5400
   * @param {Array|Object} collection
5401
   * @param {Function} iterator
5402
   * @param {Function} callback
5403
   * @example
5404
   *
5405
   * // array
5406
   * var order = [];
5407
   * var array = [1, 3, 2];
5408
   * var iterator = function(num, done) {
5409
   *   setTimeout(function() {
5410
   *     order.push(num);
5411
   *     done(null, num);
5412
   *   }, num * 10);
5413
   * };
5414
   * async.sortBySeries(array, iterator, function(err, res) {
5415
   *   console.log(res); // [1, 2, 3];
5416
   *   console.log(order); // [1, 3, 2]
5417
   * });
5418
   *
5419
   * @example
5420
   *
5421
   * // array with index
5422
   * var order = [];
5423
   * var array = [1, 3, 2];
5424
   * var iterator = function(num, index, done) {
5425
   *   setTimeout(function() {
5426
   *     order.push([num, index]);
5427
   *     done(null, num);
5428
   *   }, num * 10);
5429
   * };
5430
   * async.sortBySeries(array, iterator, function(err, res) {
5431
   *   console.log(res); // [1, 2, 3]
5432
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
5433
   * });
5434
   *
5435
   * @example
5436
   *
5437
   * // object
5438
   * var order = [];
5439
   * var object = { a: 1, b: 3, c: 2 };
5440
   * var iterator = function(num, done) {
5441
   *   setTimeout(function() {
5442
   *     order.push(num);
5443
   *     done(null, num);
5444
   *   }, num * 10);
5445
   * };
5446
   * async.sortBySeries(object, iterator, function(err, res) {
5447
   *   console.log(res); // [1, 2, 3]
5448
   *   console.log(order); // [1, 3, 2]
5449
   * });
5450
   *
5451
   * @example
5452
   *
5453
   * // object with key
5454
   * var order = [];
5455
   * var object = { a: 1, b: 3, c: 2 };
5456
   * var iterator = function(num, key, done) {
5457
   *   setTimeout(function() {
5458
   *     order.push([num, key]);
5459
   *     done(null, num);
5460
   *   }, num * 10);
5461
   * };
5462
   * async.sortBySeries(object, iterator, function(err, res) {
5463
   *   console.log(res); // [1, 2, 3]
5464
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
5465
   * });
5466
   *
5467
   */
5468
  function sortBySeries(collection, iterator, callback) {
5469
    callback = onlyOnce(callback || noop);
5470
    var size, key, value, keys, iter, item, array, criteria, iterate;
5471
    var sync = false;
5472
    var completed = 0;
5473

    
5474
    if (isArray(collection)) {
5475
      size = collection.length;
5476
      array = collection;
5477
      criteria = Array(size);
5478
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
5479
    } else if (!collection) {
5480
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
5481
      size = Infinity;
5482
      array = [];
5483
      criteria = [];
5484
      iter = collection[iteratorSymbol]();
5485
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
5486
    } else if (typeof collection === obj) {
5487
      keys = nativeKeys(collection);
5488
      size = keys.length;
5489
      array = Array(size);
5490
      criteria = Array(size);
5491
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
5492
    }
5493
    if (!size) {
5494
      return callback(null, []);
5495
    }
5496
    iterate();
5497

    
5498
    function arrayIterator() {
5499
      value = collection[completed];
5500
      iterator(value, done);
5501
    }
5502

    
5503
    function arrayIteratorWithIndex() {
5504
      value = collection[completed];
5505
      iterator(value, completed, done);
5506
    }
5507

    
5508
    function symbolIterator() {
5509
      item = iter.next();
5510
      if (item.done) {
5511
        return callback(null, sortByCriteria(array, criteria));
5512
      }
5513
      value = item.value;
5514
      array[completed] = value;
5515
      iterator(value, done);
5516
    }
5517

    
5518
    function symbolIteratorWithKey() {
5519
      item = iter.next();
5520
      if (item.done) {
5521
        return callback(null, sortByCriteria(array, criteria));
5522
      }
5523
      value = item.value;
5524
      array[completed] = value;
5525
      iterator(value, completed, done);
5526
    }
5527

    
5528
    function objectIterator() {
5529
      value = collection[keys[completed]];
5530
      array[completed] = value;
5531
      iterator(value, done);
5532
    }
5533

    
5534
    function objectIteratorWithKey() {
5535
      key = keys[completed];
5536
      value = collection[key];
5537
      array[completed] = value;
5538
      iterator(value, key, done);
5539
    }
5540

    
5541
    function done(err, criterion) {
5542
      criteria[completed] = criterion;
5543
      if (err) {
5544
        callback(err);
5545
      } else if (++completed === size) {
5546
        iterate = throwError;
5547
        callback(null, sortByCriteria(array, criteria));
5548
      } else if (sync) {
5549
        nextTick(iterate);
5550
      } else {
5551
        sync = true;
5552
        iterate();
5553
      }
5554
      sync = false;
5555
    }
5556
  }
5557

    
5558
  /**
5559
   * @memberof async
5560
   * @namespace sortByLimit
5561
   * @param {Array|Object} collection
5562
   * @param {number} limit - limit >= 1
5563
   * @param {Function} iterator
5564
   * @param {Function} callback
5565
   * @example
5566
   *
5567
   * // array
5568
   * var order = [];
5569
   * var array = [1, 5, 3, 4, 2];
5570
   * var iterator = function(num, done) {
5571
   *   setTimeout(function() {
5572
   *     order.push(num);
5573
   *     done(null, num);
5574
   *   }, num * 10);
5575
   * };
5576
   * async.sortByLimit(array, 2, iterator, function(err, res) {
5577
   *   console.log(res); // [1, 2, 3, 4, 5]
5578
   *   console.log(order); // [1, 3, 5, 2, 4]
5579
   * });
5580
   *
5581
   * @example
5582
   *
5583
   * // array with index
5584
   * var order = [];
5585
   * var array = [1, 5, 3, 4, 2];
5586
   * var iterator = function(num, index, done) {
5587
   *   setTimeout(function() {
5588
   *     order.push([num, index]);
5589
   *     done(null, num);
5590
   *   }, num * 10);
5591
   * };
5592
   * async.sortByLimit(array, 2, iterator, function(err, res) {
5593
   *   console.log(res); // [1, 2, 3, 4, 5]
5594
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
5595
   * });
5596
   *
5597
   * @example
5598
   *
5599
   * // object
5600
   * var order = [];
5601
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5602
   * var iterator = function(num, done) {
5603
   *   setTimeout(function() {
5604
   *     order.push(num);
5605
   *     done(null, num);
5606
   *   }, num * 10);
5607
   * };
5608
   * async.sortByLimit(object, 2, iterator, function(err, res) {
5609
   *   console.log(res); // [1, 2, 3, 4, 5]
5610
   *   console.log(order); // [1, 3, 5, 2, 4]
5611
   * });
5612
   *
5613
   * @example
5614
   *
5615
   * // object with key
5616
   * var order = [];
5617
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5618
   * var iterator = function(num, key, done) {
5619
   *   setTimeout(function() {
5620
   *     order.push([num, key]);
5621
   *     done(null, num);
5622
   *   }, num * 10);
5623
   * };
5624
   * async.sortByLimit(object, 2, iterator, function(err, res) {
5625
   *   console.log(res); // [1, 2, 3, 4, 5]
5626
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
5627
   * });
5628
   *
5629
   */
5630
  function sortByLimit(collection, limit, iterator, callback) {
5631
    callback = callback || noop;
5632
    var size, index, key, value, array, keys, iter, item, criteria, iterate;
5633
    var sync = false;
5634
    var started = 0;
5635
    var completed = 0;
5636

    
5637
    if (isArray(collection)) {
5638
      size = collection.length;
5639
      array = collection;
5640
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
5641
    } else if (!collection) {
5642
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
5643
      size = Infinity;
5644
      iter = collection[iteratorSymbol]();
5645
      array = [];
5646
      criteria = [];
5647
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
5648
    } else if (typeof collection === obj) {
5649
      keys = nativeKeys(collection);
5650
      size = keys.length;
5651
      array = Array(size);
5652
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
5653
    }
5654
    if (!size || isNaN(limit) || limit < 1) {
5655
      return callback(null, []);
5656
    }
5657
    criteria = criteria || Array(size);
5658
    timesSync(limit > size ? size : limit, iterate);
5659

    
5660
    function arrayIterator() {
5661
      if (started < size) {
5662
        value = collection[started];
5663
        iterator(value, createCallback(value, started++));
5664
      }
5665
    }
5666

    
5667
    function arrayIteratorWithIndex() {
5668
      index = started++;
5669
      if (index < size) {
5670
        value = collection[index];
5671
        iterator(value, index, createCallback(value, index));
5672
      }
5673
    }
5674

    
5675
    function symbolIterator() {
5676
      item = iter.next();
5677
      if (item.done === false) {
5678
        value = item.value;
5679
        array[started] = value;
5680
        iterator(value, createCallback(value, started++));
5681
      } else if (completed === started && iterator !== noop) {
5682
        iterator = noop;
5683
        callback(null, sortByCriteria(array, criteria));
5684
      }
5685
    }
5686

    
5687
    function symbolIteratorWithKey() {
5688
      item = iter.next();
5689
      if (item.done === false) {
5690
        value = item.value;
5691
        array[started] = value;
5692
        iterator(value, started, createCallback(value, started++));
5693
      } else if (completed === started && iterator !== noop) {
5694
        iterator = noop;
5695
        callback(null, sortByCriteria(array, criteria));
5696
      }
5697
    }
5698

    
5699
    function objectIterator() {
5700
      if (started < size) {
5701
        value = collection[keys[started]];
5702
        array[started] = value;
5703
        iterator(value, createCallback(value, started++));
5704
      }
5705
    }
5706

    
5707
    function objectIteratorWithKey() {
5708
      if (started < size) {
5709
        key = keys[started];
5710
        value = collection[key];
5711
        array[started] = value;
5712
        iterator(value, key, createCallback(value, started++));
5713
      }
5714
    }
5715

    
5716
    function createCallback(value, index) {
5717
      var called = false;
5718
      return function(err, criterion) {
5719
        if (called) {
5720
          throwError();
5721
        }
5722
        called = true;
5723
        criteria[index] = criterion;
5724
        if (err) {
5725
          iterate = noop;
5726
          callback(err);
5727
          callback = noop;
5728
        } else if (++completed === size) {
5729
          callback(null, sortByCriteria(array, criteria));
5730
        } else if (sync) {
5731
          nextTick(iterate);
5732
        } else {
5733
          sync = true;
5734
          iterate();
5735
        }
5736
        sync = false;
5737
      };
5738
    }
5739
  }
5740

    
5741
  /**
5742
   * @memberof async
5743
   * @namespace some
5744
   * @param {Array|Object} collection
5745
   * @param {Function} iterator
5746
   * @param {Function} callback
5747
   * @example
5748
   *
5749
   * // array
5750
   * var order = [];
5751
   * var array = [1, 3, 2];
5752
   * var iterator = function(num, done) {
5753
   *   setTimeout(function() {
5754
   *     order.push(num);
5755
   *     done(null, num % 2);
5756
   *   }, num * 10);
5757
   * };
5758
   * async.some(array, iterator, function(err, res) {
5759
   *   console.log(res); // true
5760
   *   console.log(order); // [1]
5761
   * });
5762
   *
5763
   * @example
5764
   *
5765
   * // array with index
5766
   * var order = [];
5767
   * var array = [1, 3, 2];
5768
   * var iterator = function(num, index, done) {
5769
   *   setTimeout(function() {
5770
   *     order.push([num, index]);
5771
   *     done(null, num % 2);
5772
   *   }, num * 10);
5773
   * };
5774
   * async.some(array, iterator, function(err, res) {
5775
   *   console.log(res); // true
5776
   *   console.log(order); // [[1, 0]]
5777
   * });
5778
   *
5779
   * @example
5780
   *
5781
   * // object
5782
   * var order = [];
5783
   * var object = { a: 1, b: 3, c: 2 };
5784
   * var iterator = function(num, done) {
5785
   *   setTimeout(function() {
5786
   *     order.push(num);
5787
   *     done(null, num % 2);
5788
   *   }, num * 10);
5789
   * };
5790
   * async.some(object, iterator, function(err, res) {
5791
   *   console.log(res); // true
5792
   *   console.log(order); // [1]
5793
   * });
5794
   *
5795
   * @example
5796
   *
5797
   * // object with key
5798
   * var order = [];
5799
   * var object = { a: 1, b: 3, c: 2 };
5800
   * var iterator = function(num, key, done) {
5801
   *   setTimeout(function() {
5802
   *     order.push([num, key]);
5803
   *     done(null, num % 2);
5804
   *   }, num * 10);
5805
   * };
5806
   * async.some(object, iterator, function(err, res) {
5807
   *   console.log(res); // true
5808
   *   console.log(order); // [[1, 'a']]
5809
   * });
5810
   *
5811
   */
5812
  function some(collection, iterator, callback) {
5813
    callback = callback || noop;
5814
    detect(collection, iterator, done);
5815

    
5816
    function done(err, res) {
5817
      if (err) {
5818
        return callback(err);
5819
      }
5820
      callback(null, !!res);
5821
    }
5822
  }
5823

    
5824
  /**
5825
   * @memberof async
5826
   * @namespace someSeries
5827
   * @param {Array|Object} collection
5828
   * @param {Function} iterator
5829
   * @param {Function} callback
5830
   * @example
5831
   *
5832
   * // array
5833
   * var order = [];
5834
   * var array = [1, 3, 2];
5835
   * var iterator = function(num, done) {
5836
   *   setTimeout(function() {
5837
   *     order.push(num);
5838
   *     done(null, num % 2);
5839
   *   }, num * 10);
5840
   * };
5841
   * async.someSeries(array, iterator, function(err, res) {
5842
   *   console.log(res); // true
5843
   *   console.log(order); // [1]
5844
   * });
5845
   *
5846
   * @example
5847
   *
5848
   * // array with index
5849
   * var order = [];
5850
   * var array = [1, 3, 2];
5851
   * var iterator = function(num, index, done) {
5852
   *   setTimeout(function() {
5853
   *     order.push([num, index]);
5854
   *     done(null, num % 2);
5855
   *   }, num * 10);
5856
   * };
5857
   * async.someSeries(array, iterator, function(err, res) {
5858
   *   console.log(res); // true
5859
   *   console.log(order); // [[1, 0]]
5860
   * });
5861
   *
5862
   * @example
5863
   *
5864
   * // object
5865
   * var order = [];
5866
   * var object = { a: 1, b: 3, c: 2 };
5867
   * var iterator = function(num, done) {
5868
   *   setTimeout(function() {
5869
   *     order.push(num);
5870
   *     done(null, num % 2);
5871
   *   }, num * 10);
5872
   * };
5873
   * async.someSeries(object, iterator, function(err, res) {
5874
   *   console.log(res); // true
5875
   *   console.log(order); // [1]
5876
   * });
5877
   *
5878
   * @example
5879
   *
5880
   * // object with key
5881
   * var order = [];
5882
   * var object = { a: 1, b: 3, c: 2 };
5883
   * var iterator = function(num, key, done) {
5884
   *   setTimeout(function() {
5885
   *     order.push([num, key]);
5886
   *     done(null, num % 2);
5887
   *   }, num * 10);
5888
   * };
5889
   * async.someSeries(object, iterator, function(err, res) {
5890
   *   console.log(res); // true
5891
   *   console.log(order); // [[1, 'a']]
5892
   * });
5893
   *
5894
   */
5895
  function someSeries(collection, iterator, callback) {
5896
    callback = callback || noop;
5897
    detectSeries(collection, iterator, done);
5898

    
5899
    function done(err, res) {
5900
      if (err) {
5901
        return callback(err);
5902
      }
5903
      callback(null, !!res);
5904
    }
5905
  }
5906

    
5907
  /**
5908
   * @memberof async
5909
   * @namespace someLimit
5910
   * @param {Array|Object} collection
5911
   * @param {number} limit - limit >= 1
5912
   * @param {Function} iterator
5913
   * @param {Function} callback
5914
   * @example
5915
   *
5916
   * // array
5917
   * var order = [];
5918
   * var array = [1, 5, 3, 4, 2];
5919
   * var iterator = function(num, done) {
5920
   *   setTimeout(function() {
5921
   *     order.push(num);
5922
   *     done(null, num % 2);
5923
   *   }, num * 10);
5924
   * };
5925
   * async.someLimit(array, 2, iterator, function(err, res) {
5926
   *   console.log(res); // true
5927
   *   console.log(order); // [1]
5928
   * });
5929
   *
5930
   * @example
5931
   *
5932
   * // array with index
5933
   * var order = [];
5934
   * var array = [1, 5, 3, 4, 2];
5935
   * var iterator = function(num, index, done) {
5936
   *   setTimeout(function() {
5937
   *     order.push([num, index]);
5938
   *     done(null, num % 2);
5939
   *   }, num * 10);
5940
   * };
5941
   * async.someLimit(array, 2, iterator, function(err, res) {
5942
   *   console.log(res); // true
5943
   *   console.log(order); // [[1, 0]]
5944
   * });
5945
   *
5946
   * @example
5947
   *
5948
   * // object
5949
   * var order = [];
5950
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5951
   * var iterator = function(num, done) {
5952
   *   setTimeout(function() {
5953
   *     order.push(num);
5954
   *     done(null, num % 2);
5955
   *   }, num * 10);
5956
   * };
5957
   * async.someLimit(object, 2, iterator, function(err, res) {
5958
   *   console.log(res); // true
5959
   *   console.log(order); // [1]
5960
   * });
5961
   *
5962
   * @example
5963
   *
5964
   * // object with key
5965
   * var order = [];
5966
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5967
   * var iterator = function(num, key, done) {
5968
   *   setTimeout(function() {
5969
   *     order.push([num, key]);
5970
   *     done(null, num % 2);
5971
   *   }, num * 10);
5972
   * };
5973
   * async.someLimit(object, 2, iterator, function(err, res) {
5974
   *   console.log(res); // true
5975
   *   console.log(order); // [[1, 'a']]
5976
   * });
5977
   *
5978
   */
5979
  function someLimit(collection, limit, iterator, callback) {
5980
    callback = callback || noop;
5981
    detectLimit(collection, limit, iterator, done);
5982

    
5983
    function done(err, res) {
5984
      if (err) {
5985
        return callback(err);
5986
      }
5987
      callback(null, !!res);
5988
    }
5989
  }
5990

    
5991
  /**
5992
   * @private
5993
   * @param {Function} arrayEach
5994
   * @param {Function} baseEach
5995
   * @param {Function} symbolEach
5996
   */
5997
  function createEvery(arrayEach, baseEach, symbolEach) {
5998
    var deny = createDetect(arrayEach, baseEach, symbolEach, false);
5999

    
6000
    return function every(collection, iterator, callback) {
6001
      callback = callback || noop;
6002
      deny(collection, iterator, done);
6003

    
6004
      function done(err, res) {
6005
        if (err) {
6006
          return callback(err);
6007
        }
6008
        callback(null, !res);
6009
      }
6010
    };
6011
  }
6012

    
6013
  /**
6014
   * @private
6015
   */
6016
  function createEverySeries() {
6017
    var denySeries = createDetectSeries(false);
6018

    
6019
    return function everySeries(collection, iterator, callback) {
6020
      callback = callback || noop;
6021
      denySeries(collection, iterator, done);
6022

    
6023
      function done(err, res) {
6024
        if (err) {
6025
          return callback(err);
6026
        }
6027
        callback(null, !res);
6028
      }
6029
    };
6030
  }
6031

    
6032
  /**
6033
   * @private
6034
   */
6035
  function createEveryLimit() {
6036
    var denyLimit = createDetectLimit(false);
6037

    
6038
    return function everyLimit(collection, limit, iterator, callback) {
6039
      callback = callback || noop;
6040
      denyLimit(collection, limit, iterator, done);
6041

    
6042
      function done(err, res) {
6043
        if (err) {
6044
          return callback(err);
6045
        }
6046
        callback(null, !res);
6047
      }
6048
    };
6049
  }
6050

    
6051
  /**
6052
   * @private
6053
   * @param {Function} arrayEach
6054
   * @param {Function} baseEach
6055
   * @param {Function} symbolEach
6056
   */
6057
  function createConcat(arrayEach, baseEach, symbolEach) {
6058
    return function concat(collection, iterator, callback) {
6059
      callback = callback || noop;
6060
      var size, result;
6061
      var completed = 0;
6062

    
6063
      if (isArray(collection)) {
6064
        size = collection.length;
6065
        result = Array(size);
6066
        arrayEach(collection, iterator, createCallback);
6067
      } else if (!collection) {
6068
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
6069
        result = [];
6070
        size = symbolEach(collection, iterator, createCallback);
6071
        size && size === completed && callback(null, result);
6072
      } else if (typeof collection === obj) {
6073
        var keys = nativeKeys(collection);
6074
        size = keys.length;
6075
        result = Array(size);
6076
        baseEach(collection, iterator, createCallback, keys);
6077
      }
6078
      if (!size) {
6079
        callback(null, []);
6080
      }
6081

    
6082
      function createCallback(index) {
6083
        return function done(err, res) {
6084
          if (index === null) {
6085
            throwError();
6086
          }
6087
          if (err) {
6088
            index = null;
6089
            callback = once(callback);
6090
            arrayEachSync(result, function(array, index) {
6091
              if (array === undefined) {
6092
                result[index] = noop;
6093
              }
6094
            });
6095
            callback(err, makeConcatResult(result));
6096
            return;
6097
          }
6098
          switch (arguments.length) {
6099
            case 0:
6100
            case 1:
6101
              result[index] = noop;
6102
              break;
6103
            case 2:
6104
              result[index] = res;
6105
              break;
6106
            default:
6107
              result[index] = slice(arguments, 1);
6108
              break;
6109
          }
6110
          index = null;
6111
          if (++completed === size) {
6112
            callback(null, makeConcatResult(result));
6113
          }
6114
        };
6115
      }
6116
    };
6117
  }
6118

    
6119
  /**
6120
   * @memberof async
6121
   * @namespace concatSeries
6122
   * @param {Array|Object} collection
6123
   * @param {Function} iterator
6124
   * @param {Function} callback
6125
   * @example
6126
   *
6127
   * // array
6128
   * var order = [];
6129
   * var array = [1, 3, 2];
6130
   * var iterator = function(num, done) {
6131
   *   setTimeout(function() {
6132
   *     order.push(num);
6133
   *     done(null, [num]);
6134
   *   }, num * 10);
6135
   * };
6136
   * async.concatSeries(array, iterator, function(err, res) {
6137
   *   console.log(res); // [1, 3, 2];
6138
   *   console.log(order); // [1, 3, 2]
6139
   * });
6140
   *
6141
   * @example
6142
   *
6143
   * // array with index
6144
   * var order = [];
6145
   * var array = [1, 3, 2];
6146
   * var iterator = function(num, index, done) {
6147
   *   setTimeout(function() {
6148
   *     order.push([num, index]);
6149
   *     done(null, [num]);
6150
   *   }, num * 10);
6151
   * };
6152
   * async.concatSeries(array, iterator, function(err, res) {
6153
   *   console.log(res); // [1, 3, 2]
6154
   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
6155
   * });
6156
   *
6157
   * @example
6158
   *
6159
   * // object
6160
   * var order = [];
6161
   * var object = { a: 1, b: 3, c: 2 };
6162
   * var iterator = function(num, done) {
6163
   *   setTimeout(function() {
6164
   *     order.push(num);
6165
   *     done(null, [num]);
6166
   *   }, num * 10);
6167
   * };
6168
   * async.concatSeries(object, iterator, function(err, res) {
6169
   *   console.log(res); // [1, 3, 2]
6170
   *   console.log(order); // [1, 3, 2]
6171
   * });
6172
   *
6173
   * @example
6174
   *
6175
   * // object with key
6176
   * var order = [];
6177
   * var object = { a: 1, b: 3, c: 2 };
6178
   * var iterator = function(num, key, done) {
6179
   *   setTimeout(function() {
6180
   *     order.push([num, key]);
6181
   *     done(null, [num]);
6182
   *   }, num * 10);
6183
   * };
6184
   * async.concatSeries(object, iterator, function(err, res) {
6185
   *   console.log(res); // [1, 3, 2]
6186
   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
6187
   * });
6188
   *
6189
   */
6190
  function concatSeries(collection, iterator, callback) {
6191
    callback = onlyOnce(callback || noop);
6192
    var size, key, keys, iter, item, iterate;
6193
    var sync = false;
6194
    var result = [];
6195
    var completed = 0;
6196

    
6197
    if (isArray(collection)) {
6198
      size = collection.length;
6199
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6200
    } else if (!collection) {
6201
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
6202
      size = Infinity;
6203
      iter = collection[iteratorSymbol]();
6204
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6205
    } else if (typeof collection === obj) {
6206
      keys = nativeKeys(collection);
6207
      size = keys.length;
6208
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6209
    }
6210
    if (!size) {
6211
      return callback(null, result);
6212
    }
6213
    iterate();
6214

    
6215
    function arrayIterator() {
6216
      iterator(collection[completed], done);
6217
    }
6218

    
6219
    function arrayIteratorWithIndex() {
6220
      iterator(collection[completed], completed, done);
6221
    }
6222

    
6223
    function symbolIterator() {
6224
      item = iter.next();
6225
      item.done ? callback(null, result) : iterator(item.value, done);
6226
    }
6227

    
6228
    function symbolIteratorWithKey() {
6229
      item = iter.next();
6230
      item.done ? callback(null, result) : iterator(item.value, completed, done);
6231
    }
6232

    
6233
    function objectIterator() {
6234
      iterator(collection[keys[completed]], done);
6235
    }
6236

    
6237
    function objectIteratorWithKey() {
6238
      key = keys[completed];
6239
      iterator(collection[key], key, done);
6240
    }
6241

    
6242
    function done(err, array) {
6243
      if (isArray(array)) {
6244
        nativePush.apply(result, array);
6245
      } else if (arguments.length >= 2) {
6246
        nativePush.apply(result, slice(arguments, 1));
6247
      }
6248
      if (err) {
6249
        callback(err, result);
6250
      } else if (++completed === size) {
6251
        iterate = throwError;
6252
        callback(null, result);
6253
      } else if (sync) {
6254
        nextTick(iterate);
6255
      } else {
6256
        sync = true;
6257
        iterate();
6258
      }
6259
      sync = false;
6260
    }
6261
  }
6262

    
6263
  /**
6264
   * @memberof async
6265
   * @namespace concatLimit
6266
   * @param {Array|Object} collection
6267
   * @param {number} limit - limit >= 1
6268
   * @param {Function} iterator
6269
   * @param {Function} callback
6270
   * @example
6271
   *
6272
   * // array
6273
   * var order = [];
6274
   * var array = [1, 5, 3, 4, 2];
6275
   * var iterator = function(num, done) {
6276
   *   setTimeout(function() {
6277
   *     order.push(num);
6278
   *     done(null, [num]);
6279
   *   }, num * 10);
6280
   * };
6281
   * async.concatLimit(array, 2, iterator, function(err, res) {
6282
   *   console.log(res); // [1, 3, 5, 2, 4]
6283
   *   console.log(order); // [1, 3, 5, 2, 4]
6284
   * });
6285
   *
6286
   * @example
6287
   *
6288
   * // array with index
6289
   * var order = [];
6290
   * var array = [1, 5, 3, 4, 2];
6291
   * var iterator = function(num, index, done) {
6292
   *   setTimeout(function() {
6293
   *     order.push([num, index]);
6294
   *     done(null, [num]);
6295
   *   }, num * 10);
6296
   * };
6297
   * async.cocnatLimit(array, 2, iterator, function(err, res) {
6298
   *   console.log(res); // [1, 3, 5, 2, 4]
6299
   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
6300
   * });
6301
   *
6302
   * @example
6303
   *
6304
   * // object
6305
   * var order = [];
6306
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
6307
   * var iterator = function(num, done) {
6308
   *   setTimeout(function() {
6309
   *     order.push(num);
6310
   *     done(null, [num]);
6311
   *   }, num * 10);
6312
   * };
6313
   * async.concatLimit(object, 2, iterator, function(err, res) {
6314
   *   console.log(res); // [1, 3, 5, 2, 4]
6315
   *   console.log(order); // [1, 3, 5, 2, 4]
6316
   * });
6317
   *
6318
   * @example
6319
   *
6320
   * // object with key
6321
   * var order = [];
6322
   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
6323
   * var iterator = function(num, key, done) {
6324
   *   setTimeout(function() {
6325
   *     order.push([num, key]);
6326
   *     done(null, num);
6327
   *   }, num * 10);
6328
   * };
6329
   * async.cocnatLimit(object, 2, iterator, function(err, res) {
6330
   *   console.log(res); // [1, 3, 5, 2, 4]
6331
   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
6332
   * });
6333
   *
6334
   */
6335
  function concatLimit(collection, limit, iterator, callback) {
6336
    callback = callback || noop;
6337
    var size, key, iter, item, iterate, result;
6338
    var sync = false;
6339
    var started = 0;
6340
    var completed = 0;
6341

    
6342
    if (isArray(collection)) {
6343
      size = collection.length;
6344
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6345
    } else if (!collection) {
6346
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
6347
      size = Infinity;
6348
      result = [];
6349
      iter = collection[iteratorSymbol]();
6350
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6351
    } else if (typeof collection === obj) {
6352
      var keys = nativeKeys(collection);
6353
      size = keys.length;
6354
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6355
    }
6356
    if (!size || isNaN(limit) || limit < 1) {
6357
      return callback(null, []);
6358
    }
6359
    result = result || Array(size);
6360
    timesSync(limit > size ? size : limit, iterate);
6361

    
6362
    function arrayIterator() {
6363
      if (started < size) {
6364
        iterator(collection[started], createCallback(started++));
6365
      }
6366
    }
6367

    
6368
    function arrayIteratorWithIndex() {
6369
      if (started < size) {
6370
        iterator(collection[started], started, createCallback(started++));
6371
      }
6372
    }
6373

    
6374
    function symbolIterator() {
6375
      item = iter.next();
6376
      if (item.done === false) {
6377
        iterator(item.value, createCallback(started++));
6378
      } else if (completed === started && iterator !== noop) {
6379
        iterator = noop;
6380
        callback(null, makeConcatResult(result));
6381
      }
6382
    }
6383

    
6384
    function symbolIteratorWithKey() {
6385
      item = iter.next();
6386
      if (item.done === false) {
6387
        iterator(item.value, started, createCallback(started++));
6388
      } else if (completed === started && iterator !== noop) {
6389
        iterator = noop;
6390
        callback(null, makeConcatResult(result));
6391
      }
6392
    }
6393

    
6394
    function objectIterator() {
6395
      if (started < size) {
6396
        iterator(collection[keys[started]], createCallback(started++));
6397
      }
6398
    }
6399

    
6400
    function objectIteratorWithKey() {
6401
      if (started < size) {
6402
        key = keys[started];
6403
        iterator(collection[key], key, createCallback(started++));
6404
      }
6405
    }
6406

    
6407
    function createCallback(index) {
6408
      return function(err, res) {
6409
        if (index === null) {
6410
          throwError();
6411
        }
6412
        if (err) {
6413
          index = null;
6414
          iterate = noop;
6415
          callback = once(callback);
6416
          arrayEachSync(result, function(array, index) {
6417
            if (array === undefined) {
6418
              result[index] = noop;
6419
            }
6420
          });
6421
          callback(err, makeConcatResult(result));
6422
          return;
6423
        }
6424
        switch (arguments.length) {
6425
          case 0:
6426
          case 1:
6427
            result[index] = noop;
6428
            break;
6429
          case 2:
6430
            result[index] = res;
6431
            break;
6432
          default:
6433
            result[index] = slice(arguments, 1);
6434
            break;
6435
        }
6436
        index = null;
6437
        if (++completed === size) {
6438
          iterate = throwError;
6439
          callback(null, makeConcatResult(result));
6440
          callback = throwError;
6441
        } else if (sync) {
6442
          nextTick(iterate);
6443
        } else {
6444
          sync = true;
6445
          iterate();
6446
        }
6447
        sync = false;
6448
      };
6449
    }
6450
  }
6451

    
6452
  /**
6453
   * @private
6454
   * @param {Function} arrayEach
6455
   * @param {Function} baseEach
6456
   * @param {Function} symbolEach
6457
   */
6458
  function createGroupBy(arrayEach, baseEach, symbolEach) {
6459
    return function groupBy(collection, iterator, callback) {
6460
      callback = callback || noop;
6461
      var size;
6462
      var completed = 0;
6463
      var result = {};
6464

    
6465
      if (isArray(collection)) {
6466
        size = collection.length;
6467
        arrayEach(collection, iterator, createCallback);
6468
      } else if (!collection) {
6469
      } else if (iteratorSymbol && collection[iteratorSymbol]) {
6470
        size = symbolEach(collection, iterator, createCallback);
6471
        size && size === completed && callback(null, result);
6472
      } else if (typeof collection === obj) {
6473
        var keys = nativeKeys(collection);
6474
        size = keys.length;
6475
        baseEach(collection, iterator, createCallback, keys);
6476
      }
6477
      if (!size) {
6478
        callback(null, {});
6479
      }
6480

    
6481
      function createCallback(value) {
6482
        var called = false;
6483
        return function done(err, key) {
6484
          if (called) {
6485
            throwError();
6486
          }
6487
          called = true;
6488
          if (err) {
6489
            callback = once(callback);
6490
            callback(err, objectClone(result));
6491
            return;
6492
          }
6493
          var array = result[key];
6494
          if (!array) {
6495
            result[key] = [value];
6496
          } else {
6497
            array.push(value);
6498
          }
6499
          if (++completed === size) {
6500
            callback(null, result);
6501
          }
6502
        };
6503
      }
6504
    };
6505
  }
6506

    
6507
  /**
6508
   * @memberof async
6509
   * @namespace groupBySeries
6510
   * @param {Array|Object} collection
6511
   * @param {Function} iterator
6512
   * @param {Function} callback
6513
   * @example
6514
   *
6515
   * // array
6516
   * var order = [];
6517
   * var array = [4.2, 6.4, 6.1];
6518
   * var iterator = function(num, done) {
6519
   *   setTimeout(function() {
6520
   *     order.push(num);
6521
   *     done(null, Math.floor(num));
6522
   *   }, num * 10);
6523
   * };
6524
   * async.groupBySeries(array, iterator, function(err, res) {
6525
   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6526
   *   console.log(order); // [4.2, 6.4, 6.1]
6527
   * });
6528
   *
6529
   * @example
6530
   *
6531
   * // array with index
6532
   * var order = [];
6533
   * var array = [4.2, 6.4, 6.1];
6534
   * var iterator = function(num, index, done) {
6535
   *   setTimeout(function() {
6536
   *     order.push([num, index]);
6537
   *     done(null, Math.floor(num));
6538
   *   }, num * 10);
6539
   * };
6540
   * async.groupBySeries(array, iterator, function(err, res) {
6541
   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6542
   *   console.log(order); // [[4.2, 0], [6.4, 1], [6.1, 2]]
6543
   * });
6544
   *
6545
   * @example
6546
   *
6547
   * // object
6548
   * var order = [];
6549
   * var object = { a: 4.2, b: 6.4, c: 6.1 };
6550
   * var iterator = function(num, done) {
6551
   *   setTimeout(function() {
6552
   *     order.push(num);
6553
   *     done(null, Math.floor(num));
6554
   *   }, num * 10);
6555
   * };
6556
   * async.groupBySeries(object, iterator, function(err, res) {
6557
   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6558
   *   console.log(order); // [4.2, 6.4, 6.1]
6559
   * });
6560
   *
6561
   * @example
6562
   *
6563
   * // object with key
6564
   * var order = [];
6565
   * var object = { a: 4.2, b: 6.4, c: 6.1 };
6566
   * var iterator = function(num, key, done) {
6567
   *   setTimeout(function() {
6568
   *     order.push([num, key]);
6569
   *     done(null, Math.floor(num));
6570
   *   }, num * 10);
6571
   * };
6572
   * async.groupBySeries(object, iterator, function(err, res) {
6573
   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6574
   *   console.log(order); // [[4.2, 'a'], [6.4, 'b'], [6.1, 'c']]
6575
   * });
6576
   *
6577
   */
6578
  function groupBySeries(collection, iterator, callback) {
6579
    callback = onlyOnce(callback || noop);
6580
    var size, key, value, keys, iter, item, iterate;
6581
    var sync = false;
6582
    var completed = 0;
6583
    var result = {};
6584

    
6585
    if (isArray(collection)) {
6586
      size = collection.length;
6587
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6588
    } else if (!collection) {
6589
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
6590
      size = Infinity;
6591
      iter = collection[iteratorSymbol]();
6592
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6593
    } else if (typeof collection === obj) {
6594
      keys = nativeKeys(collection);
6595
      size = keys.length;
6596
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6597
    }
6598
    if (!size) {
6599
      return callback(null, result);
6600
    }
6601
    iterate();
6602

    
6603
    function arrayIterator() {
6604
      value = collection[completed];
6605
      iterator(value, done);
6606
    }
6607

    
6608
    function arrayIteratorWithIndex() {
6609
      value = collection[completed];
6610
      iterator(value, completed, done);
6611
    }
6612

    
6613
    function symbolIterator() {
6614
      item = iter.next();
6615
      value = item.value;
6616
      item.done ? callback(null, result) : iterator(value, done);
6617
    }
6618

    
6619
    function symbolIteratorWithKey() {
6620
      item = iter.next();
6621
      value = item.value;
6622
      item.done ? callback(null, result) : iterator(value, completed, done);
6623
    }
6624

    
6625
    function objectIterator() {
6626
      value = collection[keys[completed]];
6627
      iterator(value, done);
6628
    }
6629

    
6630
    function objectIteratorWithKey() {
6631
      key = keys[completed];
6632
      value = collection[key];
6633
      iterator(value, key, done);
6634
    }
6635

    
6636
    function done(err, key) {
6637
      if (err) {
6638
        iterate = throwError;
6639
        callback = onlyOnce(callback);
6640
        callback(err, objectClone(result));
6641
        return;
6642
      }
6643
      var array = result[key];
6644
      if (!array) {
6645
        result[key] = [value];
6646
      } else {
6647
        array.push(value);
6648
      }
6649
      if (++completed === size) {
6650
        iterate = throwError;
6651
        callback(null, result);
6652
      } else if (sync) {
6653
        nextTick(iterate);
6654
      } else {
6655
        sync = true;
6656
        iterate();
6657
      }
6658
      sync = false;
6659
    }
6660
  }
6661

    
6662
  /**
6663
   * @memberof async
6664
   * @namespace groupByLimit
6665
   * @param {Array|Object} collection
6666
   * @param {Function} iterator
6667
   * @param {Function} callback
6668
   * @example
6669
   *
6670
   * // array
6671
   * var order = [];
6672
   * var array = [1.1, 5.9, 3.2, 3.9, 2.1];
6673
   * var iterator = function(num, done) {
6674
   *   setTimeout(function() {
6675
   *     order.push(num);
6676
   *     done(null, Math.floor(num));
6677
   *   }, num * 10);
6678
   * };
6679
   * async.groupByLimit(array, 2, iterator, function(err, res) {
6680
   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6681
   *   console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9]
6682
   * });
6683
   *
6684
   * @example
6685
   *
6686
   * // array with index
6687
   * var order = [];
6688
   * var array = [1.1, 5.9, 3.2, 3.9, 2.1];
6689
   * var iterator = function(num, index, done) {
6690
   *   setTimeout(function() {
6691
   *     order.push([num, index]);
6692
   *     done(null, Math.floor(num));
6693
   *   }, num * 10);
6694
   * };
6695
   * async.groupByLimit(array, 2, iterator, function(err, res) {
6696
   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6697
   *   console.log(order); // [[1.1, 0], [3.2, 2], [5.9, 1], [2.1, 4], [3.9, 3]]
6698
   * });
6699
   *
6700
   * @example
6701
   *
6702
   * // object
6703
   * var order = [];
6704
   * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 }
6705
   * var iterator = function(num, done) {
6706
   *   setTimeout(function() {
6707
   *     order.push(num);
6708
   *     done(null, Math.floor(num));
6709
   *   }, num * 10);
6710
   * };
6711
   * async.groupByLimit(object, 2, iterator, function(err, res) {
6712
   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6713
   *   console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9]
6714
   * });
6715
   *
6716
   * @example
6717
   *
6718
   * // object with key
6719
   * var order = [];
6720
   * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 }
6721
   * var iterator = function(num, key, done) {
6722
   *   setTimeout(function() {
6723
   *     order.push([num, key]);
6724
   *     done(null, Math.floor(num));
6725
   *   }, num * 10);
6726
   * };
6727
   * async.groupByLimit(object, 2, iterator, function(err, res) {
6728
   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6729
   *   console.log(order); // [[1.1, 'a'], [3.2, 'c'], [5.9, 'b'], [2.1, 'e'], [3.9, 'd']]
6730
   * });
6731
   *
6732
   */
6733
  function groupByLimit(collection, limit, iterator, callback) {
6734
    callback = callback || noop;
6735
    var size, index, key, value, keys, iter, item, iterate;
6736
    var sync = false;
6737
    var started = 0;
6738
    var completed = 0;
6739
    var result = {};
6740

    
6741
    if (isArray(collection)) {
6742
      size = collection.length;
6743
      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6744
    } else if (!collection) {
6745
    } else if (iteratorSymbol && collection[iteratorSymbol]) {
6746
      size = Infinity;
6747
      iter = collection[iteratorSymbol]();
6748
      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6749
    } else if (typeof collection === obj) {
6750
      keys = nativeKeys(collection);
6751
      size = keys.length;
6752
      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6753
    }
6754
    if (!size || isNaN(limit) || limit < 1) {
6755
      return callback(null, result);
6756
    }
6757
    timesSync(limit > size ? size : limit, iterate);
6758

    
6759
    function arrayIterator() {
6760
      if (started < size) {
6761
        value = collection[started++];
6762
        iterator(value, createCallback(value));
6763
      }
6764
    }
6765

    
6766
    function arrayIteratorWithIndex() {
6767
      index = started++;
6768
      if (index < size) {
6769
        value = collection[index];
6770
        iterator(value, index, createCallback(value));
6771
      }
6772
    }
6773

    
6774
    function symbolIterator() {
6775
      item = iter.next();
6776
      if (item.done === false) {
6777
        started++;
6778
        value = item.value;
6779
        iterator(value, createCallback(value));
6780
      } else if (completed === started && iterator !== noop) {
6781
        iterator = noop;
6782
        callback(null, result);
6783
      }
6784
    }
6785

    
6786
    function symbolIteratorWithKey() {
6787
      item = iter.next();
6788
      if (item.done === false) {
6789
        value = item.value;
6790
        iterator(value, started++, createCallback(value));
6791
      } else if (completed === started && iterator !== noop) {
6792
        iterator = noop;
6793
        callback(null, result);
6794
      }
6795
    }
6796

    
6797
    function objectIterator() {
6798
      if (started < size) {
6799
        value = collection[keys[started++]];
6800
        iterator(value, createCallback(value));
6801
      }
6802
    }
6803

    
6804
    function objectIteratorWithKey() {
6805
      if (started < size) {
6806
        key = keys[started++];
6807
        value = collection[key];
6808
        iterator(value, key, createCallback(value));
6809
      }
6810
    }
6811

    
6812
    function createCallback(value) {
6813
      var called = false;
6814
      return function(err, key) {
6815
        if (called) {
6816
          throwError();
6817
        }
6818
        called = true;
6819
        if (err) {
6820
          iterate = noop;
6821
          callback = once(callback);
6822
          callback(err, objectClone(result));
6823
          return;
6824
        }
6825
        var array = result[key];
6826
        if (!array) {
6827
          result[key] = [value];
6828
        } else {
6829
          array.push(value);
6830
        }
6831
        if (++completed === size) {
6832
          callback(null, result);
6833
        } else if (sync) {
6834
          nextTick(iterate);
6835
        } else {
6836
          sync = true;
6837
          iterate();
6838
        }
6839
        sync = false;
6840
      };
6841
    }
6842
  }
6843

    
6844
  /**
6845
   * @private
6846
   * @param {Function} arrayEach
6847
   * @param {Function} baseEach
6848
   */
6849
  function createParallel(arrayEach, baseEach) {
6850
    return function parallel(tasks, callback) {
6851
      callback = callback || noop;
6852
      var size, keys, result;
6853
      var completed = 0;
6854

    
6855
      if (isArray(tasks)) {
6856
        size = tasks.length;
6857
        result = Array(size);
6858
        arrayEach(tasks, createCallback);
6859
      } else if (tasks && typeof tasks === obj) {
6860
        keys = nativeKeys(tasks);
6861
        size = keys.length;
6862
        result = {};
6863
        baseEach(tasks, createCallback, keys);
6864
      }
6865
      if (!size) {
6866
        callback(null, result);
6867
      }
6868

    
6869
      function createCallback(key) {
6870
        return function(err, res) {
6871
          if (key === null) {
6872
            throwError();
6873
          }
6874
          if (err) {
6875
            key = null;
6876
            callback = once(callback);
6877
            callback(err, result);
6878
            return;
6879
          }
6880
          result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
6881
          key = null;
6882
          if (++completed === size) {
6883
            callback(null, result);
6884
          }
6885
        };
6886
      }
6887
    };
6888
  }
6889

    
6890
  /**
6891
   * @memberof async
6892
   * @namespace series
6893
   * @param {Array|Object} tasks - functions
6894
   * @param {Function} callback
6895
   * @example
6896
   *
6897
   * var order = [];
6898
   * var tasks = [
6899
   *  function(done) {
6900
   *    setTimeout(function() {
6901
   *      order.push(1);
6902
   *      done(null, 1);
6903
   *    }, 10);
6904
   *  },
6905
   *  function(done) {
6906
   *    setTimeout(function() {
6907
   *      order.push(2);
6908
   *      done(null, 2);
6909
   *    }, 30);
6910
   *  },
6911
   *  function(done) {
6912
   *    setTimeout(function() {
6913
   *      order.push(3);
6914
   *      done(null, 3);
6915
   *    }, 40);
6916
   *  },
6917
   *  function(done) {
6918
   *    setTimeout(function() {
6919
   *      order.push(4);
6920
   *      done(null, 4);
6921
   *    }, 20);
6922
   *  }
6923
   * ];
6924
   * async.series(tasks, function(err, res) {
6925
   *   console.log(res); // [1, 2, 3, 4];
6926
   *   console.log(order); // [1, 2, 3, 4]
6927
   * });
6928
   *
6929
   * @example
6930
   *
6931
   * var order = [];
6932
   * var tasks = {
6933
   *   'a': function(done) {
6934
   *     setTimeout(function() {
6935
   *       order.push(1);
6936
   *       done(null, 1);
6937
   *     }, 10);
6938
   *   },
6939
   *   'b': function(done) {
6940
   *     setTimeout(function() {
6941
   *       order.push(2);
6942
   *       done(null, 2);
6943
   *     }, 30);
6944
   *   },
6945
   *   'c': function(done) {
6946
   *     setTimeout(function() {
6947
   *       order.push(3);
6948
   *       done(null, 3);
6949
   *     }, 40);
6950
   *   },
6951
   *   'd': function(done) {
6952
   *     setTimeout(function() {
6953
   *       order.push(4);
6954
   *       done(null, 4);
6955
   *     }, 20);
6956
   *   }
6957
   * };
6958
   * async.series(tasks, function(err, res) {
6959
   *   console.log(res); // { a: 1, b: 2, c: 3, d:4 }
6960
   *   console.log(order); // [1, 4, 2, 3]
6961
   * });
6962
   *
6963
   */
6964
  function series(tasks, callback) {
6965
    callback = callback || noop;
6966
    var size, key, keys, result, iterate;
6967
    var sync = false;
6968
    var completed = 0;
6969

    
6970
    if (isArray(tasks)) {
6971
      size = tasks.length;
6972
      result = Array(size);
6973
      iterate = arrayIterator;
6974
    } else if (tasks && typeof tasks === obj) {
6975
      keys = nativeKeys(tasks);
6976
      size = keys.length;
6977
      result = {};
6978
      iterate = objectIterator;
6979
    } else {
6980
      return callback(null);
6981
    }
6982
    if (!size) {
6983
      return callback(null, result);
6984
    }
6985
    iterate();
6986

    
6987
    function arrayIterator() {
6988
      key = completed;
6989
      tasks[completed](done);
6990
    }
6991

    
6992
    function objectIterator() {
6993
      key = keys[completed];
6994
      tasks[key](done);
6995
    }
6996

    
6997
    function done(err, res) {
6998
      if (err) {
6999
        iterate = throwError;
7000
        callback = onlyOnce(callback);
7001
        callback(err, result);
7002
        return;
7003
      }
7004
      result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
7005
      if (++completed === size) {
7006
        iterate = throwError;
7007
        callback(null, result);
7008
      } else if (sync) {
7009
        nextTick(iterate);
7010
      } else {
7011
        sync = true;
7012
        iterate();
7013
      }
7014
      sync = false;
7015
    }
7016
  }
7017

    
7018
  /**
7019
   * @memberof async
7020
   * @namespace parallelLimit
7021
   * @param {Array|Object} tasks - functions
7022
   * @param {number} limit - limit >= 1
7023
   * @param {Function} callback
7024
   * @example
7025
   *
7026
   * var order = [];
7027
   * var tasks = [
7028
   *  function(done) {
7029
   *    setTimeout(function() {
7030
   *      order.push(1);
7031
   *      done(null, 1);
7032
   *    }, 10);
7033
   *  },
7034
   *  function(done) {
7035
   *    setTimeout(function() {
7036
   *      order.push(2);
7037
   *      done(null, 2);
7038
   *    }, 50);
7039
   *  },
7040
   *  function(done) {
7041
   *    setTimeout(function() {
7042
   *      order.push(3);
7043
   *      done(null, 3);
7044
   *    }, 30);
7045
   *  },
7046
   *  function(done) {
7047
   *    setTimeout(function() {
7048
   *      order.push(4);
7049
   *      done(null, 4);
7050
   *    }, 40);
7051
   *  }
7052
   * ];
7053
   * async.parallelLimit(tasks, 2, function(err, res) {
7054
   *   console.log(res); // [1, 2, 3, 4];
7055
   *   console.log(order); // [1, 3, 2, 4]
7056
   * });
7057
   *
7058
   * @example
7059
   *
7060
   * var order = [];
7061
   * var tasks = {
7062
   *   'a': function(done) {
7063
   *     setTimeout(function() {
7064
   *       order.push(1);
7065
   *       done(null, 1);
7066
   *     }, 10);
7067
   *   },
7068
   *   'b': function(done) {
7069
   *     setTimeout(function() {
7070
   *       order.push(2);
7071
   *       done(null, 2);
7072
   *     }, 50);
7073
   *   },
7074
   *   'c': function(done) {
7075
   *     setTimeout(function() {
7076
   *       order.push(3);
7077
   *       done(null, 3);
7078
   *     }, 20);
7079
   *   },
7080
   *   'd': function(done) {
7081
   *     setTimeout(function() {
7082
   *       order.push(4);
7083
   *       done(null, 4);
7084
   *     }, 40);
7085
   *   }
7086
   * };
7087
   * async.parallelLimit(tasks, 2, function(err, res) {
7088
   *   console.log(res); // { a: 1, b: 2, c: 3, d:4 }
7089
   *   console.log(order); // [1, 3, 2, 4]
7090
   * });
7091
   *
7092
   */
7093
  function parallelLimit(tasks, limit, callback) {
7094
    callback = callback || noop;
7095
    var size, index, key, keys, result, iterate;
7096
    var sync = false;
7097
    var started = 0;
7098
    var completed = 0;
7099

    
7100
    if (isArray(tasks)) {
7101
      size = tasks.length;
7102
      result = Array(size);
7103
      iterate = arrayIterator;
7104
    } else if (tasks && typeof tasks === obj) {
7105
      keys = nativeKeys(tasks);
7106
      size = keys.length;
7107
      result = {};
7108
      iterate = objectIterator;
7109
    }
7110
    if (!size || isNaN(limit) || limit < 1) {
7111
      return callback(null, result);
7112
    }
7113
    timesSync(limit > size ? size : limit, iterate);
7114

    
7115
    function arrayIterator() {
7116
      index = started++;
7117
      if (index < size) {
7118
        tasks[index](createCallback(index));
7119
      }
7120
    }
7121

    
7122
    function objectIterator() {
7123
      if (started < size) {
7124
        key = keys[started++];
7125
        tasks[key](createCallback(key));
7126
      }
7127
    }
7128

    
7129
    function createCallback(key) {
7130
      return function(err, res) {
7131
        if (key === null) {
7132
          throwError();
7133
        }
7134
        if (err) {
7135
          key = null;
7136
          iterate = noop;
7137
          callback = once(callback);
7138
          callback(err, result);
7139
          return;
7140
        }
7141
        result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
7142
        key = null;
7143
        if (++completed === size) {
7144
          callback(null, result);
7145
        } else if (sync) {
7146
          nextTick(iterate);
7147
        } else {
7148
          sync = true;
7149
          iterate();
7150
        }
7151
        sync = false;
7152
      };
7153
    }
7154
  }
7155

    
7156
  /**
7157
   * @memberof async
7158
   * @namespace tryEach
7159
   * @param {Array|Object} tasks - functions
7160
   * @param {Function} callback
7161
   * @example
7162
   *
7163
   * var tasks = [
7164
   *  function(done) {
7165
   *    setTimeout(function() {
7166
   *      done(new Error('error'));
7167
   *    }, 10);
7168
   *  },
7169
   *  function(done) {
7170
   *    setTimeout(function() {
7171
   *      done(null, 2);
7172
   *    }, 10);
7173
   *  }
7174
   * ];
7175
   * async.tryEach(tasks, function(err, res) {
7176
   *   console.log(res); // 2
7177
   * });
7178
   *
7179
   * @example
7180
   *
7181
   * var tasks = [
7182
   *  function(done) {
7183
   *    setTimeout(function() {
7184
   *      done(new Error('error1'));
7185
   *    }, 10);
7186
   *  },
7187
   *  function(done) {
7188
   *    setTimeout(function() {
7189
   *      done(new Error('error2');
7190
   *    }, 10);
7191
   *  }
7192
   * ];
7193
   * async.tryEach(tasks, function(err, res) {
7194
   *   console.log(err); // error2
7195
   *   console.log(res); // undefined
7196
   * });
7197
   *
7198
   */
7199
  function tryEach(tasks, callback) {
7200
    callback = callback || noop;
7201
    var size, keys, iterate;
7202
    var sync = false;
7203
    var completed = 0;
7204

    
7205
    if (isArray(tasks)) {
7206
      size = tasks.length;
7207
      iterate = arrayIterator;
7208
    } else if (tasks && typeof tasks === obj) {
7209
      keys = nativeKeys(tasks);
7210
      size = keys.length;
7211
      iterate = objectIterator;
7212
    }
7213
    if (!size) {
7214
      return callback(null);
7215
    }
7216
    iterate();
7217

    
7218
    function arrayIterator() {
7219
      tasks[completed](done);
7220
    }
7221

    
7222
    function objectIterator() {
7223
      tasks[keys[completed]](done);
7224
    }
7225

    
7226
    function done(err, res) {
7227
      if (!err) {
7228
        if (arguments.length <= 2) {
7229
          callback(null, res);
7230
        } else {
7231
          callback(null, slice(arguments, 1));
7232
        }
7233
      } else if (++completed === size) {
7234
        callback(err);
7235
      } else {
7236
        sync = true;
7237
        iterate();
7238
      }
7239
      sync = false;
7240
    }
7241
  }
7242

    
7243
  /**
7244
   * check for waterfall tasks
7245
   * @private
7246
   * @param {Array} tasks
7247
   * @param {Function} callback
7248
   * @return {boolean}
7249
   */
7250
  function checkWaterfallTasks(tasks, callback) {
7251
    if (!isArray(tasks)) {
7252
      callback(new Error('First argument to waterfall must be an array of functions'));
7253
      return false;
7254
    }
7255
    if (tasks.length === 0) {
7256
      callback(null);
7257
      return false;
7258
    }
7259
    return true;
7260
  }
7261

    
7262
  /**
7263
   * check for waterfall tasks
7264
   * @private
7265
   * @param {function} func
7266
   * @param {Array|Object} args - arguments
7267
   * @return {function} next
7268
   */
7269
  function waterfallIterator(func, args, next) {
7270
    switch (args.length) {
7271
      case 0:
7272
      case 1:
7273
        return func(next);
7274
      case 2:
7275
        return func(args[1], next);
7276
      case 3:
7277
        return func(args[1], args[2], next);
7278
      case 4:
7279
        return func(args[1], args[2], args[3], next);
7280
      case 5:
7281
        return func(args[1], args[2], args[3], args[4], next);
7282
      case 6:
7283
        return func(args[1], args[2], args[3], args[4], args[5], next);
7284
      default:
7285
        args = slice(args, 1);
7286
        args.push(next);
7287
        return func.apply(null, args);
7288
    }
7289
  }
7290

    
7291
  /**
7292
   * @memberof async
7293
   * @namespace waterfall
7294
   * @param {Array} tasks - functions
7295
   * @param {Function} callback
7296
   * @example
7297
   *
7298
   * var order = [];
7299
   * var tasks = [
7300
   *   function(next) {
7301
   *     setTimeout(function() {
7302
   *       order.push(1);
7303
   *       next(null, 1);
7304
   *     }, 10);
7305
   *   },
7306
   *   function(arg1, next) {
7307
   *     setTimeout(function() {
7308
   *       order.push(2);
7309
   *       next(null, 1, 2);
7310
   *     }, 30);
7311
   *   },
7312
   *   function(arg1, arg2, next) {
7313
   *     setTimeout(function() {
7314
   *       order.push(3);
7315
   *       next(null, 3);
7316
   *     }, 20);
7317
   *   },
7318
   *   function(arg1, next) {
7319
   *     setTimeout(function() {
7320
   *       order.push(4);
7321
   *       next(null, 1, 2, 3, 4);
7322
   *     }, 40);
7323
   *   }
7324
   * ];
7325
   * async.waterfall(tasks, function(err, arg1, arg2, arg3, arg4) {
7326
   *   console.log(arg1, arg2, arg3, arg4); // 1 2 3 4
7327
   * });
7328
   *
7329
   */
7330
  function waterfall(tasks, callback) {
7331
    callback = callback || noop;
7332
    if (!checkWaterfallTasks(tasks, callback)) {
7333
      return;
7334
    }
7335
    var func, args, done, sync;
7336
    var completed = 0;
7337
    var size = tasks.length;
7338
    waterfallIterator(tasks[0], [], createCallback(0));
7339

    
7340
    function iterate() {
7341
      waterfallIterator(func, args, createCallback(func));
7342
    }
7343

    
7344
    function createCallback(index) {
7345
      return function next(err, res) {
7346
        if (index === undefined) {
7347
          callback = noop;
7348
          throwError();
7349
        }
7350
        index = undefined;
7351
        if (err) {
7352
          done = callback;
7353
          callback = throwError;
7354
          done(err);
7355
          return;
7356
        }
7357
        if (++completed === size) {
7358
          done = callback;
7359
          callback = throwError;
7360
          if (arguments.length <= 2) {
7361
            done(err, res);
7362
          } else {
7363
            done.apply(null, createArray(arguments));
7364
          }
7365
          return;
7366
        }
7367
        if (sync) {
7368
          args = arguments;
7369
          func = tasks[completed] || throwError;
7370
          nextTick(iterate);
7371
        } else {
7372
          sync = true;
7373
          waterfallIterator(tasks[completed] || throwError, arguments, createCallback(completed));
7374
        }
7375
        sync = false;
7376
      };
7377
    }
7378
  }
7379

    
7380
  /**
7381
   * `angelFall` is like `waterfall` and inject callback to last argument of next task.
7382
   *
7383
   * @memberof async
7384
   * @namespace angelFall
7385
   * @param {Array} tasks - functions
7386
   * @param {Function} callback
7387
   * @example
7388
   *
7389
   * var order = [];
7390
   * var tasks = [
7391
   *   function(next) {
7392
   *     setTimeout(function() {
7393
   *       order.push(1);
7394
   *       next(null, 1);
7395
   *     }, 10);
7396
   *   },
7397
   *   function(arg1, empty, next) {
7398
   *     setTimeout(function() {
7399
   *       order.push(2);
7400
   *       next(null, 1, 2);
7401
   *     }, 30);
7402
   *   },
7403
   *   function(next) {
7404
   *     setTimeout(function() {
7405
   *       order.push(3);
7406
   *       next(null, 3);
7407
   *     }, 20);
7408
   *   },
7409
   *   function(arg1, empty1, empty2, empty3, next) {
7410
   *     setTimeout(function() {
7411
   *       order.push(4);
7412
   *       next(null, 1, 2, 3, 4);
7413
   *     }, 40);
7414
   *   }
7415
   * ];
7416
   * async.angelFall(tasks, function(err, arg1, arg2, arg3, arg4) {
7417
   *   console.log(arg1, arg2, arg3, arg4); // 1 2 3 4
7418
   * });
7419
   *
7420
   */
7421
  function angelFall(tasks, callback) {
7422
    callback = callback || noop;
7423
    if (!checkWaterfallTasks(tasks, callback)) {
7424
      return;
7425
    }
7426
    var completed = 0;
7427
    var sync = false;
7428
    var size = tasks.length;
7429
    var func = tasks[completed];
7430
    var args = [];
7431
    var iterate = function() {
7432
      switch (func.length) {
7433
        case 0:
7434
          try {
7435
            next(null, func());
7436
          } catch (e) {
7437
            next(e);
7438
          }
7439
          return;
7440
        case 1:
7441
          return func(next);
7442
        case 2:
7443
          return func(args[1], next);
7444
        case 3:
7445
          return func(args[1], args[2], next);
7446
        case 4:
7447
          return func(args[1], args[2], args[3], next);
7448
        case 5:
7449
          return func(args[1], args[2], args[3], args[4], next);
7450
        default:
7451
          args = slice(args, 1);
7452
          args[func.length - 1] = next;
7453
          return func.apply(null, args);
7454
      }
7455
    };
7456
    iterate();
7457

    
7458
    function next(err, res) {
7459
      if (err) {
7460
        iterate = throwError;
7461
        callback = onlyOnce(callback);
7462
        callback(err);
7463
        return;
7464
      }
7465
      if (++completed === size) {
7466
        iterate = throwError;
7467
        var done = callback;
7468
        callback = throwError;
7469
        if (arguments.length === 2) {
7470
          done(err, res);
7471
        } else {
7472
          done.apply(null, createArray(arguments));
7473
        }
7474
        return;
7475
      }
7476
      func = tasks[completed];
7477
      args = arguments;
7478
      if (sync) {
7479
        nextTick(iterate);
7480
      } else {
7481
        sync = true;
7482
        iterate();
7483
      }
7484
      sync = false;
7485
    }
7486
  }
7487

    
7488
  /**
7489
   * @memberof async
7490
   * @namespace whilst
7491
   * @param {Function} test
7492
   * @param {Function} iterator
7493
   * @param {Function} callback
7494
   */
7495
  function whilst(test, iterator, callback) {
7496
    callback = callback || noop;
7497
    var sync = false;
7498
    if (test()) {
7499
      iterate();
7500
    } else {
7501
      callback(null);
7502
    }
7503

    
7504
    function iterate() {
7505
      if (sync) {
7506
        nextTick(next);
7507
      } else {
7508
        sync = true;
7509
        iterator(done);
7510
      }
7511
      sync = false;
7512
    }
7513

    
7514
    function next() {
7515
      iterator(done);
7516
    }
7517

    
7518
    function done(err, arg) {
7519
      if (err) {
7520
        return callback(err);
7521
      }
7522
      if (arguments.length <= 2) {
7523
        if (test(arg)) {
7524
          iterate();
7525
        } else {
7526
          callback(null, arg);
7527
        }
7528
        return;
7529
      }
7530
      arg = slice(arguments, 1);
7531
      if (test.apply(null, arg)) {
7532
        iterate();
7533
      } else {
7534
        callback.apply(null, [null].concat(arg));
7535
      }
7536
    }
7537
  }
7538

    
7539
  /**
7540
   * @memberof async
7541
   * @namespace doWhilst
7542
   * @param {Function} iterator
7543
   * @param {Function} test
7544
   * @param {Function} callback
7545
   */
7546
  function doWhilst(iterator, test, callback) {
7547
    callback = callback || noop;
7548
    var sync = false;
7549
    next();
7550

    
7551
    function iterate() {
7552
      if (sync) {
7553
        nextTick(next);
7554
      } else {
7555
        sync = true;
7556
        iterator(done);
7557
      }
7558
      sync = false;
7559
    }
7560

    
7561
    function next() {
7562
      iterator(done);
7563
    }
7564

    
7565
    function done(err, arg) {
7566
      if (err) {
7567
        return callback(err);
7568
      }
7569
      if (arguments.length <= 2) {
7570
        if (test(arg)) {
7571
          iterate();
7572
        } else {
7573
          callback(null, arg);
7574
        }
7575
        return;
7576
      }
7577
      arg = slice(arguments, 1);
7578
      if (test.apply(null, arg)) {
7579
        iterate();
7580
      } else {
7581
        callback.apply(null, [null].concat(arg));
7582
      }
7583
    }
7584
  }
7585

    
7586
  /**
7587
   * @memberof async
7588
   * @namespace until
7589
   * @param {Function} test
7590
   * @param {Function} iterator
7591
   * @param {Function} callback
7592
   */
7593
  function until(test, iterator, callback) {
7594
    callback = callback || noop;
7595
    var sync = false;
7596
    if (!test()) {
7597
      iterate();
7598
    } else {
7599
      callback(null);
7600
    }
7601

    
7602
    function iterate() {
7603
      if (sync) {
7604
        nextTick(next);
7605
      } else {
7606
        sync = true;
7607
        iterator(done);
7608
      }
7609
      sync = false;
7610
    }
7611

    
7612
    function next() {
7613
      iterator(done);
7614
    }
7615

    
7616
    function done(err, arg) {
7617
      if (err) {
7618
        return callback(err);
7619
      }
7620
      if (arguments.length <= 2) {
7621
        if (!test(arg)) {
7622
          iterate();
7623
        } else {
7624
          callback(null, arg);
7625
        }
7626
        return;
7627
      }
7628
      arg = slice(arguments, 1);
7629
      if (!test.apply(null, arg)) {
7630
        iterate();
7631
      } else {
7632
        callback.apply(null, [null].concat(arg));
7633
      }
7634
    }
7635
  }
7636

    
7637
  /**
7638
   * @memberof async
7639
   * @namespace doUntil
7640
   * @param {Function} iterator
7641
   * @param {Function} test
7642
   * @param {Function} callback
7643
   */
7644
  function doUntil(iterator, test, callback) {
7645
    callback = callback || noop;
7646
    var sync = false;
7647
    next();
7648

    
7649
    function iterate() {
7650
      if (sync) {
7651
        nextTick(next);
7652
      } else {
7653
        sync = true;
7654
        iterator(done);
7655
      }
7656
      sync = false;
7657
    }
7658

    
7659
    function next() {
7660
      iterator(done);
7661
    }
7662

    
7663
    function done(err, arg) {
7664
      if (err) {
7665
        return callback(err);
7666
      }
7667
      if (arguments.length <= 2) {
7668
        if (!test(arg)) {
7669
          iterate();
7670
        } else {
7671
          callback(null, arg);
7672
        }
7673
        return;
7674
      }
7675
      arg = slice(arguments, 1);
7676
      if (!test.apply(null, arg)) {
7677
        iterate();
7678
      } else {
7679
        callback.apply(null, [null].concat(arg));
7680
      }
7681
    }
7682
  }
7683

    
7684
  /**
7685
   * @memberof async
7686
   * @namespace during
7687
   * @param {Function} test
7688
   * @param {Function} iterator
7689
   * @param {Function} callback
7690
   */
7691
  function during(test, iterator, callback) {
7692
    callback = callback || noop;
7693
    _test();
7694

    
7695
    function _test() {
7696
      test(iterate);
7697
    }
7698

    
7699
    function iterate(err, truth) {
7700
      if (err) {
7701
        return callback(err);
7702
      }
7703
      if (truth) {
7704
        iterator(done);
7705
      } else {
7706
        callback(null);
7707
      }
7708
    }
7709

    
7710
    function done(err) {
7711
      if (err) {
7712
        return callback(err);
7713
      }
7714
      _test();
7715
    }
7716
  }
7717

    
7718
  /**
7719
   * @memberof async
7720
   * @namespace doDuring
7721
   * @param {Function} test
7722
   * @param {Function} iterator
7723
   * @param {Function} callback
7724
   */
7725
  function doDuring(iterator, test, callback) {
7726
    callback = callback || noop;
7727
    iterate(null, true);
7728

    
7729
    function iterate(err, truth) {
7730
      if (err) {
7731
        return callback(err);
7732
      }
7733
      if (truth) {
7734
        iterator(done);
7735
      } else {
7736
        callback(null);
7737
      }
7738
    }
7739

    
7740
    function done(err, res) {
7741
      if (err) {
7742
        return callback(err);
7743
      }
7744
      switch (arguments.length) {
7745
        case 0:
7746
        case 1:
7747
          test(iterate);
7748
          break;
7749
        case 2:
7750
          test(res, iterate);
7751
          break;
7752
        default:
7753
          var args = slice(arguments, 1);
7754
          args.push(iterate);
7755
          test.apply(null, args);
7756
          break;
7757
      }
7758
    }
7759
  }
7760

    
7761
  /**
7762
   * @memberof async
7763
   * @namespace forever
7764
   */
7765
  function forever(iterator, callback) {
7766
    var sync = false;
7767
    iterate();
7768

    
7769
    function iterate() {
7770
      iterator(next);
7771
    }
7772

    
7773
    function next(err) {
7774
      if (err) {
7775
        if (callback) {
7776
          return callback(err);
7777
        }
7778
        throw err;
7779
      }
7780
      if (sync) {
7781
        nextTick(iterate);
7782
      } else {
7783
        sync = true;
7784
        iterate();
7785
      }
7786
      sync = false;
7787
    }
7788
  }
7789

    
7790
  /**
7791
   * @memberof async
7792
   * @namespace compose
7793
   */
7794
  function compose() {
7795
    return seq.apply(null, reverse(arguments));
7796
  }
7797

    
7798
  /**
7799
   * @memberof async
7800
   * @namespace seq
7801
   */
7802
  function seq(/* functions... */) {
7803
    var fns = createArray(arguments);
7804

    
7805
    return function() {
7806
      var self = this;
7807
      var args = createArray(arguments);
7808
      var callback = args[args.length - 1];
7809
      if (typeof callback === func) {
7810
        args.pop();
7811
      } else {
7812
        callback = noop;
7813
      }
7814
      reduce(fns, args, iterator, done);
7815

    
7816
      function iterator(newargs, fn, callback) {
7817
        var func = function(err) {
7818
          var nextargs = slice(arguments, 1);
7819
          callback(err, nextargs);
7820
        };
7821
        newargs.push(func);
7822
        fn.apply(self, newargs);
7823
      }
7824

    
7825
      function done(err, res) {
7826
        res = isArray(res) ? res : [res];
7827
        res.unshift(err);
7828
        callback.apply(self, res);
7829
      }
7830
    };
7831
  }
7832

    
7833
  function createApplyEach(func) {
7834
    return function applyEach(fns /* arguments */) {
7835
      var go = function() {
7836
        var self = this;
7837
        var args = createArray(arguments);
7838
        var callback = args.pop() || noop;
7839
        return func(fns, iterator, callback);
7840

    
7841
        function iterator(fn, done) {
7842
          fn.apply(self, args.concat([done]));
7843
        }
7844
      };
7845
      if (arguments.length > 1) {
7846
        var args = slice(arguments, 1);
7847
        return go.apply(this, args);
7848
      } else {
7849
        return go;
7850
      }
7851
    };
7852
  }
7853

    
7854
  /**
7855
   * @see https://github.com/caolan/async/blob/master/lib/internal/DoublyLinkedList.js
7856
   */
7857
  function DLL() {
7858
    this.head = null;
7859
    this.tail = null;
7860
    this.length = 0;
7861
  }
7862

    
7863
  DLL.prototype._removeLink = function(node) {
7864
    var prev = node.prev;
7865
    var next = node.next;
7866
    if (prev) {
7867
      prev.next = next;
7868
    } else {
7869
      this.head = next;
7870
    }
7871
    if (next) {
7872
      next.prev = prev;
7873
    } else {
7874
      this.tail = prev;
7875
    }
7876
    node.prev = null;
7877
    node.next = null;
7878
    this.length--;
7879
    return node;
7880
  };
7881

    
7882
  DLL.prototype.empty = DLL;
7883

    
7884
  DLL.prototype._setInitial = function(node) {
7885
    this.length = 1;
7886
    this.head = this.tail = node;
7887
  };
7888

    
7889
  DLL.prototype.insertBefore = function(node, newNode) {
7890
    newNode.prev = node.prev;
7891
    newNode.next = node;
7892
    if (node.prev) {
7893
      node.prev.next = newNode;
7894
    } else {
7895
      this.head = newNode;
7896
    }
7897
    node.prev = newNode;
7898
    this.length++;
7899
  };
7900

    
7901
  DLL.prototype.unshift = function(node) {
7902
    if (this.head) {
7903
      this.insertBefore(this.head, node);
7904
    } else {
7905
      this._setInitial(node);
7906
    }
7907
  };
7908

    
7909
  DLL.prototype.push = function(node) {
7910
    var tail = this.tail;
7911
    if (tail) {
7912
      node.prev = tail;
7913
      node.next = tail.next;
7914
      this.tail = node;
7915
      tail.next = node;
7916
      this.length++;
7917
    } else {
7918
      this._setInitial(node);
7919
    }
7920
  };
7921

    
7922
  DLL.prototype.shift = function() {
7923
    return this.head && this._removeLink(this.head);
7924
  };
7925

    
7926
  DLL.prototype.splice = function(end) {
7927
    var task;
7928
    var tasks = [];
7929
    while (end-- && (task = this.shift())) {
7930
      tasks.push(task);
7931
    }
7932
    return tasks;
7933
  };
7934

    
7935
  DLL.prototype.remove = function(test) {
7936
    var node = this.head;
7937
    while (node) {
7938
      if (test(node)) {
7939
        this._removeLink(node);
7940
      }
7941
      node = node.next;
7942
    }
7943
    return this;
7944
  };
7945

    
7946
  /**
7947
   * @private
7948
   */
7949
  function baseQueue(isQueue, worker, concurrency, payload) {
7950
    if (concurrency === undefined) {
7951
      concurrency = 1;
7952
    } else if (isNaN(concurrency) || concurrency < 1) {
7953
      throw new Error('Concurrency must not be zero');
7954
    }
7955

    
7956
    var workers = 0;
7957
    var workersList = [];
7958
    var _callback, _unshift;
7959

    
7960
    var q = {
7961
      _tasks: new DLL(),
7962
      concurrency: concurrency,
7963
      payload: payload,
7964
      saturated: noop,
7965
      unsaturated: noop,
7966
      buffer: concurrency / 4,
7967
      empty: noop,
7968
      drain: noop,
7969
      error: noop,
7970
      started: false,
7971
      paused: false,
7972
      push: push,
7973
      kill: kill,
7974
      unshift: unshift,
7975
      remove: remove,
7976
      process: isQueue ? runQueue : runCargo,
7977
      length: getLength,
7978
      running: running,
7979
      workersList: getWorkersList,
7980
      idle: idle,
7981
      pause: pause,
7982
      resume: resume,
7983
      _worker: worker
7984
    };
7985
    return q;
7986

    
7987
    function push(tasks, callback) {
7988
      _insert(tasks, callback);
7989
    }
7990

    
7991
    function unshift(tasks, callback) {
7992
      _insert(tasks, callback, true);
7993
    }
7994

    
7995
    function _exec(task) {
7996
      var item = {
7997
        data: task,
7998
        callback: _callback
7999
      };
8000
      if (_unshift) {
8001
        q._tasks.unshift(item);
8002
      } else {
8003
        q._tasks.push(item);
8004
      }
8005
      nextTick(q.process);
8006
    }
8007

    
8008
    function _insert(tasks, callback, unshift) {
8009
      if (callback == null) {
8010
        callback = noop;
8011
      } else if (typeof callback !== 'function') {
8012
        throw new Error('task callback must be a function');
8013
      }
8014
      q.started = true;
8015
      var _tasks = isArray(tasks) ? tasks : [tasks];
8016

    
8017
      if (tasks === undefined || !_tasks.length) {
8018
        if (q.idle()) {
8019
          nextTick(q.drain);
8020
        }
8021
        return;
8022
      }
8023

    
8024
      _unshift = unshift;
8025
      _callback = callback;
8026
      arrayEachSync(_tasks, _exec);
8027
    }
8028

    
8029
    function kill() {
8030
      q.drain = noop;
8031
      q._tasks.empty();
8032
    }
8033

    
8034
    function _next(q, tasks) {
8035
      var called = false;
8036
      return function done(err, res) {
8037
        if (called) {
8038
          throwError();
8039
        }
8040
        called = true;
8041

    
8042
        workers--;
8043
        var task;
8044
        var index = -1;
8045
        var size = workersList.length;
8046
        var taskIndex = -1;
8047
        var taskSize = tasks.length;
8048
        var useApply = arguments.length > 2;
8049
        var args = useApply && createArray(arguments);
8050
        while (++taskIndex < taskSize) {
8051
          task = tasks[taskIndex];
8052
          while (++index < size) {
8053
            if (workersList[index] === task) {
8054
              if (index === 0) {
8055
                workersList.shift();
8056
              } else {
8057
                workersList.splice(index, 1);
8058
              }
8059
              index = size;
8060
              size--;
8061
            }
8062
          }
8063
          index = -1;
8064
          if (useApply) {
8065
            task.callback.apply(task, args);
8066
          } else {
8067
            task.callback(err, res);
8068
          }
8069
          if (err) {
8070
            q.error(err, task.data);
8071
          }
8072
        }
8073

    
8074
        if (workers <= q.concurrency - q.buffer) {
8075
          q.unsaturated();
8076
        }
8077

    
8078
        if (q._tasks.length + workers === 0) {
8079
          q.drain();
8080
        }
8081
        q.process();
8082
      };
8083
    }
8084

    
8085
    function runQueue() {
8086
      while (!q.paused && workers < q.concurrency && q._tasks.length) {
8087
        var task = q._tasks.shift();
8088
        workers++;
8089
        workersList.push(task);
8090
        if (q._tasks.length === 0) {
8091
          q.empty();
8092
        }
8093
        if (workers === q.concurrency) {
8094
          q.saturated();
8095
        }
8096
        var done = _next(q, [task]);
8097
        worker(task.data, done);
8098
      }
8099
    }
8100

    
8101
    function runCargo() {
8102
      while (!q.paused && workers < q.concurrency && q._tasks.length) {
8103
        var tasks = q._tasks.splice(q.payload || q._tasks.length);
8104
        var index = -1;
8105
        var size = tasks.length;
8106
        var data = Array(size);
8107
        while (++index < size) {
8108
          data[index] = tasks[index].data;
8109
        }
8110
        workers++;
8111
        nativePush.apply(workersList, tasks);
8112
        if (q._tasks.length === 0) {
8113
          q.empty();
8114
        }
8115
        if (workers === q.concurrency) {
8116
          q.saturated();
8117
        }
8118
        var done = _next(q, tasks);
8119
        worker(data, done);
8120
      }
8121
    }
8122

    
8123
    function getLength() {
8124
      return q._tasks.length;
8125
    }
8126

    
8127
    function running() {
8128
      return workers;
8129
    }
8130

    
8131
    function getWorkersList() {
8132
      return workersList;
8133
    }
8134

    
8135
    function idle() {
8136
      return q.length() + workers === 0;
8137
    }
8138

    
8139
    function pause() {
8140
      q.paused = true;
8141
    }
8142

    
8143
    function _resume() {
8144
      nextTick(q.process);
8145
    }
8146

    
8147
    function resume() {
8148
      if (q.paused === false) {
8149
        return;
8150
      }
8151
      q.paused = false;
8152
      var count = q.concurrency < q._tasks.length ? q.concurrency : q._tasks.length;
8153
      timesSync(count, _resume);
8154
    }
8155

    
8156
    /**
8157
     * @param {Function} test
8158
     */
8159
    function remove(test) {
8160
      q._tasks.remove(test);
8161
    }
8162
  }
8163

    
8164
  /**
8165
   * @memberof async
8166
   * @namespace queue
8167
   */
8168
  function queue(worker, concurrency) {
8169
    return baseQueue(true, worker, concurrency);
8170
  }
8171

    
8172
  /**
8173
   * @memberof async
8174
   * @namespace priorityQueue
8175
   */
8176
  function priorityQueue(worker, concurrency) {
8177
    var q = baseQueue(true, worker, concurrency);
8178
    q.push = push;
8179
    delete q.unshift;
8180
    return q;
8181

    
8182
    function push(tasks, priority, callback) {
8183
      q.started = true;
8184
      priority = priority || 0;
8185
      var _tasks = isArray(tasks) ? tasks : [tasks];
8186
      var taskSize = _tasks.length;
8187

    
8188
      if (tasks === undefined || taskSize === 0) {
8189
        if (q.idle()) {
8190
          nextTick(q.drain);
8191
        }
8192
        return;
8193
      }
8194

    
8195
      callback = typeof callback === func ? callback : noop;
8196
      var nextNode = q._tasks.head;
8197
      while (nextNode && priority >= nextNode.priority) {
8198
        nextNode = nextNode.next;
8199
      }
8200
      while (taskSize--) {
8201
        var item = {
8202
          data: _tasks[taskSize],
8203
          priority: priority,
8204
          callback: callback
8205
        };
8206
        if (nextNode) {
8207
          q._tasks.insertBefore(nextNode, item);
8208
        } else {
8209
          q._tasks.push(item);
8210
        }
8211
        nextTick(q.process);
8212
      }
8213
    }
8214
  }
8215

    
8216
  /**
8217
   * @memberof async
8218
   * @namespace cargo
8219
   */
8220
  function cargo(worker, payload) {
8221
    return baseQueue(false, worker, 1, payload);
8222
  }
8223

    
8224
  /**
8225
   * @memberof async
8226
   * @namespace auto
8227
   * @param {Object} tasks
8228
   * @param {number} [concurrency]
8229
   * @param {Function} [callback]
8230
   */
8231
  function auto(tasks, concurrency, callback) {
8232
    if (typeof concurrency === func) {
8233
      callback = concurrency;
8234
      concurrency = null;
8235
    }
8236
    var keys = nativeKeys(tasks);
8237
    var rest = keys.length;
8238
    var results = {};
8239
    if (rest === 0) {
8240
      return callback(null, results);
8241
    }
8242
    var runningTasks = 0;
8243
    var readyTasks = [];
8244
    var listeners = Object.create(null);
8245
    callback = onlyOnce(callback || noop);
8246
    concurrency = concurrency || rest;
8247

    
8248
    baseEachSync(tasks, iterator, keys);
8249
    proceedQueue();
8250

    
8251
    function iterator(task, key) {
8252
      // no dependencies
8253
      var _task, _taskSize;
8254
      if (!isArray(task)) {
8255
        _task = task;
8256
        _taskSize = 0;
8257
        readyTasks.push([_task, _taskSize, done]);
8258
        return;
8259
      }
8260
      var dependencySize = task.length - 1;
8261
      _task = task[dependencySize];
8262
      _taskSize = dependencySize;
8263
      if (dependencySize === 0) {
8264
        readyTasks.push([_task, _taskSize, done]);
8265
        return;
8266
      }
8267
      // dependencies
8268
      var index = -1;
8269
      while (++index < dependencySize) {
8270
        var dependencyName = task[index];
8271
        if (notInclude(keys, dependencyName)) {
8272
          var msg =
8273
            'async.auto task `' +
8274
            key +
8275
            '` has non-existent dependency `' +
8276
            dependencyName +
8277
            '` in ' +
8278
            task.join(', ');
8279
          throw new Error(msg);
8280
        }
8281
        var taskListeners = listeners[dependencyName];
8282
        if (!taskListeners) {
8283
          taskListeners = listeners[dependencyName] = [];
8284
        }
8285
        taskListeners.push(taskListener);
8286
      }
8287

    
8288
      function done(err, arg) {
8289
        if (key === null) {
8290
          throwError();
8291
        }
8292
        arg = arguments.length <= 2 ? arg : slice(arguments, 1);
8293
        if (err) {
8294
          rest = 0;
8295
          runningTasks = 0;
8296
          readyTasks.length = 0;
8297
          var safeResults = objectClone(results);
8298
          safeResults[key] = arg;
8299
          key = null;
8300
          var _callback = callback;
8301
          callback = noop;
8302
          _callback(err, safeResults);
8303
          return;
8304
        }
8305
        runningTasks--;
8306
        rest--;
8307
        results[key] = arg;
8308
        taskComplete(key);
8309
        key = null;
8310
      }
8311

    
8312
      function taskListener() {
8313
        if (--dependencySize === 0) {
8314
          readyTasks.push([_task, _taskSize, done]);
8315
        }
8316
      }
8317
    }
8318

    
8319
    function proceedQueue() {
8320
      if (readyTasks.length === 0 && runningTasks === 0) {
8321
        if (rest !== 0) {
8322
          throw new Error('async.auto task has cyclic dependencies');
8323
        }
8324
        return callback(null, results);
8325
      }
8326
      while (readyTasks.length && runningTasks < concurrency && callback !== noop) {
8327
        runningTasks++;
8328
        var array = readyTasks.shift();
8329
        if (array[1] === 0) {
8330
          array[0](array[2]);
8331
        } else {
8332
          array[0](results, array[2]);
8333
        }
8334
      }
8335
    }
8336

    
8337
    function taskComplete(key) {
8338
      var taskListeners = listeners[key] || [];
8339
      arrayEachSync(taskListeners, function(task) {
8340
        task();
8341
      });
8342
      proceedQueue();
8343
    }
8344
  }
8345

    
8346
  var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
8347
  var FN_ARG_SPLIT = /,/;
8348
  var FN_ARG = /(=.+)?(\s*)$/;
8349
  var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
8350

    
8351
  /**
8352
   * parse function arguments for `autoInject`
8353
   *
8354
   * @private
8355
   */
8356
  function parseParams(func) {
8357
    func = func.toString().replace(STRIP_COMMENTS, '');
8358
    func = func.match(FN_ARGS)[2].replace(' ', '');
8359
    func = func ? func.split(FN_ARG_SPLIT) : [];
8360
    func = func.map(function(arg) {
8361
      return arg.replace(FN_ARG, '').trim();
8362
    });
8363
    return func;
8364
  }
8365

    
8366
  /**
8367
   * @memberof async
8368
   * @namespace autoInject
8369
   * @param {Object} tasks
8370
   * @param {number} [concurrency]
8371
   * @param {Function} [callback]
8372
   */
8373
  function autoInject(tasks, concurrency, callback) {
8374
    var newTasks = {};
8375
    baseEachSync(tasks, iterator, nativeKeys(tasks));
8376
    auto(newTasks, concurrency, callback);
8377

    
8378
    function iterator(task, key) {
8379
      var params;
8380
      var taskLength = task.length;
8381

    
8382
      if (isArray(task)) {
8383
        if (taskLength === 0) {
8384
          throw new Error('autoInject task functions require explicit parameters.');
8385
        }
8386
        params = createArray(task);
8387
        taskLength = params.length - 1;
8388
        task = params[taskLength];
8389
        if (taskLength === 0) {
8390
          newTasks[key] = task;
8391
          return;
8392
        }
8393
      } else if (taskLength === 1) {
8394
        newTasks[key] = task;
8395
        return;
8396
      } else {
8397
        params = parseParams(task);
8398
        if (taskLength === 0 && params.length === 0) {
8399
          throw new Error('autoInject task functions require explicit parameters.');
8400
        }
8401
        taskLength = params.length - 1;
8402
      }
8403
      params[taskLength] = newTask;
8404
      newTasks[key] = params;
8405

    
8406
      function newTask(results, done) {
8407
        switch (taskLength) {
8408
          case 1:
8409
            task(results[params[0]], done);
8410
            break;
8411
          case 2:
8412
            task(results[params[0]], results[params[1]], done);
8413
            break;
8414
          case 3:
8415
            task(results[params[0]], results[params[1]], results[params[2]], done);
8416
            break;
8417
          default:
8418
            var i = -1;
8419
            while (++i < taskLength) {
8420
              params[i] = results[params[i]];
8421
            }
8422
            params[i] = done;
8423
            task.apply(null, params);
8424
            break;
8425
        }
8426
      }
8427
    }
8428
  }
8429

    
8430
  /**
8431
   * @memberof async
8432
   * @namespace retry
8433
   * @param {integer|Object|Function} opts
8434
   * @param {Function} [task]
8435
   * @param {Function} [callback]
8436
   */
8437
  function retry(opts, task, callback) {
8438
    var times, intervalFunc, errorFilter;
8439
    var count = 0;
8440
    if (arguments.length < 3 && typeof opts === func) {
8441
      callback = task || noop;
8442
      task = opts;
8443
      opts = null;
8444
      times = DEFAULT_TIMES;
8445
    } else {
8446
      callback = callback || noop;
8447
      switch (typeof opts) {
8448
        case 'object':
8449
          if (typeof opts.errorFilter === func) {
8450
            errorFilter = opts.errorFilter;
8451
          }
8452
          var interval = opts.interval;
8453
          switch (typeof interval) {
8454
            case func:
8455
              intervalFunc = interval;
8456
              break;
8457
            case 'string':
8458
            case 'number':
8459
              interval = +interval;
8460
              intervalFunc = interval
8461
                ? function() {
8462
                    return interval;
8463
                  }
8464
                : function() {
8465
                    return DEFAULT_INTERVAL;
8466
                  };
8467
              break;
8468
          }
8469
          times = +opts.times || DEFAULT_TIMES;
8470
          break;
8471
        case 'number':
8472
          times = opts || DEFAULT_TIMES;
8473
          break;
8474
        case 'string':
8475
          times = +opts || DEFAULT_TIMES;
8476
          break;
8477
        default:
8478
          throw new Error('Invalid arguments for async.retry');
8479
      }
8480
    }
8481
    if (typeof task !== 'function') {
8482
      throw new Error('Invalid arguments for async.retry');
8483
    }
8484

    
8485
    if (intervalFunc) {
8486
      task(intervalCallback);
8487
    } else {
8488
      task(simpleCallback);
8489
    }
8490

    
8491
    function simpleIterator() {
8492
      task(simpleCallback);
8493
    }
8494

    
8495
    function simpleCallback(err, res) {
8496
      if (++count === times || !err || (errorFilter && !errorFilter(err))) {
8497
        if (arguments.length <= 2) {
8498
          return callback(err, res);
8499
        }
8500
        var args = createArray(arguments);
8501
        return callback.apply(null, args);
8502
      }
8503
      simpleIterator();
8504
    }
8505

    
8506
    function intervalIterator() {
8507
      task(intervalCallback);
8508
    }
8509

    
8510
    function intervalCallback(err, res) {
8511
      if (++count === times || !err || (errorFilter && !errorFilter(err))) {
8512
        if (arguments.length <= 2) {
8513
          return callback(err, res);
8514
        }
8515
        var args = createArray(arguments);
8516
        return callback.apply(null, args);
8517
      }
8518
      setTimeout(intervalIterator, intervalFunc(count));
8519
    }
8520
  }
8521

    
8522
  function retryable(opts, task) {
8523
    if (!task) {
8524
      task = opts;
8525
      opts = null;
8526
    }
8527
    return done;
8528

    
8529
    function done() {
8530
      var taskFn;
8531
      var args = createArray(arguments);
8532
      var lastIndex = args.length - 1;
8533
      var callback = args[lastIndex];
8534
      switch (task.length) {
8535
        case 1:
8536
          taskFn = task1;
8537
          break;
8538
        case 2:
8539
          taskFn = task2;
8540
          break;
8541
        case 3:
8542
          taskFn = task3;
8543
          break;
8544
        default:
8545
          taskFn = task4;
8546
      }
8547
      if (opts) {
8548
        retry(opts, taskFn, callback);
8549
      } else {
8550
        retry(taskFn, callback);
8551
      }
8552

    
8553
      function task1(done) {
8554
        task(done);
8555
      }
8556

    
8557
      function task2(done) {
8558
        task(args[0], done);
8559
      }
8560

    
8561
      function task3(done) {
8562
        task(args[0], args[1], done);
8563
      }
8564

    
8565
      function task4(callback) {
8566
        args[lastIndex] = callback;
8567
        task.apply(null, args);
8568
      }
8569
    }
8570
  }
8571

    
8572
  /**
8573
   * @memberof async
8574
   * @namespace iterator
8575
   */
8576
  function iterator(tasks) {
8577
    var size = 0;
8578
    var keys = [];
8579
    if (isArray(tasks)) {
8580
      size = tasks.length;
8581
    } else {
8582
      keys = nativeKeys(tasks);
8583
      size = keys.length;
8584
    }
8585
    return makeCallback(0);
8586

    
8587
    function makeCallback(index) {
8588
      var fn = function() {
8589
        if (size) {
8590
          var key = keys[index] || index;
8591
          tasks[key].apply(null, createArray(arguments));
8592
        }
8593
        return fn.next();
8594
      };
8595
      fn.next = function() {
8596
        return index < size - 1 ? makeCallback(index + 1) : null;
8597
      };
8598
      return fn;
8599
    }
8600
  }
8601

    
8602
  /**
8603
   * @memberof async
8604
   * @namespace apply
8605
   */
8606
  function apply(func) {
8607
    switch (arguments.length) {
8608
      case 0:
8609
      case 1:
8610
        return func;
8611
      case 2:
8612
        return func.bind(null, arguments[1]);
8613
      case 3:
8614
        return func.bind(null, arguments[1], arguments[2]);
8615
      case 4:
8616
        return func.bind(null, arguments[1], arguments[2], arguments[3]);
8617
      case 5:
8618
        return func.bind(null, arguments[1], arguments[2], arguments[3], arguments[4]);
8619
      default:
8620
        var size = arguments.length;
8621
        var index = 0;
8622
        var args = Array(size);
8623
        args[index] = null;
8624
        while (++index < size) {
8625
          args[index] = arguments[index];
8626
        }
8627
        return func.bind.apply(func, args);
8628
    }
8629
  }
8630

    
8631
  /**
8632
   * @memberof async
8633
   * @namespace timeout
8634
   * @param {Function} func
8635
   * @param {number} millisec
8636
   * @param {*} info
8637
   */
8638
  function timeout(func, millisec, info) {
8639
    var callback, timer;
8640
    return wrappedFunc;
8641

    
8642
    function wrappedFunc() {
8643
      timer = setTimeout(timeoutCallback, millisec);
8644
      var args = createArray(arguments);
8645
      var lastIndex = args.length - 1;
8646
      callback = args[lastIndex];
8647
      args[lastIndex] = injectedCallback;
8648
      simpleApply(func, args);
8649
    }
8650

    
8651
    function timeoutCallback() {
8652
      var name = func.name || 'anonymous';
8653
      var err = new Error('Callback function "' + name + '" timed out.');
8654
      err.code = 'ETIMEDOUT';
8655
      if (info) {
8656
        err.info = info;
8657
      }
8658
      timer = null;
8659
      callback(err);
8660
    }
8661

    
8662
    function injectedCallback() {
8663
      if (timer !== null) {
8664
        simpleApply(callback, createArray(arguments));
8665
        clearTimeout(timer);
8666
      }
8667
    }
8668

    
8669
    function simpleApply(func, args) {
8670
      switch (args.length) {
8671
        case 0:
8672
          func();
8673
          break;
8674
        case 1:
8675
          func(args[0]);
8676
          break;
8677
        case 2:
8678
          func(args[0], args[1]);
8679
          break;
8680
        default:
8681
          func.apply(null, args);
8682
          break;
8683
      }
8684
    }
8685
  }
8686

    
8687
  /**
8688
   * @memberof async
8689
   * @namespace times
8690
   * @param {number} n - n >= 1
8691
   * @param {Function} iterator
8692
   * @param {Function} callback
8693
   * @example
8694
   *
8695
   * var iterator = function(n, done) {
8696
   *   done(null, n);
8697
   * };
8698
   * async.times(4, iterator, function(err, res) {
8699
   *   console.log(res); // [0, 1, 2, 3];
8700
   * });
8701
   *
8702
   */
8703
  function times(n, iterator, callback) {
8704
    callback = callback || noop;
8705
    n = +n;
8706
    if (isNaN(n) || n < 1) {
8707
      return callback(null, []);
8708
    }
8709
    var result = Array(n);
8710
    timesSync(n, iterate);
8711

    
8712
    function iterate(num) {
8713
      iterator(num, createCallback(num));
8714
    }
8715

    
8716
    function createCallback(index) {
8717
      return function(err, res) {
8718
        if (index === null) {
8719
          throwError();
8720
        }
8721
        result[index] = res;
8722
        index = null;
8723
        if (err) {
8724
          callback(err);
8725
          callback = noop;
8726
        } else if (--n === 0) {
8727
          callback(null, result);
8728
        }
8729
      };
8730
    }
8731
  }
8732

    
8733
  /**
8734
   * @memberof async
8735
   * @namespace timesSeries
8736
   * @param {number} n - n >= 1
8737
   * @param {Function} iterator
8738
   * @param {Function} callback
8739
   * @example
8740
   *
8741
   * var iterator = function(n, done) {
8742
   *   done(null, n);
8743
   * };
8744
   * async.timesSeries(4, iterator, function(err, res) {
8745
   *   console.log(res); // [0, 1, 2, 3];
8746
   * });
8747
   *
8748
   */
8749
  function timesSeries(n, iterator, callback) {
8750
    callback = callback || noop;
8751
    n = +n;
8752
    if (isNaN(n) || n < 1) {
8753
      return callback(null, []);
8754
    }
8755
    var result = Array(n);
8756
    var sync = false;
8757
    var completed = 0;
8758
    iterate();
8759

    
8760
    function iterate() {
8761
      iterator(completed, done);
8762
    }
8763

    
8764
    function done(err, res) {
8765
      result[completed] = res;
8766
      if (err) {
8767
        callback(err);
8768
        callback = throwError;
8769
      } else if (++completed >= n) {
8770
        callback(null, result);
8771
        callback = throwError;
8772
      } else if (sync) {
8773
        nextTick(iterate);
8774
      } else {
8775
        sync = true;
8776
        iterate();
8777
      }
8778
      sync = false;
8779
    }
8780
  }
8781

    
8782
  /**
8783
   * @memberof async
8784
   * @namespace timesLimit
8785
   * @param {number} n - n >= 1
8786
   * @param {number} limit - n >= 1
8787
   * @param {Function} iterator
8788
   * @param {Function} callback
8789
   * @example
8790
   *
8791
   * var iterator = function(n, done) {
8792
   *   done(null, n);
8793
   * };
8794
   * async.timesLimit(4, 2, iterator, function(err, res) {
8795
   *   console.log(res); // [0, 1, 2, 3];
8796
   * });
8797
   *
8798
   */
8799
  function timesLimit(n, limit, iterator, callback) {
8800
    callback = callback || noop;
8801
    n = +n;
8802
    if (isNaN(n) || n < 1 || isNaN(limit) || limit < 1) {
8803
      return callback(null, []);
8804
    }
8805
    var result = Array(n);
8806
    var sync = false;
8807
    var started = 0;
8808
    var completed = 0;
8809
    timesSync(limit > n ? n : limit, iterate);
8810

    
8811
    function iterate() {
8812
      var index = started++;
8813
      if (index < n) {
8814
        iterator(index, createCallback(index));
8815
      }
8816
    }
8817

    
8818
    function createCallback(index) {
8819
      return function(err, res) {
8820
        if (index === null) {
8821
          throwError();
8822
        }
8823
        result[index] = res;
8824
        index = null;
8825
        if (err) {
8826
          callback(err);
8827
          callback = noop;
8828
        } else if (++completed >= n) {
8829
          callback(null, result);
8830
          callback = throwError;
8831
        } else if (sync) {
8832
          nextTick(iterate);
8833
        } else {
8834
          sync = true;
8835
          iterate();
8836
        }
8837
        sync = false;
8838
      };
8839
    }
8840
  }
8841

    
8842
  /**
8843
   * @memberof async
8844
   * @namespace race
8845
   * @param {Array|Object} tasks - functions
8846
   * @param {Function} callback
8847
   * @example
8848
   *
8849
   * // array
8850
   * var called = 0;
8851
   * var tasks = [
8852
   *   function(done) {
8853
   *     setTimeout(function() {
8854
   *       called++;
8855
   *       done(null, '1');
8856
   *     }, 30);
8857
   *   },
8858
   *   function(done) {
8859
   *     setTimeout(function() {
8860
   *       called++;
8861
   *       done(null, '2');
8862
   *     }, 20);
8863
   *   },
8864
   *   function(done) {
8865
   *     setTimeout(function() {
8866
   *       called++;
8867
   *       done(null, '3');
8868
   *     }, 10);
8869
   *   }
8870
   * ];
8871
   * async.race(tasks, function(err, res) {
8872
   *   console.log(res); // '3'
8873
   *   console.log(called); // 1
8874
   *   setTimeout(function() {
8875
   *     console.log(called); // 3
8876
   *   }, 50);
8877
   * });
8878
   *
8879
   * @example
8880
   *
8881
   * // object
8882
   * var called = 0;
8883
   * var tasks = {
8884
   *   'test1': function(done) {
8885
   *     setTimeout(function() {
8886
   *       called++;
8887
   *       done(null, '1');
8888
   *     }, 30);
8889
   *   },
8890
   *   'test2': function(done) {
8891
   *     setTimeout(function() {
8892
   *       called++;
8893
   *       done(null, '2');
8894
   *     }, 20);
8895
   *   },
8896
   *   'test3': function(done) {
8897
   *     setTimeout(function() {
8898
   *       called++;
8899
   *       done(null, '3');
8900
   *     }, 10);
8901
   *   }
8902
   * };
8903
   * async.race(tasks, function(err, res) {
8904
   *   console.log(res); // '3'
8905
   *   console.log(called); // 1
8906
   *   setTimeout(function() {
8907
   *     console.log(called); // 3
8908
   *     done();
8909
   *   }, 50);
8910
   * });
8911
   *
8912
   */
8913
  function race(tasks, callback) {
8914
    callback = once(callback || noop);
8915
    var size, keys;
8916
    var index = -1;
8917
    if (isArray(tasks)) {
8918
      size = tasks.length;
8919
      while (++index < size) {
8920
        tasks[index](callback);
8921
      }
8922
    } else if (tasks && typeof tasks === obj) {
8923
      keys = nativeKeys(tasks);
8924
      size = keys.length;
8925
      while (++index < size) {
8926
        tasks[keys[index]](callback);
8927
      }
8928
    } else {
8929
      return callback(new TypeError('First argument to race must be a collection of functions'));
8930
    }
8931
    if (!size) {
8932
      callback(null);
8933
    }
8934
  }
8935

    
8936
  /**
8937
   * @memberof async
8938
   * @namespace memoize
8939
   */
8940
  function memoize(fn, hasher) {
8941
    hasher =
8942
      hasher ||
8943
      function(hash) {
8944
        return hash;
8945
      };
8946

    
8947
    var memo = {};
8948
    var queues = {};
8949
    var memoized = function() {
8950
      var args = createArray(arguments);
8951
      var callback = args.pop();
8952
      var key = hasher.apply(null, args);
8953
      if (has(memo, key)) {
8954
        nextTick(function() {
8955
          callback.apply(null, memo[key]);
8956
        });
8957
        return;
8958
      }
8959
      if (has(queues, key)) {
8960
        return queues[key].push(callback);
8961
      }
8962

    
8963
      queues[key] = [callback];
8964
      args.push(done);
8965
      fn.apply(null, args);
8966

    
8967
      function done(err) {
8968
        var args = createArray(arguments);
8969
        if (!err) {
8970
          memo[key] = args;
8971
        }
8972
        var q = queues[key];
8973
        delete queues[key];
8974

    
8975
        var i = -1;
8976
        var size = q.length;
8977
        while (++i < size) {
8978
          q[i].apply(null, args);
8979
        }
8980
      }
8981
    };
8982
    memoized.memo = memo;
8983
    memoized.unmemoized = fn;
8984
    return memoized;
8985
  }
8986

    
8987
  /**
8988
   * @memberof async
8989
   * @namespace unmemoize
8990
   */
8991
  function unmemoize(fn) {
8992
    return function() {
8993
      return (fn.unmemoized || fn).apply(null, arguments);
8994
    };
8995
  }
8996

    
8997
  /**
8998
   * @memberof async
8999
   * @namespace ensureAsync
9000
   */
9001
  function ensureAsync(fn) {
9002
    return function(/* ...args, callback */) {
9003
      var args = createArray(arguments);
9004
      var lastIndex = args.length - 1;
9005
      var callback = args[lastIndex];
9006
      var sync = true;
9007
      args[lastIndex] = done;
9008
      fn.apply(this, args);
9009
      sync = false;
9010

    
9011
      function done() {
9012
        var innerArgs = createArray(arguments);
9013
        if (sync) {
9014
          nextTick(function() {
9015
            callback.apply(null, innerArgs);
9016
          });
9017
        } else {
9018
          callback.apply(null, innerArgs);
9019
        }
9020
      }
9021
    };
9022
  }
9023

    
9024
  /**
9025
   * @memberof async
9026
   * @namespace constant
9027
   */
9028
  function constant(/* values... */) {
9029
    var args = [null].concat(createArray(arguments));
9030
    return function(callback) {
9031
      callback = arguments[arguments.length - 1];
9032
      callback.apply(this, args);
9033
    };
9034
  }
9035

    
9036
  function asyncify(fn) {
9037
    return function(/* args..., callback */) {
9038
      var args = createArray(arguments);
9039
      var callback = args.pop();
9040
      var result;
9041
      try {
9042
        result = fn.apply(this, args);
9043
      } catch (e) {
9044
        return callback(e);
9045
      }
9046
      if (result && typeof result.then === func) {
9047
        result.then(
9048
          function(value) {
9049
            invokeCallback(callback, null, value);
9050
          },
9051
          function(err) {
9052
            invokeCallback(callback, err && err.message ? err : new Error(err));
9053
          }
9054
        );
9055
      } else {
9056
        callback(null, result);
9057
      }
9058
    };
9059
  }
9060

    
9061
  function invokeCallback(callback, err, value) {
9062
    try {
9063
      callback(err, value);
9064
    } catch (e) {
9065
      nextTick(rethrow, e);
9066
    }
9067
  }
9068

    
9069
  function rethrow(error) {
9070
    throw error;
9071
  }
9072

    
9073
  /**
9074
   * @memberof async
9075
   * @namespace reflect
9076
   * @param {Function} func
9077
   * @return {Function}
9078
   */
9079
  function reflect(func) {
9080
    return function(/* args..., callback */) {
9081
      var callback;
9082
      switch (arguments.length) {
9083
        case 1:
9084
          callback = arguments[0];
9085
          return func(done);
9086
        case 2:
9087
          callback = arguments[1];
9088
          return func(arguments[0], done);
9089
        default:
9090
          var args = createArray(arguments);
9091
          var lastIndex = args.length - 1;
9092
          callback = args[lastIndex];
9093
          args[lastIndex] = done;
9094
          func.apply(this, args);
9095
      }
9096

    
9097
      function done(err, res) {
9098
        if (err) {
9099
          return callback(null, {
9100
            error: err
9101
          });
9102
        }
9103
        if (arguments.length > 2) {
9104
          res = slice(arguments, 1);
9105
        }
9106
        callback(null, {
9107
          value: res
9108
        });
9109
      }
9110
    };
9111
  }
9112

    
9113
  /**
9114
   * @memberof async
9115
   * @namespace reflectAll
9116
   * @param {Array[]|Object} tasks
9117
   * @return {Function}
9118
   */
9119
  function reflectAll(tasks) {
9120
    var newTasks, keys;
9121
    if (isArray(tasks)) {
9122
      newTasks = Array(tasks.length);
9123
      arrayEachSync(tasks, iterate);
9124
    } else if (tasks && typeof tasks === obj) {
9125
      keys = nativeKeys(tasks);
9126
      newTasks = {};
9127
      baseEachSync(tasks, iterate, keys);
9128
    }
9129
    return newTasks;
9130

    
9131
    function iterate(func, key) {
9132
      newTasks[key] = reflect(func);
9133
    }
9134
  }
9135

    
9136
  /**
9137
   * @memberof async
9138
   * @namespace createLogger
9139
   */
9140
  function createLogger(name) {
9141
    return function(fn) {
9142
      var args = slice(arguments, 1);
9143
      args.push(done);
9144
      fn.apply(null, args);
9145
    };
9146

    
9147
    function done(err) {
9148
      if (typeof console === obj) {
9149
        if (err) {
9150
          if (console.error) {
9151
            console.error(err);
9152
          }
9153
          return;
9154
        }
9155
        if (console[name]) {
9156
          var args = slice(arguments, 1);
9157
          arrayEachSync(args, function(arg) {
9158
            console[name](arg);
9159
          });
9160
        }
9161
      }
9162
    }
9163
  }
9164

    
9165
  /**
9166
   * @memberof async
9167
   * @namespace safe
9168
   */
9169
  function safe() {
9170
    createImmediate();
9171
    return exports;
9172
  }
9173

    
9174
  /**
9175
   * @memberof async
9176
   * @namespace fast
9177
   */
9178
  function fast() {
9179
    createImmediate(false);
9180
    return exports;
9181
  }
9182
});
(10-10/116)