UNPKG

98 kBJavaScriptView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3/*-----------------------------------------------------------------------------
4| Copyright (c) 2014-2017, PhosphorJS Contributors
5|
6| Distributed under the terms of the BSD 3-Clause License.
7|
8| The full license is in the file LICENSE, distributed with this software.
9|----------------------------------------------------------------------------*/
10/**
11 * The namespace for array-specific algorithms.
12 */
13var ArrayExt;
14(function (ArrayExt) {
15 /**
16 * Find the index of the first occurrence of a value in an array.
17 *
18 * @param array - The array-like object to search.
19 *
20 * @param value - The value to locate in the array. Values are
21 * compared using strict `===` equality.
22 *
23 * @param start - The index of the first element in the range to be
24 * searched, inclusive. The default value is `0`. Negative values
25 * are taken as an offset from the end of the array.
26 *
27 * @param stop - The index of the last element in the range to be
28 * searched, inclusive. The default value is `-1`. Negative values
29 * are taken as an offset from the end of the array.
30 *
31 * @returns The index of the first occurrence of the value, or `-1`
32 * if the value is not found.
33 *
34 * #### Notes
35 * If `stop < start` the search will wrap at the end of the array.
36 *
37 * #### Complexity
38 * Linear.
39 *
40 * #### Undefined Behavior
41 * A `start` or `stop` which is non-integral.
42 *
43 * #### Example
44 * ```typescript
45 * import { ArrayExt } from '@lumino/algorithm';
46 *
47 * let data = ['one', 'two', 'three', 'four', 'one'];
48 * ArrayExt.firstIndexOf(data, 'red'); // -1
49 * ArrayExt.firstIndexOf(data, 'one'); // 0
50 * ArrayExt.firstIndexOf(data, 'one', 1); // 4
51 * ArrayExt.firstIndexOf(data, 'two', 2); // -1
52 * ArrayExt.firstIndexOf(data, 'two', 2, 1); // 1
53 * ```
54 */
55 function firstIndexOf(array, value, start, stop) {
56 if (start === void 0) { start = 0; }
57 if (stop === void 0) { stop = -1; }
58 var n = array.length;
59 if (n === 0) {
60 return -1;
61 }
62 if (start < 0) {
63 start = Math.max(0, start + n);
64 }
65 else {
66 start = Math.min(start, n - 1);
67 }
68 if (stop < 0) {
69 stop = Math.max(0, stop + n);
70 }
71 else {
72 stop = Math.min(stop, n - 1);
73 }
74 var span;
75 if (stop < start) {
76 span = stop + 1 + (n - start);
77 }
78 else {
79 span = stop - start + 1;
80 }
81 for (var i = 0; i < span; ++i) {
82 var j = (start + i) % n;
83 if (array[j] === value) {
84 return j;
85 }
86 }
87 return -1;
88 }
89 ArrayExt.firstIndexOf = firstIndexOf;
90 /**
91 * Find the index of the last occurrence of a value in an array.
92 *
93 * @param array - The array-like object to search.
94 *
95 * @param value - The value to locate in the array. Values are
96 * compared using strict `===` equality.
97 *
98 * @param start - The index of the first element in the range to be
99 * searched, inclusive. The default value is `-1`. Negative values
100 * are taken as an offset from the end of the array.
101 *
102 * @param stop - The index of the last element in the range to be
103 * searched, inclusive. The default value is `0`. Negative values
104 * are taken as an offset from the end of the array.
105 *
106 * @returns The index of the last occurrence of the value, or `-1`
107 * if the value is not found.
108 *
109 * #### Notes
110 * If `start < stop` the search will wrap at the front of the array.
111 *
112 * #### Complexity
113 * Linear.
114 *
115 * #### Undefined Behavior
116 * A `start` or `stop` which is non-integral.
117 *
118 * #### Example
119 * ```typescript
120 * import { ArrayExt } from '@lumino/algorithm';
121 *
122 * let data = ['one', 'two', 'three', 'four', 'one'];
123 * ArrayExt.lastIndexOf(data, 'red'); // -1
124 * ArrayExt.lastIndexOf(data, 'one'); // 4
125 * ArrayExt.lastIndexOf(data, 'one', 1); // 0
126 * ArrayExt.lastIndexOf(data, 'two', 0); // -1
127 * ArrayExt.lastIndexOf(data, 'two', 0, 1); // 1
128 * ```
129 */
130 function lastIndexOf(array, value, start, stop) {
131 if (start === void 0) { start = -1; }
132 if (stop === void 0) { stop = 0; }
133 var n = array.length;
134 if (n === 0) {
135 return -1;
136 }
137 if (start < 0) {
138 start = Math.max(0, start + n);
139 }
140 else {
141 start = Math.min(start, n - 1);
142 }
143 if (stop < 0) {
144 stop = Math.max(0, stop + n);
145 }
146 else {
147 stop = Math.min(stop, n - 1);
148 }
149 var span;
150 if (start < stop) {
151 span = start + 1 + (n - stop);
152 }
153 else {
154 span = start - stop + 1;
155 }
156 for (var i = 0; i < span; ++i) {
157 var j = (start - i + n) % n;
158 if (array[j] === value) {
159 return j;
160 }
161 }
162 return -1;
163 }
164 ArrayExt.lastIndexOf = lastIndexOf;
165 /**
166 * Find the index of the first value which matches a predicate.
167 *
168 * @param array - The array-like object to search.
169 *
170 * @param fn - The predicate function to apply to the values.
171 *
172 * @param start - The index of the first element in the range to be
173 * searched, inclusive. The default value is `0`. Negative values
174 * are taken as an offset from the end of the array.
175 *
176 * @param stop - The index of the last element in the range to be
177 * searched, inclusive. The default value is `-1`. Negative values
178 * are taken as an offset from the end of the array.
179 *
180 * @returns The index of the first matching value, or `-1` if no
181 * matching value is found.
182 *
183 * #### Notes
184 * If `stop < start` the search will wrap at the end of the array.
185 *
186 * #### Complexity
187 * Linear.
188 *
189 * #### Undefined Behavior
190 * A `start` or `stop` which is non-integral.
191 *
192 * Modifying the length of the array while searching.
193 *
194 * #### Example
195 * ```typescript
196 * import { ArrayExt } from '@lumino/algorithm';
197 *
198 * function isEven(value: number): boolean {
199 * return value % 2 === 0;
200 * }
201 *
202 * let data = [1, 2, 3, 4, 3, 2, 1];
203 * ArrayExt.findFirstIndex(data, isEven); // 1
204 * ArrayExt.findFirstIndex(data, isEven, 4); // 5
205 * ArrayExt.findFirstIndex(data, isEven, 6); // -1
206 * ArrayExt.findFirstIndex(data, isEven, 6, 5); // 1
207 * ```
208 */
209 function findFirstIndex(array, fn, start, stop) {
210 if (start === void 0) { start = 0; }
211 if (stop === void 0) { stop = -1; }
212 var n = array.length;
213 if (n === 0) {
214 return -1;
215 }
216 if (start < 0) {
217 start = Math.max(0, start + n);
218 }
219 else {
220 start = Math.min(start, n - 1);
221 }
222 if (stop < 0) {
223 stop = Math.max(0, stop + n);
224 }
225 else {
226 stop = Math.min(stop, n - 1);
227 }
228 var span;
229 if (stop < start) {
230 span = stop + 1 + (n - start);
231 }
232 else {
233 span = stop - start + 1;
234 }
235 for (var i = 0; i < span; ++i) {
236 var j = (start + i) % n;
237 if (fn(array[j], j)) {
238 return j;
239 }
240 }
241 return -1;
242 }
243 ArrayExt.findFirstIndex = findFirstIndex;
244 /**
245 * Find the index of the last value which matches a predicate.
246 *
247 * @param object - The array-like object to search.
248 *
249 * @param fn - The predicate function to apply to the values.
250 *
251 * @param start - The index of the first element in the range to be
252 * searched, inclusive. The default value is `-1`. Negative values
253 * are taken as an offset from the end of the array.
254 *
255 * @param stop - The index of the last element in the range to be
256 * searched, inclusive. The default value is `0`. Negative values
257 * are taken as an offset from the end of the array.
258 *
259 * @returns The index of the last matching value, or `-1` if no
260 * matching value is found.
261 *
262 * #### Notes
263 * If `start < stop` the search will wrap at the front of the array.
264 *
265 * #### Complexity
266 * Linear.
267 *
268 * #### Undefined Behavior
269 * A `start` or `stop` which is non-integral.
270 *
271 * Modifying the length of the array while searching.
272 *
273 * #### Example
274 * ```typescript
275 * import { ArrayExt } from '@lumino/algorithm';
276 *
277 * function isEven(value: number): boolean {
278 * return value % 2 === 0;
279 * }
280 *
281 * let data = [1, 2, 3, 4, 3, 2, 1];
282 * ArrayExt.findLastIndex(data, isEven); // 5
283 * ArrayExt.findLastIndex(data, isEven, 4); // 3
284 * ArrayExt.findLastIndex(data, isEven, 0); // -1
285 * ArrayExt.findLastIndex(data, isEven, 0, 1); // 5
286 * ```
287 */
288 function findLastIndex(array, fn, start, stop) {
289 if (start === void 0) { start = -1; }
290 if (stop === void 0) { stop = 0; }
291 var n = array.length;
292 if (n === 0) {
293 return -1;
294 }
295 if (start < 0) {
296 start = Math.max(0, start + n);
297 }
298 else {
299 start = Math.min(start, n - 1);
300 }
301 if (stop < 0) {
302 stop = Math.max(0, stop + n);
303 }
304 else {
305 stop = Math.min(stop, n - 1);
306 }
307 var d;
308 if (start < stop) {
309 d = start + 1 + (n - stop);
310 }
311 else {
312 d = start - stop + 1;
313 }
314 for (var i = 0; i < d; ++i) {
315 var j = (start - i + n) % n;
316 if (fn(array[j], j)) {
317 return j;
318 }
319 }
320 return -1;
321 }
322 ArrayExt.findLastIndex = findLastIndex;
323 /**
324 * Find the first value which matches a predicate.
325 *
326 * @param array - The array-like object to search.
327 *
328 * @param fn - The predicate function to apply to the values.
329 *
330 * @param start - The index of the first element in the range to be
331 * searched, inclusive. The default value is `0`. Negative values
332 * are taken as an offset from the end of the array.
333 *
334 * @param stop - The index of the last element in the range to be
335 * searched, inclusive. The default value is `-1`. Negative values
336 * are taken as an offset from the end of the array.
337 *
338 * @returns The first matching value, or `undefined` if no matching
339 * value is found.
340 *
341 * #### Notes
342 * If `stop < start` the search will wrap at the end of the array.
343 *
344 * #### Complexity
345 * Linear.
346 *
347 * #### Undefined Behavior
348 * A `start` or `stop` which is non-integral.
349 *
350 * Modifying the length of the array while searching.
351 *
352 * #### Example
353 * ```typescript
354 * import { ArrayExt } from '@lumino/algorithm';
355 *
356 * function isEven(value: number): boolean {
357 * return value % 2 === 0;
358 * }
359 *
360 * let data = [1, 2, 3, 4, 3, 2, 1];
361 * ArrayExt.findFirstValue(data, isEven); // 2
362 * ArrayExt.findFirstValue(data, isEven, 2); // 4
363 * ArrayExt.findFirstValue(data, isEven, 6); // undefined
364 * ArrayExt.findFirstValue(data, isEven, 6, 5); // 2
365 * ```
366 */
367 function findFirstValue(array, fn, start, stop) {
368 if (start === void 0) { start = 0; }
369 if (stop === void 0) { stop = -1; }
370 var index = findFirstIndex(array, fn, start, stop);
371 return index !== -1 ? array[index] : undefined;
372 }
373 ArrayExt.findFirstValue = findFirstValue;
374 /**
375 * Find the last value which matches a predicate.
376 *
377 * @param object - The array-like object to search.
378 *
379 * @param fn - The predicate function to apply to the values.
380 *
381 * @param start - The index of the first element in the range to be
382 * searched, inclusive. The default value is `-1`. Negative values
383 * are taken as an offset from the end of the array.
384 *
385 * @param stop - The index of the last element in the range to be
386 * searched, inclusive. The default value is `0`. Negative values
387 * are taken as an offset from the end of the array.
388 *
389 * @returns The last matching value, or `undefined` if no matching
390 * value is found.
391 *
392 * #### Notes
393 * If `start < stop` the search will wrap at the front of the array.
394 *
395 * #### Complexity
396 * Linear.
397 *
398 * #### Undefined Behavior
399 * A `start` or `stop` which is non-integral.
400 *
401 * Modifying the length of the array while searching.
402 *
403 * #### Example
404 * ```typescript
405 * import { ArrayExt } from '@lumino/algorithm';
406 *
407 * function isEven(value: number): boolean {
408 * return value % 2 === 0;
409 * }
410 *
411 * let data = [1, 2, 3, 4, 3, 2, 1];
412 * ArrayExt.findLastValue(data, isEven); // 2
413 * ArrayExt.findLastValue(data, isEven, 4); // 4
414 * ArrayExt.findLastValue(data, isEven, 0); // undefined
415 * ArrayExt.findLastValue(data, isEven, 0, 1); // 2
416 * ```
417 */
418 function findLastValue(array, fn, start, stop) {
419 if (start === void 0) { start = -1; }
420 if (stop === void 0) { stop = 0; }
421 var index = findLastIndex(array, fn, start, stop);
422 return index !== -1 ? array[index] : undefined;
423 }
424 ArrayExt.findLastValue = findLastValue;
425 /**
426 * Find the index of the first element which compares `>=` to a value.
427 *
428 * @param array - The sorted array-like object to search.
429 *
430 * @param value - The value to locate in the array.
431 *
432 * @param fn - The 3-way comparison function to apply to the values.
433 * It should return `< 0` if an element is less than a value, `0` if
434 * an element is equal to a value, or `> 0` if an element is greater
435 * than a value.
436 *
437 * @param start - The index of the first element in the range to be
438 * searched, inclusive. The default value is `0`. Negative values
439 * are taken as an offset from the end of the array.
440 *
441 * @param stop - The index of the last element in the range to be
442 * searched, inclusive. The default value is `-1`. Negative values
443 * are taken as an offset from the end of the array.
444 *
445 * @returns The index of the first element which compares `>=` to the
446 * value, or `length` if there is no such element. If the computed
447 * index for `stop` is less than `start`, then the computed index
448 * for `start` is returned.
449 *
450 * #### Notes
451 * The array must already be sorted in ascending order according to
452 * the comparison function.
453 *
454 * #### Complexity
455 * Logarithmic.
456 *
457 * #### Undefined Behavior
458 * Searching a range which is not sorted in ascending order.
459 *
460 * A `start` or `stop` which is non-integral.
461 *
462 * Modifying the length of the array while searching.
463 *
464 * #### Example
465 * ```typescript
466 * import { ArrayExt } from '@lumino/algorithm';
467 *
468 * function numberCmp(a: number, b: number): number {
469 * return a - b;
470 * }
471 *
472 * let data = [0, 3, 4, 7, 7, 9];
473 * ArrayExt.lowerBound(data, 0, numberCmp); // 0
474 * ArrayExt.lowerBound(data, 6, numberCmp); // 3
475 * ArrayExt.lowerBound(data, 7, numberCmp); // 3
476 * ArrayExt.lowerBound(data, -1, numberCmp); // 0
477 * ArrayExt.lowerBound(data, 10, numberCmp); // 6
478 * ```
479 */
480 function lowerBound(array, value, fn, start, stop) {
481 if (start === void 0) { start = 0; }
482 if (stop === void 0) { stop = -1; }
483 var n = array.length;
484 if (n === 0) {
485 return 0;
486 }
487 if (start < 0) {
488 start = Math.max(0, start + n);
489 }
490 else {
491 start = Math.min(start, n - 1);
492 }
493 if (stop < 0) {
494 stop = Math.max(0, stop + n);
495 }
496 else {
497 stop = Math.min(stop, n - 1);
498 }
499 var begin = start;
500 var span = stop - start + 1;
501 while (span > 0) {
502 var half = span >> 1;
503 var middle = begin + half;
504 if (fn(array[middle], value) < 0) {
505 begin = middle + 1;
506 span -= half + 1;
507 }
508 else {
509 span = half;
510 }
511 }
512 return begin;
513 }
514 ArrayExt.lowerBound = lowerBound;
515 /**
516 * Find the index of the first element which compares `>` than a value.
517 *
518 * @param array - The sorted array-like object to search.
519 *
520 * @param value - The value to locate in the array.
521 *
522 * @param fn - The 3-way comparison function to apply to the values.
523 * It should return `< 0` if an element is less than a value, `0` if
524 * an element is equal to a value, or `> 0` if an element is greater
525 * than a value.
526 *
527 * @param start - The index of the first element in the range to be
528 * searched, inclusive. The default value is `0`. Negative values
529 * are taken as an offset from the end of the array.
530 *
531 * @param stop - The index of the last element in the range to be
532 * searched, inclusive. The default value is `-1`. Negative values
533 * are taken as an offset from the end of the array.
534 *
535 * @returns The index of the first element which compares `>` than the
536 * value, or `length` if there is no such element. If the computed
537 * index for `stop` is less than `start`, then the computed index
538 * for `start` is returned.
539 *
540 * #### Notes
541 * The array must already be sorted in ascending order according to
542 * the comparison function.
543 *
544 * #### Complexity
545 * Logarithmic.
546 *
547 * #### Undefined Behavior
548 * Searching a range which is not sorted in ascending order.
549 *
550 * A `start` or `stop` which is non-integral.
551 *
552 * Modifying the length of the array while searching.
553 *
554 * #### Example
555 * ```typescript
556 * import { ArrayExt } from '@lumino/algorithm';
557 *
558 * function numberCmp(a: number, b: number): number {
559 * return a - b;
560 * }
561 *
562 * let data = [0, 3, 4, 7, 7, 9];
563 * ArrayExt.upperBound(data, 0, numberCmp); // 1
564 * ArrayExt.upperBound(data, 6, numberCmp); // 3
565 * ArrayExt.upperBound(data, 7, numberCmp); // 5
566 * ArrayExt.upperBound(data, -1, numberCmp); // 0
567 * ArrayExt.upperBound(data, 10, numberCmp); // 6
568 * ```
569 */
570 function upperBound(array, value, fn, start, stop) {
571 if (start === void 0) { start = 0; }
572 if (stop === void 0) { stop = -1; }
573 var n = array.length;
574 if (n === 0) {
575 return 0;
576 }
577 if (start < 0) {
578 start = Math.max(0, start + n);
579 }
580 else {
581 start = Math.min(start, n - 1);
582 }
583 if (stop < 0) {
584 stop = Math.max(0, stop + n);
585 }
586 else {
587 stop = Math.min(stop, n - 1);
588 }
589 var begin = start;
590 var span = stop - start + 1;
591 while (span > 0) {
592 var half = span >> 1;
593 var middle = begin + half;
594 if (fn(array[middle], value) > 0) {
595 span = half;
596 }
597 else {
598 begin = middle + 1;
599 span -= half + 1;
600 }
601 }
602 return begin;
603 }
604 ArrayExt.upperBound = upperBound;
605 /**
606 * Test whether two arrays are shallowly equal.
607 *
608 * @param a - The first array-like object to compare.
609 *
610 * @param b - The second array-like object to compare.
611 *
612 * @param fn - The comparison function to apply to the elements. It
613 * should return `true` if the elements are "equal". The default
614 * compares elements using strict `===` equality.
615 *
616 * @returns Whether the two arrays are shallowly equal.
617 *
618 * #### Complexity
619 * Linear.
620 *
621 * #### Undefined Behavior
622 * Modifying the length of the arrays while comparing.
623 *
624 * #### Example
625 * ```typescript
626 * import { ArrayExt } from '@lumino/algorithm';
627 *
628 * let d1 = [0, 3, 4, 7, 7, 9];
629 * let d2 = [0, 3, 4, 7, 7, 9];
630 * let d3 = [42];
631 * ArrayExt.shallowEqual(d1, d2); // true
632 * ArrayExt.shallowEqual(d2, d3); // false
633 * ```
634 */
635 function shallowEqual(a, b, fn) {
636 // Check for object identity first.
637 if (a === b) {
638 return true;
639 }
640 // Bail early if the lengths are different.
641 if (a.length !== b.length) {
642 return false;
643 }
644 // Compare each element for equality.
645 for (var i = 0, n = a.length; i < n; ++i) {
646 if (fn ? !fn(a[i], b[i]) : a[i] !== b[i]) {
647 return false;
648 }
649 }
650 // The array are shallowly equal.
651 return true;
652 }
653 ArrayExt.shallowEqual = shallowEqual;
654 /**
655 * Create a slice of an array subject to an optional step.
656 *
657 * @param array - The array-like object of interest.
658 *
659 * @param options - The options for configuring the slice.
660 *
661 * @returns A new array with the specified values.
662 *
663 * @throws An exception if the slice `step` is `0`.
664 *
665 * #### Complexity
666 * Linear.
667 *
668 * #### Undefined Behavior
669 * A `start`, `stop`, or `step` which is non-integral.
670 *
671 * #### Example
672 * ```typescript
673 * import { ArrayExt } from '@lumino/algorithm';
674 *
675 * let data = [0, 3, 4, 7, 7, 9];
676 * ArrayExt.slice(data); // [0, 3, 4, 7, 7, 9]
677 * ArrayExt.slice(data, { start: 2 }); // [4, 7, 7, 9]
678 * ArrayExt.slice(data, { start: 0, stop: 4 }); // [0, 3, 4, 7]
679 * ArrayExt.slice(data, { step: 2 }); // [0, 4, 7]
680 * ArrayExt.slice(data, { step: -1 }); // [9, 7, 7, 4, 3, 0]
681 * ```
682 */
683 function slice(array, options) {
684 if (options === void 0) { options = {}; }
685 // Extract the options.
686 var start = options.start, stop = options.stop, step = options.step;
687 // Set up the `step` value.
688 if (step === undefined) {
689 step = 1;
690 }
691 // Validate the step size.
692 if (step === 0) {
693 throw new Error('Slice `step` cannot be zero.');
694 }
695 // Look up the length of the array.
696 var n = array.length;
697 // Set up the `start` value.
698 if (start === undefined) {
699 start = step < 0 ? n - 1 : 0;
700 }
701 else if (start < 0) {
702 start = Math.max(start + n, step < 0 ? -1 : 0);
703 }
704 else if (start >= n) {
705 start = step < 0 ? n - 1 : n;
706 }
707 // Set up the `stop` value.
708 if (stop === undefined) {
709 stop = step < 0 ? -1 : n;
710 }
711 else if (stop < 0) {
712 stop = Math.max(stop + n, step < 0 ? -1 : 0);
713 }
714 else if (stop >= n) {
715 stop = step < 0 ? n - 1 : n;
716 }
717 // Compute the slice length.
718 var length;
719 if ((step < 0 && stop >= start) || (step > 0 && start >= stop)) {
720 length = 0;
721 }
722 else if (step < 0) {
723 length = Math.floor((stop - start + 1) / step + 1);
724 }
725 else {
726 length = Math.floor((stop - start - 1) / step + 1);
727 }
728 // Compute the sliced result.
729 var result = [];
730 for (var i = 0; i < length; ++i) {
731 result[i] = array[start + i * step];
732 }
733 // Return the result.
734 return result;
735 }
736 ArrayExt.slice = slice;
737 /**
738 * Move an element in an array from one index to another.
739 *
740 * @param array - The mutable array-like object of interest.
741 *
742 * @param fromIndex - The index of the element to move. Negative
743 * values are taken as an offset from the end of the array.
744 *
745 * @param toIndex - The target index of the element. Negative
746 * values are taken as an offset from the end of the array.
747 *
748 * #### Complexity
749 * Linear.
750 *
751 * #### Undefined Behavior
752 * A `fromIndex` or `toIndex` which is non-integral.
753 *
754 * #### Example
755 * ```typescript
756 * import { ArrayExt } from from '@lumino/algorithm';
757 *
758 * let data = [0, 1, 2, 3, 4];
759 * ArrayExt.move(data, 1, 2); // [0, 2, 1, 3, 4]
760 * ArrayExt.move(data, 4, 2); // [0, 2, 4, 1, 3]
761 * ```
762 */
763 function move(array, fromIndex, toIndex) {
764 var n = array.length;
765 if (n <= 1) {
766 return;
767 }
768 if (fromIndex < 0) {
769 fromIndex = Math.max(0, fromIndex + n);
770 }
771 else {
772 fromIndex = Math.min(fromIndex, n - 1);
773 }
774 if (toIndex < 0) {
775 toIndex = Math.max(0, toIndex + n);
776 }
777 else {
778 toIndex = Math.min(toIndex, n - 1);
779 }
780 if (fromIndex === toIndex) {
781 return;
782 }
783 var value = array[fromIndex];
784 var d = fromIndex < toIndex ? 1 : -1;
785 for (var i = fromIndex; i !== toIndex; i += d) {
786 array[i] = array[i + d];
787 }
788 array[toIndex] = value;
789 }
790 ArrayExt.move = move;
791 /**
792 * Reverse an array in-place.
793 *
794 * @param array - The mutable array-like object of interest.
795 *
796 * @param start - The index of the first element in the range to be
797 * reversed, inclusive. The default value is `0`. Negative values
798 * are taken as an offset from the end of the array.
799 *
800 * @param stop - The index of the last element in the range to be
801 * reversed, inclusive. The default value is `-1`. Negative values
802 * are taken as an offset from the end of the array.
803 *
804 * #### Complexity
805 * Linear.
806 *
807 * #### Undefined Behavior
808 * A `start` or `stop` index which is non-integral.
809 *
810 * #### Example
811 * ```typescript
812 * import { ArrayExt } from '@lumino/algorithm';
813 *
814 * let data = [0, 1, 2, 3, 4];
815 * ArrayExt.reverse(data, 1, 3); // [0, 3, 2, 1, 4]
816 * ArrayExt.reverse(data, 3); // [0, 3, 2, 4, 1]
817 * ArrayExt.reverse(data); // [1, 4, 2, 3, 0]
818 * ```
819 */
820 function reverse(array, start, stop) {
821 if (start === void 0) { start = 0; }
822 if (stop === void 0) { stop = -1; }
823 var n = array.length;
824 if (n <= 1) {
825 return;
826 }
827 if (start < 0) {
828 start = Math.max(0, start + n);
829 }
830 else {
831 start = Math.min(start, n - 1);
832 }
833 if (stop < 0) {
834 stop = Math.max(0, stop + n);
835 }
836 else {
837 stop = Math.min(stop, n - 1);
838 }
839 while (start < stop) {
840 var a = array[start];
841 var b = array[stop];
842 array[start++] = b;
843 array[stop--] = a;
844 }
845 }
846 ArrayExt.reverse = reverse;
847 /**
848 * Rotate the elements of an array in-place.
849 *
850 * @param array - The mutable array-like object of interest.
851 *
852 * @param delta - The amount of rotation to apply to the elements. A
853 * positive value will rotate the elements to the left. A negative
854 * value will rotate the elements to the right.
855 *
856 * @param start - The index of the first element in the range to be
857 * rotated, inclusive. The default value is `0`. Negative values
858 * are taken as an offset from the end of the array.
859 *
860 * @param stop - The index of the last element in the range to be
861 * rotated, inclusive. The default value is `-1`. Negative values
862 * are taken as an offset from the end of the array.
863 *
864 * #### Complexity
865 * Linear.
866 *
867 * #### Undefined Behavior
868 * A `delta`, `start`, or `stop` which is non-integral.
869 *
870 * #### Example
871 * ```typescript
872 * import { ArrayExt } from '@lumino/algorithm';
873 *
874 * let data = [0, 1, 2, 3, 4];
875 * ArrayExt.rotate(data, 2); // [2, 3, 4, 0, 1]
876 * ArrayExt.rotate(data, -2); // [0, 1, 2, 3, 4]
877 * ArrayExt.rotate(data, 10); // [0, 1, 2, 3, 4]
878 * ArrayExt.rotate(data, 9); // [4, 0, 1, 2, 3]
879 * ArrayExt.rotate(data, 2, 1, 3); // [4, 2, 0, 1, 3]
880 * ```
881 */
882 function rotate(array, delta, start, stop) {
883 if (start === void 0) { start = 0; }
884 if (stop === void 0) { stop = -1; }
885 var n = array.length;
886 if (n <= 1) {
887 return;
888 }
889 if (start < 0) {
890 start = Math.max(0, start + n);
891 }
892 else {
893 start = Math.min(start, n - 1);
894 }
895 if (stop < 0) {
896 stop = Math.max(0, stop + n);
897 }
898 else {
899 stop = Math.min(stop, n - 1);
900 }
901 if (start >= stop) {
902 return;
903 }
904 var length = stop - start + 1;
905 if (delta > 0) {
906 delta = delta % length;
907 }
908 else if (delta < 0) {
909 delta = ((delta % length) + length) % length;
910 }
911 if (delta === 0) {
912 return;
913 }
914 var pivot = start + delta;
915 reverse(array, start, pivot - 1);
916 reverse(array, pivot, stop);
917 reverse(array, start, stop);
918 }
919 ArrayExt.rotate = rotate;
920 /**
921 * Fill an array with a static value.
922 *
923 * @param array - The mutable array-like object to fill.
924 *
925 * @param value - The static value to use to fill the array.
926 *
927 * @param start - The index of the first element in the range to be
928 * filled, inclusive. The default value is `0`. Negative values
929 * are taken as an offset from the end of the array.
930 *
931 * @param stop - The index of the last element in the range to be
932 * filled, inclusive. The default value is `-1`. Negative values
933 * are taken as an offset from the end of the array.
934 *
935 * #### Notes
936 * If `stop < start` the fill will wrap at the end of the array.
937 *
938 * #### Complexity
939 * Linear.
940 *
941 * #### Undefined Behavior
942 * A `start` or `stop` which is non-integral.
943 *
944 * #### Example
945 * ```typescript
946 * import { ArrayExt } from '@lumino/algorithm';
947 *
948 * let data = ['one', 'two', 'three', 'four'];
949 * ArrayExt.fill(data, 'r'); // ['r', 'r', 'r', 'r']
950 * ArrayExt.fill(data, 'g', 1); // ['r', 'g', 'g', 'g']
951 * ArrayExt.fill(data, 'b', 2, 3); // ['r', 'g', 'b', 'b']
952 * ArrayExt.fill(data, 'z', 3, 1); // ['z', 'z', 'b', 'z']
953 * ```
954 */
955 function fill(array, value, start, stop) {
956 if (start === void 0) { start = 0; }
957 if (stop === void 0) { stop = -1; }
958 var n = array.length;
959 if (n === 0) {
960 return;
961 }
962 if (start < 0) {
963 start = Math.max(0, start + n);
964 }
965 else {
966 start = Math.min(start, n - 1);
967 }
968 if (stop < 0) {
969 stop = Math.max(0, stop + n);
970 }
971 else {
972 stop = Math.min(stop, n - 1);
973 }
974 var span;
975 if (stop < start) {
976 span = stop + 1 + (n - start);
977 }
978 else {
979 span = stop - start + 1;
980 }
981 for (var i = 0; i < span; ++i) {
982 array[(start + i) % n] = value;
983 }
984 }
985 ArrayExt.fill = fill;
986 /**
987 * Insert a value into an array at a specific index.
988 *
989 * @param array - The array of interest.
990 *
991 * @param index - The index at which to insert the value. Negative
992 * values are taken as an offset from the end of the array.
993 *
994 * @param value - The value to set at the specified index.
995 *
996 * #### Complexity
997 * Linear.
998 *
999 * #### Undefined Behavior
1000 * An `index` which is non-integral.
1001 *
1002 * #### Example
1003 * ```typescript
1004 * import { ArrayExt } from '@lumino/algorithm';
1005 *
1006 * let data = [0, 1, 2];
1007 * ArrayExt.insert(data, 0, -1); // [-1, 0, 1, 2]
1008 * ArrayExt.insert(data, 2, 12); // [-1, 0, 12, 1, 2]
1009 * ArrayExt.insert(data, -1, 7); // [-1, 0, 12, 1, 7, 2]
1010 * ArrayExt.insert(data, 6, 19); // [-1, 0, 12, 1, 7, 2, 19]
1011 * ```
1012 */
1013 function insert(array, index, value) {
1014 var n = array.length;
1015 if (index < 0) {
1016 index = Math.max(0, index + n);
1017 }
1018 else {
1019 index = Math.min(index, n);
1020 }
1021 for (var i = n; i > index; --i) {
1022 array[i] = array[i - 1];
1023 }
1024 array[index] = value;
1025 }
1026 ArrayExt.insert = insert;
1027 /**
1028 * Remove and return a value at a specific index in an array.
1029 *
1030 * @param array - The array of interest.
1031 *
1032 * @param index - The index of the value to remove. Negative values
1033 * are taken as an offset from the end of the array.
1034 *
1035 * @returns The value at the specified index, or `undefined` if the
1036 * index is out of range.
1037 *
1038 * #### Complexity
1039 * Linear.
1040 *
1041 * #### Undefined Behavior
1042 * An `index` which is non-integral.
1043 *
1044 * #### Example
1045 * ```typescript
1046 * import { ArrayExt } from '@lumino/algorithm';
1047 *
1048 * let data = [0, 12, 23, 39, 14, 12, 75];
1049 * ArrayExt.removeAt(data, 2); // 23
1050 * ArrayExt.removeAt(data, -2); // 12
1051 * ArrayExt.removeAt(data, 10); // undefined;
1052 * ```
1053 */
1054 function removeAt(array, index) {
1055 var n = array.length;
1056 if (index < 0) {
1057 index += n;
1058 }
1059 if (index < 0 || index >= n) {
1060 return undefined;
1061 }
1062 var value = array[index];
1063 for (var i = index + 1; i < n; ++i) {
1064 array[i - 1] = array[i];
1065 }
1066 array.length = n - 1;
1067 return value;
1068 }
1069 ArrayExt.removeAt = removeAt;
1070 /**
1071 * Remove the first occurrence of a value from an array.
1072 *
1073 * @param array - The array of interest.
1074 *
1075 * @param value - The value to remove from the array. Values are
1076 * compared using strict `===` equality.
1077 *
1078 * @param start - The index of the first element in the range to be
1079 * searched, inclusive. The default value is `0`. Negative values
1080 * are taken as an offset from the end of the array.
1081 *
1082 * @param stop - The index of the last element in the range to be
1083 * searched, inclusive. The default value is `-1`. Negative values
1084 * are taken as an offset from the end of the array.
1085 *
1086 * @returns The index of the removed value, or `-1` if the value
1087 * is not contained in the array.
1088 *
1089 * #### Notes
1090 * If `stop < start` the search will wrap at the end of the array.
1091 *
1092 * #### Complexity
1093 * Linear.
1094 *
1095 * #### Example
1096 * ```typescript
1097 * import { ArrayExt } from '@lumino/algorithm';
1098 *
1099 * let data = [0, 12, 23, 39, 14, 12, 75];
1100 * ArrayExt.removeFirstOf(data, 12); // 1
1101 * ArrayExt.removeFirstOf(data, 17); // -1
1102 * ArrayExt.removeFirstOf(data, 39, 3); // -1
1103 * ArrayExt.removeFirstOf(data, 39, 3, 2); // 2
1104 * ```
1105 */
1106 function removeFirstOf(array, value, start, stop) {
1107 if (start === void 0) { start = 0; }
1108 if (stop === void 0) { stop = -1; }
1109 var index = firstIndexOf(array, value, start, stop);
1110 if (index !== -1) {
1111 removeAt(array, index);
1112 }
1113 return index;
1114 }
1115 ArrayExt.removeFirstOf = removeFirstOf;
1116 /**
1117 * Remove the last occurrence of a value from an array.
1118 *
1119 * @param array - The array of interest.
1120 *
1121 * @param value - The value to remove from the array. Values are
1122 * compared using strict `===` equality.
1123 *
1124 * @param start - The index of the first element in the range to be
1125 * searched, inclusive. The default value is `-1`. Negative values
1126 * are taken as an offset from the end of the array.
1127 *
1128 * @param stop - The index of the last element in the range to be
1129 * searched, inclusive. The default value is `0`. Negative values
1130 * are taken as an offset from the end of the array.
1131 *
1132 * @returns The index of the removed value, or `-1` if the value
1133 * is not contained in the array.
1134 *
1135 * #### Notes
1136 * If `start < stop` the search will wrap at the end of the array.
1137 *
1138 * #### Complexity
1139 * Linear.
1140 *
1141 * #### Example
1142 * ```typescript
1143 * import { ArrayExt } from '@lumino/algorithm';
1144 *
1145 * let data = [0, 12, 23, 39, 14, 12, 75];
1146 * ArrayExt.removeLastOf(data, 12); // 5
1147 * ArrayExt.removeLastOf(data, 17); // -1
1148 * ArrayExt.removeLastOf(data, 39, 2); // -1
1149 * ArrayExt.removeLastOf(data, 39, 2, 3); // 3
1150 * ```
1151 */
1152 function removeLastOf(array, value, start, stop) {
1153 if (start === void 0) { start = -1; }
1154 if (stop === void 0) { stop = 0; }
1155 var index = lastIndexOf(array, value, start, stop);
1156 if (index !== -1) {
1157 removeAt(array, index);
1158 }
1159 return index;
1160 }
1161 ArrayExt.removeLastOf = removeLastOf;
1162 /**
1163 * Remove all occurrences of a value from an array.
1164 *
1165 * @param array - The array of interest.
1166 *
1167 * @param value - The value to remove from the array. Values are
1168 * compared using strict `===` equality.
1169 *
1170 * @param start - The index of the first element in the range to be
1171 * searched, inclusive. The default value is `0`. Negative values
1172 * are taken as an offset from the end of the array.
1173 *
1174 * @param stop - The index of the last element in the range to be
1175 * searched, inclusive. The default value is `-1`. Negative values
1176 * are taken as an offset from the end of the array.
1177 *
1178 * @returns The number of elements removed from the array.
1179 *
1180 * #### Notes
1181 * If `stop < start` the search will conceptually wrap at the end of
1182 * the array, however the array will be traversed front-to-back.
1183 *
1184 * #### Complexity
1185 * Linear.
1186 *
1187 * #### Example
1188 * ```typescript
1189 * import { ArrayExt } from '@lumino/algorithm';
1190 *
1191 * let data = [14, 12, 23, 39, 14, 12, 19, 14];
1192 * ArrayExt.removeAllOf(data, 12); // 2
1193 * ArrayExt.removeAllOf(data, 17); // 0
1194 * ArrayExt.removeAllOf(data, 14, 1, 4); // 1
1195 * ```
1196 */
1197 function removeAllOf(array, value, start, stop) {
1198 if (start === void 0) { start = 0; }
1199 if (stop === void 0) { stop = -1; }
1200 var n = array.length;
1201 if (n === 0) {
1202 return 0;
1203 }
1204 if (start < 0) {
1205 start = Math.max(0, start + n);
1206 }
1207 else {
1208 start = Math.min(start, n - 1);
1209 }
1210 if (stop < 0) {
1211 stop = Math.max(0, stop + n);
1212 }
1213 else {
1214 stop = Math.min(stop, n - 1);
1215 }
1216 var count = 0;
1217 for (var i = 0; i < n; ++i) {
1218 if (start <= stop && i >= start && i <= stop && array[i] === value) {
1219 count++;
1220 }
1221 else if (stop < start &&
1222 (i <= stop || i >= start) &&
1223 array[i] === value) {
1224 count++;
1225 }
1226 else if (count > 0) {
1227 array[i - count] = array[i];
1228 }
1229 }
1230 if (count > 0) {
1231 array.length = n - count;
1232 }
1233 return count;
1234 }
1235 ArrayExt.removeAllOf = removeAllOf;
1236 /**
1237 * Remove the first occurrence of a value which matches a predicate.
1238 *
1239 * @param array - The array of interest.
1240 *
1241 * @param fn - The predicate function to apply to the values.
1242 *
1243 * @param start - The index of the first element in the range to be
1244 * searched, inclusive. The default value is `0`. Negative values
1245 * are taken as an offset from the end of the array.
1246 *
1247 * @param stop - The index of the last element in the range to be
1248 * searched, inclusive. The default value is `-1`. Negative values
1249 * are taken as an offset from the end of the array.
1250 *
1251 * @returns The removed `{ index, value }`, which will be `-1` and
1252 * `undefined` if the value is not contained in the array.
1253 *
1254 * #### Notes
1255 * If `stop < start` the search will wrap at the end of the array.
1256 *
1257 * #### Complexity
1258 * Linear.
1259 *
1260 * #### Example
1261 * ```typescript
1262 * import { ArrayExt } from '@lumino/algorithm';
1263 *
1264 * function isEven(value: number): boolean {
1265 * return value % 2 === 0;
1266 * }
1267 *
1268 * let data = [0, 12, 23, 39, 14, 12, 75];
1269 * ArrayExt.removeFirstWhere(data, isEven); // { index: 0, value: 0 }
1270 * ArrayExt.removeFirstWhere(data, isEven, 2); // { index: 3, value: 14 }
1271 * ArrayExt.removeFirstWhere(data, isEven, 4); // { index: -1, value: undefined }
1272 * ```
1273 */
1274 function removeFirstWhere(array, fn, start, stop) {
1275 if (start === void 0) { start = 0; }
1276 if (stop === void 0) { stop = -1; }
1277 var value;
1278 var index = findFirstIndex(array, fn, start, stop);
1279 if (index !== -1) {
1280 value = removeAt(array, index);
1281 }
1282 return { index: index, value: value };
1283 }
1284 ArrayExt.removeFirstWhere = removeFirstWhere;
1285 /**
1286 * Remove the last occurrence of a value which matches a predicate.
1287 *
1288 * @param array - The array of interest.
1289 *
1290 * @param fn - The predicate function to apply to the values.
1291 *
1292 * @param start - The index of the first element in the range to be
1293 * searched, inclusive. The default value is `-1`. Negative values
1294 * are taken as an offset from the end of the array.
1295 *
1296 * @param stop - The index of the last element in the range to be
1297 * searched, inclusive. The default value is `0`. Negative values
1298 * are taken as an offset from the end of the array.
1299 *
1300 * @returns The removed `{ index, value }`, which will be `-1` and
1301 * `undefined` if the value is not contained in the array.
1302 *
1303 * #### Notes
1304 * If `start < stop` the search will wrap at the end of the array.
1305 *
1306 * #### Complexity
1307 * Linear.
1308 *
1309 * #### Example
1310 * ```typescript
1311 * import { ArrayExt } from '@lumino/algorithm';
1312 *
1313 * function isEven(value: number): boolean {
1314 * return value % 2 === 0;
1315 * }
1316 *
1317 * let data = [0, 12, 23, 39, 14, 12, 75];
1318 * ArrayExt.removeLastWhere(data, isEven); // { index: 5, value: 12 }
1319 * ArrayExt.removeLastWhere(data, isEven, 2); // { index: 1, value: 12 }
1320 * ArrayExt.removeLastWhere(data, isEven, 2, 1); // { index: -1, value: undefined }
1321 * ```
1322 */
1323 function removeLastWhere(array, fn, start, stop) {
1324 if (start === void 0) { start = -1; }
1325 if (stop === void 0) { stop = 0; }
1326 var value;
1327 var index = findLastIndex(array, fn, start, stop);
1328 if (index !== -1) {
1329 value = removeAt(array, index);
1330 }
1331 return { index: index, value: value };
1332 }
1333 ArrayExt.removeLastWhere = removeLastWhere;
1334 /**
1335 * Remove all occurrences of values which match a predicate.
1336 *
1337 * @param array - The array of interest.
1338 *
1339 * @param fn - The predicate function to apply to the values.
1340 *
1341 * @param start - The index of the first element in the range to be
1342 * searched, inclusive. The default value is `0`. Negative values
1343 * are taken as an offset from the end of the array.
1344 *
1345 * @param stop - The index of the last element in the range to be
1346 * searched, inclusive. The default value is `-1`. Negative values
1347 * are taken as an offset from the end of the array.
1348 *
1349 * @returns The number of elements removed from the array.
1350 *
1351 * #### Notes
1352 * If `stop < start` the search will conceptually wrap at the end of
1353 * the array, however the array will be traversed front-to-back.
1354 *
1355 * #### Complexity
1356 * Linear.
1357 *
1358 * #### Example
1359 * ```typescript
1360 * import { ArrayExt } from '@lumino/algorithm';
1361 *
1362 * function isEven(value: number): boolean {
1363 * return value % 2 === 0;
1364 * }
1365 *
1366 * function isNegative(value: number): boolean {
1367 * return value < 0;
1368 * }
1369 *
1370 * let data = [0, 12, -13, -9, 23, 39, 14, -15, 12, 75];
1371 * ArrayExt.removeAllWhere(data, isEven); // 4
1372 * ArrayExt.removeAllWhere(data, isNegative, 0, 3); // 2
1373 * ```
1374 */
1375 function removeAllWhere(array, fn, start, stop) {
1376 if (start === void 0) { start = 0; }
1377 if (stop === void 0) { stop = -1; }
1378 var n = array.length;
1379 if (n === 0) {
1380 return 0;
1381 }
1382 if (start < 0) {
1383 start = Math.max(0, start + n);
1384 }
1385 else {
1386 start = Math.min(start, n - 1);
1387 }
1388 if (stop < 0) {
1389 stop = Math.max(0, stop + n);
1390 }
1391 else {
1392 stop = Math.min(stop, n - 1);
1393 }
1394 var count = 0;
1395 for (var i = 0; i < n; ++i) {
1396 if (start <= stop && i >= start && i <= stop && fn(array[i], i)) {
1397 count++;
1398 }
1399 else if (stop < start && (i <= stop || i >= start) && fn(array[i], i)) {
1400 count++;
1401 }
1402 else if (count > 0) {
1403 array[i - count] = array[i];
1404 }
1405 }
1406 if (count > 0) {
1407 array.length = n - count;
1408 }
1409 return count;
1410 }
1411 ArrayExt.removeAllWhere = removeAllWhere;
1412})(ArrayExt || (ArrayExt = {}));
1413
1414// Copyright (c) Jupyter Development Team.
1415// Distributed under the terms of the Modified BSD License.
1416/*-----------------------------------------------------------------------------
1417| Copyright (c) 2014-2017, PhosphorJS Contributors
1418|
1419| Distributed under the terms of the BSD 3-Clause License.
1420|
1421| The full license is in the file LICENSE, distributed with this software.
1422|----------------------------------------------------------------------------*/
1423/**
1424 * Create an iterator for an iterable object.
1425 *
1426 * @param object - The iterable or array-like object of interest.
1427 *
1428 * @returns A new iterator for the given object.
1429 *
1430 * #### Notes
1431 * This function allows iteration algorithms to operate on user-defined
1432 * iterable types and builtin array-like objects in a uniform fashion.
1433 */
1434function iter(object) {
1435 var it;
1436 if (typeof object.iter === 'function') {
1437 it = object.iter();
1438 }
1439 else {
1440 it = new ArrayIterator(object);
1441 }
1442 return it;
1443}
1444/**
1445 * Create an iterator for the keys in an object.
1446 *
1447 * @param object - The object of interest.
1448 *
1449 * @returns A new iterator for the keys in the given object.
1450 *
1451 * #### Complexity
1452 * Linear.
1453 *
1454 * #### Example
1455 * ```typescript
1456 * import { each, keys } from '@lumino/algorithm';
1457 *
1458 * let data = { one: 1, two: 2, three: 3 };
1459 *
1460 * each(keys(data), key => { console.log(key); }); // 'one', 'two', 'three'
1461 * ```
1462 */
1463function iterKeys(object) {
1464 return new KeyIterator(object);
1465}
1466/**
1467 * Create an iterator for the values in an object.
1468 *
1469 * @param object - The object of interest.
1470 *
1471 * @returns A new iterator for the values in the given object.
1472 *
1473 * #### Complexity
1474 * Linear.
1475 *
1476 * #### Example
1477 * ```typescript
1478 * import { each, values } from '@lumino/algorithm';
1479 *
1480 * let data = { one: 1, two: 2, three: 3 };
1481 *
1482 * each(values(data), value => { console.log(value); }); // 1, 2, 3
1483 * ```
1484 */
1485function iterValues(object) {
1486 return new ValueIterator(object);
1487}
1488/**
1489 * Create an iterator for the items in an object.
1490 *
1491 * @param object - The object of interest.
1492 *
1493 * @returns A new iterator for the items in the given object.
1494 *
1495 * #### Complexity
1496 * Linear.
1497 *
1498 * #### Example
1499 * ```typescript
1500 * import { each, items } from '@lumino/algorithm';
1501 *
1502 * let data = { one: 1, two: 2, three: 3 };
1503 *
1504 * each(items(data), value => { console.log(value); }); // ['one', 1], ['two', 2], ['three', 3]
1505 * ```
1506 */
1507function iterItems(object) {
1508 return new ItemIterator(object);
1509}
1510/**
1511 * Create an iterator for an iterator-like function.
1512 *
1513 * @param fn - A function which behaves like an iterator `next` method.
1514 *
1515 * @returns A new iterator for the given function.
1516 *
1517 * #### Notes
1518 * The returned iterator **cannot** be cloned.
1519 *
1520 * #### Example
1521 * ```typescript
1522 * import { each, iterFn } from '@lumino/algorithm';
1523 *
1524 * let it = iterFn((() => {
1525 * let i = 0;
1526 * return () => i > 3 ? undefined : i++;
1527 * })());
1528 *
1529 * each(it, v => { console.log(v); }); // 0, 1, 2, 3
1530 * ```
1531 */
1532function iterFn(fn) {
1533 return new FnIterator(fn);
1534}
1535/**
1536 * Invoke a function for each value in an iterable.
1537 *
1538 * @param object - The iterable or array-like object of interest.
1539 *
1540 * @param fn - The callback function to invoke for each value.
1541 *
1542 * #### Notes
1543 * Iteration can be terminated early by returning `false` from the
1544 * callback function.
1545 *
1546 * #### Complexity
1547 * Linear.
1548 *
1549 * #### Example
1550 * ```typescript
1551 * import { each } from '@lumino/algorithm';
1552 *
1553 * let data = [5, 7, 0, -2, 9];
1554 *
1555 * each(data, value => { console.log(value); });
1556 * ```
1557 */
1558function each(object, fn) {
1559 var index = 0;
1560 var it = iter(object);
1561 var value;
1562 while ((value = it.next()) !== undefined) {
1563 if (fn(value, index++) === false) {
1564 return;
1565 }
1566 }
1567}
1568/**
1569 * Test whether all values in an iterable satisfy a predicate.
1570 *
1571 * @param object - The iterable or array-like object of interest.
1572 *
1573 * @param fn - The predicate function to invoke for each value.
1574 *
1575 * @returns `true` if all values pass the test, `false` otherwise.
1576 *
1577 * #### Notes
1578 * Iteration terminates on the first `false` predicate result.
1579 *
1580 * #### Complexity
1581 * Linear.
1582 *
1583 * #### Example
1584 * ```typescript
1585 * import { every } from '@lumino/algorithm';
1586 *
1587 * let data = [5, 7, 1];
1588 *
1589 * every(data, value => value % 2 === 0); // false
1590 * every(data, value => value % 2 === 1); // true
1591 * ```
1592 */
1593function every(object, fn) {
1594 var index = 0;
1595 var it = iter(object);
1596 var value;
1597 while ((value = it.next()) !== undefined) {
1598 if (!fn(value, index++)) {
1599 return false;
1600 }
1601 }
1602 return true;
1603}
1604/**
1605 * Test whether any value in an iterable satisfies a predicate.
1606 *
1607 * @param object - The iterable or array-like object of interest.
1608 *
1609 * @param fn - The predicate function to invoke for each value.
1610 *
1611 * @returns `true` if any value passes the test, `false` otherwise.
1612 *
1613 * #### Notes
1614 * Iteration terminates on the first `true` predicate result.
1615 *
1616 * #### Complexity
1617 * Linear.
1618 *
1619 * #### Example
1620 * ```typescript
1621 * import { some } from '@lumino/algorithm';
1622 *
1623 * let data = [5, 7, 1];
1624 *
1625 * some(data, value => value === 7); // true
1626 * some(data, value => value === 3); // false
1627 * ```
1628 */
1629function some(object, fn) {
1630 var index = 0;
1631 var it = iter(object);
1632 var value;
1633 while ((value = it.next()) !== undefined) {
1634 if (fn(value, index++)) {
1635 return true;
1636 }
1637 }
1638 return false;
1639}
1640/**
1641 * Create an array from an iterable of values.
1642 *
1643 * @param object - The iterable or array-like object of interest.
1644 *
1645 * @returns A new array of values from the given object.
1646 *
1647 * #### Example
1648 * ```typescript
1649 * import { iter, toArray } from '@lumino/algorithm';
1650 *
1651 * let data = [1, 2, 3, 4, 5, 6];
1652 *
1653 * let stream = iter(data);
1654 *
1655 * toArray(stream); // [1, 2, 3, 4, 5, 6];
1656 * ```
1657 */
1658function toArray(object) {
1659 var index = 0;
1660 var result = [];
1661 var it = iter(object);
1662 var value;
1663 while ((value = it.next()) !== undefined) {
1664 result[index++] = value;
1665 }
1666 return result;
1667}
1668/**
1669 * Create an object from an iterable of key/value pairs.
1670 *
1671 * @param object - The iterable or array-like object of interest.
1672 *
1673 * @returns A new object mapping keys to values.
1674 *
1675 * #### Example
1676 * ```typescript
1677 * import { toObject } from '@lumino/algorithm';
1678 *
1679 * let data = [['one', 1], ['two', 2], ['three', 3]];
1680 *
1681 * toObject(data); // { one: 1, two: 2, three: 3 }
1682 * ```
1683 */
1684function toObject(object) {
1685 var it = iter(object);
1686 var pair;
1687 var result = {};
1688 while ((pair = it.next()) !== undefined) {
1689 result[pair[0]] = pair[1];
1690 }
1691 return result;
1692}
1693/**
1694 * An iterator for an array-like object.
1695 *
1696 * #### Notes
1697 * This iterator can be used for any builtin JS array-like object.
1698 */
1699var ArrayIterator = /** @class */ (function () {
1700 /**
1701 * Construct a new array iterator.
1702 *
1703 * @param source - The array-like object of interest.
1704 */
1705 function ArrayIterator(source) {
1706 this._index = 0;
1707 this._source = source;
1708 }
1709 /**
1710 * Get an iterator over the object's values.
1711 *
1712 * @returns An iterator which yields the object's values.
1713 */
1714 ArrayIterator.prototype.iter = function () {
1715 return this;
1716 };
1717 /**
1718 * Create an independent clone of the iterator.
1719 *
1720 * @returns A new independent clone of the iterator.
1721 */
1722 ArrayIterator.prototype.clone = function () {
1723 var result = new ArrayIterator(this._source);
1724 result._index = this._index;
1725 return result;
1726 };
1727 /**
1728 * Get the next value from the iterator.
1729 *
1730 * @returns The next value from the iterator, or `undefined`.
1731 */
1732 ArrayIterator.prototype.next = function () {
1733 if (this._index >= this._source.length) {
1734 return undefined;
1735 }
1736 return this._source[this._index++];
1737 };
1738 return ArrayIterator;
1739}());
1740/**
1741 * An iterator for the keys in an object.
1742 *
1743 * #### Notes
1744 * This iterator can be used for any JS object.
1745 */
1746var KeyIterator = /** @class */ (function () {
1747 /**
1748 * Construct a new key iterator.
1749 *
1750 * @param source - The object of interest.
1751 *
1752 * @param keys - The keys to iterate, if known.
1753 */
1754 function KeyIterator(source, keys) {
1755 if (keys === void 0) { keys = Object.keys(source); }
1756 this._index = 0;
1757 this._source = source;
1758 this._keys = keys;
1759 }
1760 /**
1761 * Get an iterator over the object's values.
1762 *
1763 * @returns An iterator which yields the object's values.
1764 */
1765 KeyIterator.prototype.iter = function () {
1766 return this;
1767 };
1768 /**
1769 * Create an independent clone of the iterator.
1770 *
1771 * @returns A new independent clone of the iterator.
1772 */
1773 KeyIterator.prototype.clone = function () {
1774 var result = new KeyIterator(this._source, this._keys);
1775 result._index = this._index;
1776 return result;
1777 };
1778 /**
1779 * Get the next value from the iterator.
1780 *
1781 * @returns The next value from the iterator, or `undefined`.
1782 */
1783 KeyIterator.prototype.next = function () {
1784 if (this._index >= this._keys.length) {
1785 return undefined;
1786 }
1787 var key = this._keys[this._index++];
1788 if (key in this._source) {
1789 return key;
1790 }
1791 return this.next();
1792 };
1793 return KeyIterator;
1794}());
1795/**
1796 * An iterator for the values in an object.
1797 *
1798 * #### Notes
1799 * This iterator can be used for any JS object.
1800 */
1801var ValueIterator = /** @class */ (function () {
1802 /**
1803 * Construct a new value iterator.
1804 *
1805 * @param source - The object of interest.
1806 *
1807 * @param keys - The keys to iterate, if known.
1808 */
1809 function ValueIterator(source, keys) {
1810 if (keys === void 0) { keys = Object.keys(source); }
1811 this._index = 0;
1812 this._source = source;
1813 this._keys = keys;
1814 }
1815 /**
1816 * Get an iterator over the object's values.
1817 *
1818 * @returns An iterator which yields the object's values.
1819 */
1820 ValueIterator.prototype.iter = function () {
1821 return this;
1822 };
1823 /**
1824 * Create an independent clone of the iterator.
1825 *
1826 * @returns A new independent clone of the iterator.
1827 */
1828 ValueIterator.prototype.clone = function () {
1829 var result = new ValueIterator(this._source, this._keys);
1830 result._index = this._index;
1831 return result;
1832 };
1833 /**
1834 * Get the next value from the iterator.
1835 *
1836 * @returns The next value from the iterator, or `undefined`.
1837 */
1838 ValueIterator.prototype.next = function () {
1839 if (this._index >= this._keys.length) {
1840 return undefined;
1841 }
1842 var key = this._keys[this._index++];
1843 if (key in this._source) {
1844 return this._source[key];
1845 }
1846 return this.next();
1847 };
1848 return ValueIterator;
1849}());
1850/**
1851 * An iterator for the items in an object.
1852 *
1853 * #### Notes
1854 * This iterator can be used for any JS object.
1855 */
1856var ItemIterator = /** @class */ (function () {
1857 /**
1858 * Construct a new item iterator.
1859 *
1860 * @param source - The object of interest.
1861 *
1862 * @param keys - The keys to iterate, if known.
1863 */
1864 function ItemIterator(source, keys) {
1865 if (keys === void 0) { keys = Object.keys(source); }
1866 this._index = 0;
1867 this._source = source;
1868 this._keys = keys;
1869 }
1870 /**
1871 * Get an iterator over the object's values.
1872 *
1873 * @returns An iterator which yields the object's values.
1874 */
1875 ItemIterator.prototype.iter = function () {
1876 return this;
1877 };
1878 /**
1879 * Create an independent clone of the iterator.
1880 *
1881 * @returns A new independent clone of the iterator.
1882 */
1883 ItemIterator.prototype.clone = function () {
1884 var result = new ItemIterator(this._source, this._keys);
1885 result._index = this._index;
1886 return result;
1887 };
1888 /**
1889 * Get the next value from the iterator.
1890 *
1891 * @returns The next value from the iterator, or `undefined`.
1892 */
1893 ItemIterator.prototype.next = function () {
1894 if (this._index >= this._keys.length) {
1895 return undefined;
1896 }
1897 var key = this._keys[this._index++];
1898 if (key in this._source) {
1899 return [key, this._source[key]];
1900 }
1901 return this.next();
1902 };
1903 return ItemIterator;
1904}());
1905/**
1906 * An iterator for an iterator-like function.
1907 */
1908var FnIterator = /** @class */ (function () {
1909 /**
1910 * Construct a new function iterator.
1911 *
1912 * @param fn - The iterator-like function of interest.
1913 */
1914 function FnIterator(fn) {
1915 this._fn = fn;
1916 }
1917 /**
1918 * Get an iterator over the object's values.
1919 *
1920 * @returns An iterator which yields the object's values.
1921 */
1922 FnIterator.prototype.iter = function () {
1923 return this;
1924 };
1925 /**
1926 * Create an independent clone of the iterator.
1927 *
1928 * @returns A new independent clone of the iterator.
1929 */
1930 FnIterator.prototype.clone = function () {
1931 throw new Error('An `FnIterator` cannot be cloned.');
1932 };
1933 /**
1934 * Get the next value from the iterator.
1935 *
1936 * @returns The next value from the iterator, or `undefined`.
1937 */
1938 FnIterator.prototype.next = function () {
1939 return this._fn.call(undefined);
1940 };
1941 return FnIterator;
1942}());
1943
1944// Copyright (c) Jupyter Development Team.
1945/**
1946 * Chain together several iterables.
1947 *
1948 * @param objects - The iterable or array-like objects of interest.
1949 *
1950 * @returns An iterator which yields the values of the iterables
1951 * in the order in which they are supplied.
1952 *
1953 * #### Example
1954 * ```typescript
1955 * import { chain, toArray } from '@lumino/algorithm';
1956 *
1957 * let data1 = [1, 2, 3];
1958 * let data2 = [4, 5, 6];
1959 *
1960 * let stream = chain(data1, data2);
1961 *
1962 * toArray(stream); // [1, 2, 3, 4, 5, 6]
1963 * ```
1964 */
1965function chain() {
1966 var objects = [];
1967 for (var _i = 0; _i < arguments.length; _i++) {
1968 objects[_i] = arguments[_i];
1969 }
1970 return new ChainIterator(iter(objects.map(iter)));
1971}
1972/**
1973 * An iterator which chains together several iterators.
1974 */
1975var ChainIterator = /** @class */ (function () {
1976 /**
1977 * Construct a new chain iterator.
1978 *
1979 * @param source - The iterator of iterators of interest.
1980 */
1981 function ChainIterator(source) {
1982 this._cloned = false;
1983 this._source = source;
1984 this._active = undefined;
1985 }
1986 /**
1987 * Get an iterator over the object's values.
1988 *
1989 * @returns An iterator which yields the object's values.
1990 */
1991 ChainIterator.prototype.iter = function () {
1992 return this;
1993 };
1994 /**
1995 * Create an independent clone of the iterator.
1996 *
1997 * @returns A new independent clone of the iterator.
1998 */
1999 ChainIterator.prototype.clone = function () {
2000 var result = new ChainIterator(this._source.clone());
2001 result._active = this._active && this._active.clone();
2002 result._cloned = true;
2003 this._cloned = true;
2004 return result;
2005 };
2006 /**
2007 * Get the next value from the iterator.
2008 *
2009 * @returns The next value from the iterator, or `undefined`.
2010 */
2011 ChainIterator.prototype.next = function () {
2012 if (this._active === undefined) {
2013 var active = this._source.next();
2014 if (active === undefined) {
2015 return undefined;
2016 }
2017 this._active = this._cloned ? active.clone() : active;
2018 }
2019 var value = this._active.next();
2020 if (value !== undefined) {
2021 return value;
2022 }
2023 this._active = undefined;
2024 return this.next();
2025 };
2026 return ChainIterator;
2027}());
2028
2029/**
2030 * Create an empty iterator.
2031 *
2032 * @returns A new iterator which yields nothing.
2033 *
2034 * #### Example
2035 * ```typescript
2036 * import { empty, toArray } from '@lumino/algorithm';
2037 *
2038 * let stream = empty<number>();
2039 *
2040 * toArray(stream); // []
2041 * ```
2042 */
2043function empty() {
2044 return new EmptyIterator();
2045}
2046/**
2047 * An iterator which is always empty.
2048 */
2049var EmptyIterator = /** @class */ (function () {
2050 function EmptyIterator() {
2051 }
2052 /**
2053 * Get an iterator over the object's values.
2054 *
2055 * @returns An iterator which yields the object's values.
2056 */
2057 EmptyIterator.prototype.iter = function () {
2058 return this;
2059 };
2060 /**
2061 * Create an independent clone of the iterator.
2062 *
2063 * @returns A new independent clone of the iterator.
2064 */
2065 EmptyIterator.prototype.clone = function () {
2066 return new EmptyIterator();
2067 };
2068 /**
2069 * Get the next value from the iterator.
2070 *
2071 * @returns The next value from the iterator, or `undefined`.
2072 */
2073 EmptyIterator.prototype.next = function () {
2074 return undefined;
2075 };
2076 return EmptyIterator;
2077}());
2078
2079// Copyright (c) Jupyter Development Team.
2080/**
2081 * Enumerate an iterable object.
2082 *
2083 * @param object - The iterable or array-like object of interest.
2084 *
2085 * @param start - The starting enum value. The default is `0`.
2086 *
2087 * @returns An iterator which yields the enumerated values.
2088 *
2089 * #### Example
2090 * ```typescript
2091 * import { enumerate, toArray } from '@lumino/algorithm';
2092 *
2093 * let data = ['foo', 'bar', 'baz'];
2094 *
2095 * let stream = enumerate(data, 1);
2096 *
2097 * toArray(stream); // [[1, 'foo'], [2, 'bar'], [3, 'baz']]
2098 * ```
2099 */
2100function enumerate(object, start) {
2101 if (start === void 0) { start = 0; }
2102 return new EnumerateIterator(iter(object), start);
2103}
2104/**
2105 * An iterator which enumerates the source values.
2106 */
2107var EnumerateIterator = /** @class */ (function () {
2108 /**
2109 * Construct a new enumerate iterator.
2110 *
2111 * @param source - The iterator of values of interest.
2112 *
2113 * @param start - The starting enum value.
2114 */
2115 function EnumerateIterator(source, start) {
2116 this._source = source;
2117 this._index = start;
2118 }
2119 /**
2120 * Get an iterator over the object's values.
2121 *
2122 * @returns An iterator which yields the object's values.
2123 */
2124 EnumerateIterator.prototype.iter = function () {
2125 return this;
2126 };
2127 /**
2128 * Create an independent clone of the iterator.
2129 *
2130 * @returns A new independent clone of the iterator.
2131 */
2132 EnumerateIterator.prototype.clone = function () {
2133 return new EnumerateIterator(this._source.clone(), this._index);
2134 };
2135 /**
2136 * Get the next value from the iterator.
2137 *
2138 * @returns The next value from the iterator, or `undefined`.
2139 */
2140 EnumerateIterator.prototype.next = function () {
2141 var value = this._source.next();
2142 if (value === undefined) {
2143 return undefined;
2144 }
2145 return [this._index++, value];
2146 };
2147 return EnumerateIterator;
2148}());
2149
2150// Copyright (c) Jupyter Development Team.
2151/**
2152 * Filter an iterable for values which pass a test.
2153 *
2154 * @param object - The iterable or array-like object of interest.
2155 *
2156 * @param fn - The predicate function to invoke for each value.
2157 *
2158 * @returns An iterator which yields the values which pass the test.
2159 *
2160 * #### Example
2161 * ```typescript
2162 * import { filter, toArray } from '@lumino/algorithm';
2163 *
2164 * let data = [1, 2, 3, 4, 5, 6];
2165 *
2166 * let stream = filter(data, value => value % 2 === 0);
2167 *
2168 * toArray(stream); // [2, 4, 6]
2169 * ```
2170 */
2171function filter(object, fn) {
2172 return new FilterIterator(iter(object), fn);
2173}
2174/**
2175 * An iterator which yields values which pass a test.
2176 */
2177var FilterIterator = /** @class */ (function () {
2178 /**
2179 * Construct a new filter iterator.
2180 *
2181 * @param source - The iterator of values of interest.
2182 *
2183 * @param fn - The predicate function to invoke for each value.
2184 */
2185 function FilterIterator(source, fn) {
2186 this._index = 0;
2187 this._source = source;
2188 this._fn = fn;
2189 }
2190 /**
2191 * Get an iterator over the object's values.
2192 *
2193 * @returns An iterator which yields the object's values.
2194 */
2195 FilterIterator.prototype.iter = function () {
2196 return this;
2197 };
2198 /**
2199 * Create an independent clone of the iterator.
2200 *
2201 * @returns A new independent clone of the iterator.
2202 */
2203 FilterIterator.prototype.clone = function () {
2204 var result = new FilterIterator(this._source.clone(), this._fn);
2205 result._index = this._index;
2206 return result;
2207 };
2208 /**
2209 * Get the next value from the iterator.
2210 *
2211 * @returns The next value from the iterator, or `undefined`.
2212 */
2213 FilterIterator.prototype.next = function () {
2214 var fn = this._fn;
2215 var it = this._source;
2216 var value;
2217 while ((value = it.next()) !== undefined) {
2218 if (fn(value, this._index++)) {
2219 return value;
2220 }
2221 }
2222 return undefined;
2223 };
2224 return FilterIterator;
2225}());
2226
2227// Copyright (c) Jupyter Development Team.
2228/**
2229 * Find the first value in an iterable which matches a predicate.
2230 *
2231 * @param object - The iterable or array-like object to search.
2232 *
2233 * @param fn - The predicate function to apply to the values.
2234 *
2235 * @returns The first matching value, or `undefined` if no matching
2236 * value is found.
2237 *
2238 * #### Complexity
2239 * Linear.
2240 *
2241 * #### Example
2242 * ```typescript
2243 * import { find } from '@lumino/algorithm';
2244 *
2245 * interface IAnimal { species: string, name: string };
2246 *
2247 * function isCat(value: IAnimal): boolean {
2248 * return value.species === 'cat';
2249 * }
2250 *
2251 * let data: IAnimal[] = [
2252 * { species: 'dog', name: 'spot' },
2253 * { species: 'cat', name: 'fluffy' },
2254 * { species: 'alligator', name: 'pocho' }
2255 * ];
2256 *
2257 * find(data, isCat).name; // 'fluffy'
2258 * ```
2259 */
2260function find(object, fn) {
2261 var index = 0;
2262 var it = iter(object);
2263 var value;
2264 while ((value = it.next()) !== undefined) {
2265 if (fn(value, index++)) {
2266 return value;
2267 }
2268 }
2269 return undefined;
2270}
2271/**
2272 * Find the index of the first value which matches a predicate.
2273 *
2274 * @param object - The iterable or array-like object to search.
2275 *
2276 * @param fn - The predicate function to apply to the values.
2277 *
2278 * @returns The index of the first matching value, or `-1` if no
2279 * matching value is found.
2280 *
2281 * #### Complexity
2282 * Linear.
2283 *
2284 * #### Example
2285 * ```typescript
2286 * import { findIndex } from '@lumino/algorithm';
2287 *
2288 * interface IAnimal { species: string, name: string };
2289 *
2290 * function isCat(value: IAnimal): boolean {
2291 * return value.species === 'cat';
2292 * }
2293 *
2294 * let data: IAnimal[] = [
2295 * { species: 'dog', name: 'spot' },
2296 * { species: 'cat', name: 'fluffy' },
2297 * { species: 'alligator', name: 'pocho' }
2298 * ];
2299 *
2300 * findIndex(data, isCat); // 1
2301 * ```
2302 */
2303function findIndex(object, fn) {
2304 var index = 0;
2305 var it = iter(object);
2306 var value;
2307 while ((value = it.next()) !== undefined) {
2308 if (fn(value, index++)) {
2309 return index - 1;
2310 }
2311 }
2312 return -1;
2313}
2314/**
2315 * Find the minimum value in an iterable.
2316 *
2317 * @param object - The iterable or array-like object to search.
2318 *
2319 * @param fn - The 3-way comparison function to apply to the values.
2320 * It should return `< 0` if the first value is less than the second.
2321 * `0` if the values are equivalent, or `> 0` if the first value is
2322 * greater than the second.
2323 *
2324 * @returns The minimum value in the iterable. If multiple values are
2325 * equivalent to the minimum, the left-most value is returned. If
2326 * the iterable is empty, this returns `undefined`.
2327 *
2328 * #### Complexity
2329 * Linear.
2330 *
2331 * #### Example
2332 * ```typescript
2333 * import { min } from '@lumino/algorithm';
2334 *
2335 * function numberCmp(a: number, b: number): number {
2336 * return a - b;
2337 * }
2338 *
2339 * min([7, 4, 0, 3, 9, 4], numberCmp); // 0
2340 * ```
2341 */
2342function min(object, fn) {
2343 var it = iter(object);
2344 var value = it.next();
2345 if (value === undefined) {
2346 return undefined;
2347 }
2348 var result = value;
2349 while ((value = it.next()) !== undefined) {
2350 if (fn(value, result) < 0) {
2351 result = value;
2352 }
2353 }
2354 return result;
2355}
2356/**
2357 * Find the maximum value in an iterable.
2358 *
2359 * @param object - The iterable or array-like object to search.
2360 *
2361 * @param fn - The 3-way comparison function to apply to the values.
2362 * It should return `< 0` if the first value is less than the second.
2363 * `0` if the values are equivalent, or `> 0` if the first value is
2364 * greater than the second.
2365 *
2366 * @returns The maximum value in the iterable. If multiple values are
2367 * equivalent to the maximum, the left-most value is returned. If
2368 * the iterable is empty, this returns `undefined`.
2369 *
2370 * #### Complexity
2371 * Linear.
2372 *
2373 * #### Example
2374 * ```typescript
2375 * import { max } from '@lumino/algorithm';
2376 *
2377 * function numberCmp(a: number, b: number): number {
2378 * return a - b;
2379 * }
2380 *
2381 * max([7, 4, 0, 3, 9, 4], numberCmp); // 9
2382 * ```
2383 */
2384function max(object, fn) {
2385 var it = iter(object);
2386 var value = it.next();
2387 if (value === undefined) {
2388 return undefined;
2389 }
2390 var result = value;
2391 while ((value = it.next()) !== undefined) {
2392 if (fn(value, result) > 0) {
2393 result = value;
2394 }
2395 }
2396 return result;
2397}
2398/**
2399 * Find the minimum and maximum values in an iterable.
2400 *
2401 * @param object - The iterable or array-like object to search.
2402 *
2403 * @param fn - The 3-way comparison function to apply to the values.
2404 * It should return `< 0` if the first value is less than the second.
2405 * `0` if the values are equivalent, or `> 0` if the first value is
2406 * greater than the second.
2407 *
2408 * @returns A 2-tuple of the `[min, max]` values in the iterable. If
2409 * multiple values are equivalent, the left-most values are returned.
2410 * If the iterable is empty, this returns `undefined`.
2411 *
2412 * #### Complexity
2413 * Linear.
2414 *
2415 * #### Example
2416 * ```typescript
2417 * import { minmax } from '@lumino/algorithm';
2418 *
2419 * function numberCmp(a: number, b: number): number {
2420 * return a - b;
2421 * }
2422 *
2423 * minmax([7, 4, 0, 3, 9, 4], numberCmp); // [0, 9]
2424 * ```
2425 */
2426function minmax(object, fn) {
2427 var it = iter(object);
2428 var value = it.next();
2429 if (value === undefined) {
2430 return undefined;
2431 }
2432 var vmin = value;
2433 var vmax = value;
2434 while ((value = it.next()) !== undefined) {
2435 if (fn(value, vmin) < 0) {
2436 vmin = value;
2437 }
2438 else if (fn(value, vmax) > 0) {
2439 vmax = value;
2440 }
2441 }
2442 return [vmin, vmax];
2443}
2444
2445// Copyright (c) Jupyter Development Team.
2446/**
2447 * Transform the values of an iterable with a mapping function.
2448 *
2449 * @param object - The iterable or array-like object of interest.
2450 *
2451 * @param fn - The mapping function to invoke for each value.
2452 *
2453 * @returns An iterator which yields the transformed values.
2454 *
2455 * #### Example
2456 * ```typescript
2457 * import { map, toArray } from '@lumino/algorithm';
2458 *
2459 * let data = [1, 2, 3];
2460 *
2461 * let stream = map(data, value => value * 2);
2462 *
2463 * toArray(stream); // [2, 4, 6]
2464 * ```
2465 */
2466function map(object, fn) {
2467 return new MapIterator(iter(object), fn);
2468}
2469/**
2470 * An iterator which transforms values using a mapping function.
2471 */
2472var MapIterator = /** @class */ (function () {
2473 /**
2474 * Construct a new map iterator.
2475 *
2476 * @param source - The iterator of values of interest.
2477 *
2478 * @param fn - The mapping function to invoke for each value.
2479 */
2480 function MapIterator(source, fn) {
2481 this._index = 0;
2482 this._source = source;
2483 this._fn = fn;
2484 }
2485 /**
2486 * Get an iterator over the object's values.
2487 *
2488 * @returns An iterator which yields the object's values.
2489 */
2490 MapIterator.prototype.iter = function () {
2491 return this;
2492 };
2493 /**
2494 * Create an independent clone of the iterator.
2495 *
2496 * @returns A new independent clone of the iterator.
2497 */
2498 MapIterator.prototype.clone = function () {
2499 var result = new MapIterator(this._source.clone(), this._fn);
2500 result._index = this._index;
2501 return result;
2502 };
2503 /**
2504 * Get the next value from the iterator.
2505 *
2506 * @returns The next value from the iterator, or `undefined`.
2507 */
2508 MapIterator.prototype.next = function () {
2509 var value = this._source.next();
2510 if (value === undefined) {
2511 return undefined;
2512 }
2513 return this._fn.call(undefined, value, this._index++);
2514 };
2515 return MapIterator;
2516}());
2517
2518/**
2519 * Create an iterator of evenly spaced values.
2520 *
2521 * @param start - The starting value for the range, inclusive.
2522 *
2523 * @param stop - The stopping value for the range, exclusive.
2524 *
2525 * @param step - The distance between each value.
2526 *
2527 * @returns An iterator which produces evenly spaced values.
2528 *
2529 * #### Notes
2530 * In the single argument form of `range(stop)`, `start` defaults to
2531 * `0` and `step` defaults to `1`.
2532 *
2533 * In the two argument form of `range(start, stop)`, `step` defaults
2534 * to `1`.
2535 */
2536function range(start, stop, step) {
2537 if (stop === undefined) {
2538 return new RangeIterator(0, start, 1);
2539 }
2540 if (step === undefined) {
2541 return new RangeIterator(start, stop, 1);
2542 }
2543 return new RangeIterator(start, stop, step);
2544}
2545/**
2546 * An iterator which produces a range of evenly spaced values.
2547 */
2548var RangeIterator = /** @class */ (function () {
2549 /**
2550 * Construct a new range iterator.
2551 *
2552 * @param start - The starting value for the range, inclusive.
2553 *
2554 * @param stop - The stopping value for the range, exclusive.
2555 *
2556 * @param step - The distance between each value.
2557 */
2558 function RangeIterator(start, stop, step) {
2559 this._index = 0;
2560 this._start = start;
2561 this._stop = stop;
2562 this._step = step;
2563 this._length = Private.rangeLength(start, stop, step);
2564 }
2565 /**
2566 * Get an iterator over the object's values.
2567 *
2568 * @returns An iterator which yields the object's values.
2569 */
2570 RangeIterator.prototype.iter = function () {
2571 return this;
2572 };
2573 /**
2574 * Create an independent clone of the iterator.
2575 *
2576 * @returns A new independent clone of the iterator.
2577 */
2578 RangeIterator.prototype.clone = function () {
2579 var result = new RangeIterator(this._start, this._stop, this._step);
2580 result._index = this._index;
2581 return result;
2582 };
2583 /**
2584 * Get the next value from the iterator.
2585 *
2586 * @returns The next value from the iterator, or `undefined`.
2587 */
2588 RangeIterator.prototype.next = function () {
2589 if (this._index >= this._length) {
2590 return undefined;
2591 }
2592 return this._start + this._step * this._index++;
2593 };
2594 return RangeIterator;
2595}());
2596/**
2597 * The namespace for the module implementation details.
2598 */
2599var Private;
2600(function (Private) {
2601 /**
2602 * Compute the effective length of a range.
2603 *
2604 * @param start - The starting value for the range, inclusive.
2605 *
2606 * @param stop - The stopping value for the range, exclusive.
2607 *
2608 * @param step - The distance between each value.
2609 *
2610 * @returns The number of steps need to traverse the range.
2611 */
2612 function rangeLength(start, stop, step) {
2613 if (step === 0) {
2614 return Infinity;
2615 }
2616 if (start > stop && step > 0) {
2617 return 0;
2618 }
2619 if (start < stop && step < 0) {
2620 return 0;
2621 }
2622 return Math.ceil((stop - start) / step);
2623 }
2624 Private.rangeLength = rangeLength;
2625})(Private || (Private = {}));
2626
2627// Copyright (c) Jupyter Development Team.
2628function reduce(object, fn, initial) {
2629 // Setup the iterator and fetch the first value.
2630 var index = 0;
2631 var it = iter(object);
2632 var first = it.next();
2633 // An empty iterator and no initial value is an error.
2634 if (first === undefined && initial === undefined) {
2635 throw new TypeError('Reduce of empty iterable with no initial value.');
2636 }
2637 // If the iterator is empty, return the initial value.
2638 if (first === undefined) {
2639 return initial;
2640 }
2641 // If the iterator has a single item and no initial value, the
2642 // reducer is not invoked and the first item is the return value.
2643 var second = it.next();
2644 if (second === undefined && initial === undefined) {
2645 return first;
2646 }
2647 // If iterator has a single item and an initial value is provided,
2648 // the reducer is invoked and that result is the return value.
2649 if (second === undefined) {
2650 return fn(initial, first, index++);
2651 }
2652 // Setup the initial accumlated value.
2653 var accumulator;
2654 if (initial === undefined) {
2655 accumulator = fn(first, second, index++);
2656 }
2657 else {
2658 accumulator = fn(fn(initial, first, index++), second, index++);
2659 }
2660 // Iterate the rest of the values, updating the accumulator.
2661 var next;
2662 while ((next = it.next()) !== undefined) {
2663 accumulator = fn(accumulator, next, index++);
2664 }
2665 // Return the final accumulated value.
2666 return accumulator;
2667}
2668
2669/**
2670 * Create an iterator which repeats a value a number of times.
2671 *
2672 * @param value - The value to repeat.
2673 *
2674 * @param count - The number of times to repeat the value.
2675 *
2676 * @returns A new iterator which repeats the specified value.
2677 *
2678 * #### Example
2679 * ```typescript
2680 * import { repeat, toArray } from '@lumino/algorithm';
2681 *
2682 * let stream = repeat(7, 3);
2683 *
2684 * toArray(stream); // [7, 7, 7]
2685 * ```
2686 */
2687function repeat(value, count) {
2688 return new RepeatIterator(value, count);
2689}
2690/**
2691 * Create an iterator which yields a value a single time.
2692 *
2693 * @param value - The value to wrap in an iterator.
2694 *
2695 * @returns A new iterator which yields the value a single time.
2696 *
2697 * #### Example
2698 * ```typescript
2699 * import { once, toArray } from '@lumino/algorithm';
2700 *
2701 * let stream = once(7);
2702 *
2703 * toArray(stream); // [7]
2704 * ```
2705 */
2706function once(value) {
2707 return new RepeatIterator(value, 1);
2708}
2709/**
2710 * An iterator which repeats a value a specified number of times.
2711 */
2712var RepeatIterator = /** @class */ (function () {
2713 /**
2714 * Construct a new repeat iterator.
2715 *
2716 * @param value - The value to repeat.
2717 *
2718 * @param count - The number of times to repeat the value.
2719 */
2720 function RepeatIterator(value, count) {
2721 this._value = value;
2722 this._count = count;
2723 }
2724 /**
2725 * Get an iterator over the object's values.
2726 *
2727 * @returns An iterator which yields the object's values.
2728 */
2729 RepeatIterator.prototype.iter = function () {
2730 return this;
2731 };
2732 /**
2733 * Create an independent clone of the iterator.
2734 *
2735 * @returns A new independent clone of the iterator.
2736 */
2737 RepeatIterator.prototype.clone = function () {
2738 return new RepeatIterator(this._value, this._count);
2739 };
2740 /**
2741 * Get the next value from the iterator.
2742 *
2743 * @returns The next value from the iterator, or `undefined`.
2744 */
2745 RepeatIterator.prototype.next = function () {
2746 if (this._count <= 0) {
2747 return undefined;
2748 }
2749 this._count--;
2750 return this._value;
2751 };
2752 return RepeatIterator;
2753}());
2754
2755/**
2756 * Create an iterator for a retroable object.
2757 *
2758 * @param object - The retroable or array-like object of interest.
2759 *
2760 * @returns An iterator which traverses the object's values in reverse.
2761 *
2762 * #### Example
2763 * ```typescript
2764 * import { retro, toArray } from '@lumino/algorithm';
2765 *
2766 * let data = [1, 2, 3, 4, 5, 6];
2767 *
2768 * let stream = retro(data);
2769 *
2770 * toArray(stream); // [6, 5, 4, 3, 2, 1]
2771 * ```
2772 */
2773function retro(object) {
2774 var it;
2775 if (typeof object.retro === 'function') {
2776 it = object.retro();
2777 }
2778 else {
2779 it = new RetroArrayIterator(object);
2780 }
2781 return it;
2782}
2783/**
2784 * An iterator which traverses an array-like object in reverse.
2785 *
2786 * #### Notes
2787 * This iterator can be used for any builtin JS array-like object.
2788 */
2789var RetroArrayIterator = /** @class */ (function () {
2790 /**
2791 * Construct a new retro iterator.
2792 *
2793 * @param source - The array-like object of interest.
2794 */
2795 function RetroArrayIterator(source) {
2796 this._source = source;
2797 this._index = source.length - 1;
2798 }
2799 /**
2800 * Get an iterator over the object's values.
2801 *
2802 * @returns An iterator which yields the object's values.
2803 */
2804 RetroArrayIterator.prototype.iter = function () {
2805 return this;
2806 };
2807 /**
2808 * Create an independent clone of the iterator.
2809 *
2810 * @returns A new independent clone of the iterator.
2811 */
2812 RetroArrayIterator.prototype.clone = function () {
2813 var result = new RetroArrayIterator(this._source);
2814 result._index = this._index;
2815 return result;
2816 };
2817 /**
2818 * Get the next value from the iterator.
2819 *
2820 * @returns The next value from the iterator, or `undefined`.
2821 */
2822 RetroArrayIterator.prototype.next = function () {
2823 if (this._index < 0 || this._index >= this._source.length) {
2824 return undefined;
2825 }
2826 return this._source[this._index--];
2827 };
2828 return RetroArrayIterator;
2829}());
2830
2831// Copyright (c) Jupyter Development Team.
2832/**
2833 * Topologically sort an iterable of edges.
2834 *
2835 * @param edges - The iterable or array-like object of edges to sort.
2836 * An edge is represented as a 2-tuple of `[fromNode, toNode]`.
2837 *
2838 * @returns The topologically sorted array of nodes.
2839 *
2840 * #### Notes
2841 * If a cycle is present in the graph, the cycle will be ignored and
2842 * the return value will be only approximately sorted.
2843 *
2844 * #### Example
2845 * ```typescript
2846 * import { topologicSort } from '@lumino/algorithm';
2847 *
2848 * let data = [
2849 * ['d', 'e'],
2850 * ['c', 'd'],
2851 * ['a', 'b'],
2852 * ['b', 'c']
2853 * ];
2854 *
2855 * topologicSort(data); // ['a', 'b', 'c', 'd', 'e']
2856 * ```
2857 */
2858function topologicSort(edges) {
2859 // Setup the shared sorting state.
2860 var sorted = [];
2861 var visited = new Set();
2862 var graph = new Map();
2863 // Add the edges to the graph.
2864 each(edges, addEdge);
2865 // Visit each node in the graph.
2866 graph.forEach(function (v, k) {
2867 visit(k);
2868 });
2869 // Return the sorted results.
2870 return sorted;
2871 // Add an edge to the graph.
2872 function addEdge(edge) {
2873 var fromNode = edge[0], toNode = edge[1];
2874 var children = graph.get(toNode);
2875 if (children) {
2876 children.push(fromNode);
2877 }
2878 else {
2879 graph.set(toNode, [fromNode]);
2880 }
2881 }
2882 // Recursively visit the node.
2883 function visit(node) {
2884 if (visited.has(node)) {
2885 return;
2886 }
2887 visited.add(node);
2888 var children = graph.get(node);
2889 if (children) {
2890 children.forEach(visit);
2891 }
2892 sorted.push(node);
2893 }
2894}
2895
2896// Copyright (c) Jupyter Development Team.
2897/**
2898 * Iterate over an iterable using a stepped increment.
2899 *
2900 * @param object - The iterable or array-like object of interest.
2901 *
2902 * @param step - The distance to step on each iteration. A value
2903 * of less than `1` will behave the same as a value of `1`.
2904 *
2905 * @returns An iterator which traverses the iterable step-wise.
2906 *
2907 * #### Example
2908 * ```typescript
2909 * import { stride, toArray } from '@lumino/algorithm';
2910 *
2911 * let data = [1, 2, 3, 4, 5, 6];
2912 *
2913 * let stream = stride(data, 2);
2914 *
2915 * toArray(stream); // [1, 3, 5];
2916 * ```
2917 */
2918function stride(object, step) {
2919 return new StrideIterator(iter(object), step);
2920}
2921/**
2922 * An iterator which traverses a source iterator step-wise.
2923 */
2924var StrideIterator = /** @class */ (function () {
2925 /**
2926 * Construct a new stride iterator.
2927 *
2928 * @param source - The iterator of values of interest.
2929 *
2930 * @param step - The distance to step on each iteration. A value
2931 * of less than `1` will behave the same as a value of `1`.
2932 */
2933 function StrideIterator(source, step) {
2934 this._source = source;
2935 this._step = step;
2936 }
2937 /**
2938 * Get an iterator over the object's values.
2939 *
2940 * @returns An iterator which yields the object's values.
2941 */
2942 StrideIterator.prototype.iter = function () {
2943 return this;
2944 };
2945 /**
2946 * Create an independent clone of the iterator.
2947 *
2948 * @returns A new independent clone of the iterator.
2949 */
2950 StrideIterator.prototype.clone = function () {
2951 return new StrideIterator(this._source.clone(), this._step);
2952 };
2953 /**
2954 * Get the next value from the iterator.
2955 *
2956 * @returns The next value from the iterator, or `undefined`.
2957 */
2958 StrideIterator.prototype.next = function () {
2959 var value = this._source.next();
2960 for (var n = this._step - 1; n > 0; --n) {
2961 this._source.next();
2962 }
2963 return value;
2964 };
2965 return StrideIterator;
2966}());
2967
2968// Copyright (c) Jupyter Development Team.
2969// Distributed under the terms of the Modified BSD License.
2970/*-----------------------------------------------------------------------------
2971| Copyright (c) 2014-2017, PhosphorJS Contributors
2972|
2973| Distributed under the terms of the BSD 3-Clause License.
2974|
2975| The full license is in the file LICENSE, distributed with this software.
2976|----------------------------------------------------------------------------*/
2977/**
2978 * The namespace for string-specific algorithms.
2979 */
2980var StringExt;
2981(function (StringExt) {
2982 /**
2983 * Find the indices of characters in a source text.
2984 *
2985 * @param source - The source text which should be searched.
2986 *
2987 * @param query - The characters to locate in the source text.
2988 *
2989 * @param start - The index to start the search.
2990 *
2991 * @returns The matched indices, or `null` if there is no match.
2992 *
2993 * #### Complexity
2994 * Linear on `sourceText`.
2995 *
2996 * #### Notes
2997 * In order for there to be a match, all of the characters in `query`
2998 * **must** appear in `source` in the order given by `query`.
2999 *
3000 * Characters are matched using strict `===` equality.
3001 */
3002 function findIndices(source, query, start) {
3003 if (start === void 0) { start = 0; }
3004 var indices = new Array(query.length);
3005 for (var i = 0, j = start, n = query.length; i < n; ++i, ++j) {
3006 j = source.indexOf(query[i], j);
3007 if (j === -1) {
3008 return null;
3009 }
3010 indices[i] = j;
3011 }
3012 return indices;
3013 }
3014 StringExt.findIndices = findIndices;
3015 /**
3016 * A string matcher which uses a sum-of-squares algorithm.
3017 *
3018 * @param source - The source text which should be searched.
3019 *
3020 * @param query - The characters to locate in the source text.
3021 *
3022 * @param start - The index to start the search.
3023 *
3024 * @returns The match result, or `null` if there is no match.
3025 * A lower `score` represents a stronger match.
3026 *
3027 * #### Complexity
3028 * Linear on `sourceText`.
3029 *
3030 * #### Notes
3031 * This scoring algorithm uses a sum-of-squares approach to determine
3032 * the score. In order for there to be a match, all of the characters
3033 * in `query` **must** appear in `source` in order. The index of each
3034 * matching character is squared and added to the score. This means
3035 * that early and consecutive character matches are preferred, while
3036 * late matches are heavily penalized.
3037 */
3038 function matchSumOfSquares(source, query, start) {
3039 if (start === void 0) { start = 0; }
3040 var indices = findIndices(source, query, start);
3041 if (!indices) {
3042 return null;
3043 }
3044 var score = 0;
3045 for (var i = 0, n = indices.length; i < n; ++i) {
3046 var j = indices[i] - start;
3047 score += j * j;
3048 }
3049 return { score: score, indices: indices };
3050 }
3051 StringExt.matchSumOfSquares = matchSumOfSquares;
3052 /**
3053 * A string matcher which uses a sum-of-deltas algorithm.
3054 *
3055 * @param source - The source text which should be searched.
3056 *
3057 * @param query - The characters to locate in the source text.
3058 *
3059 * @param start - The index to start the search.
3060 *
3061 * @returns The match result, or `null` if there is no match.
3062 * A lower `score` represents a stronger match.
3063 *
3064 * #### Complexity
3065 * Linear on `sourceText`.
3066 *
3067 * #### Notes
3068 * This scoring algorithm uses a sum-of-deltas approach to determine
3069 * the score. In order for there to be a match, all of the characters
3070 * in `query` **must** appear in `source` in order. The delta between
3071 * the indices are summed to create the score. This means that groups
3072 * of matched characters are preferred, while fragmented matches are
3073 * penalized.
3074 */
3075 function matchSumOfDeltas(source, query, start) {
3076 if (start === void 0) { start = 0; }
3077 var indices = findIndices(source, query, start);
3078 if (!indices) {
3079 return null;
3080 }
3081 var score = 0;
3082 var last = start - 1;
3083 for (var i = 0, n = indices.length; i < n; ++i) {
3084 var j = indices[i];
3085 score += j - last - 1;
3086 last = j;
3087 }
3088 return { score: score, indices: indices };
3089 }
3090 StringExt.matchSumOfDeltas = matchSumOfDeltas;
3091 /**
3092 * Highlight the matched characters of a source text.
3093 *
3094 * @param source - The text which should be highlighted.
3095 *
3096 * @param indices - The indices of the matched characters. They must
3097 * appear in increasing order and must be in bounds of the source.
3098 *
3099 * @param fn - The function to apply to the matched chunks.
3100 *
3101 * @returns An array of unmatched and highlighted chunks.
3102 */
3103 function highlight(source, indices, fn) {
3104 // Set up the result array.
3105 var result = [];
3106 // Set up the counter variables.
3107 var k = 0;
3108 var last = 0;
3109 var n = indices.length;
3110 // Iterator over each index.
3111 while (k < n) {
3112 // Set up the chunk indices.
3113 var i = indices[k];
3114 var j = indices[k];
3115 // Advance the right chunk index until it's non-contiguous.
3116 while (++k < n && indices[k] === j + 1) {
3117 j++;
3118 }
3119 // Extract the unmatched text.
3120 if (last < i) {
3121 result.push(source.slice(last, i));
3122 }
3123 // Extract and highlight the matched text.
3124 if (i < j + 1) {
3125 result.push(fn(source.slice(i, j + 1)));
3126 }
3127 // Update the last visited index.
3128 last = j + 1;
3129 }
3130 // Extract any remaining unmatched text.
3131 if (last < source.length) {
3132 result.push(source.slice(last));
3133 }
3134 // Return the highlighted result.
3135 return result;
3136 }
3137 StringExt.highlight = highlight;
3138 /**
3139 * A 3-way string comparison function.
3140 *
3141 * @param a - The first string of interest.
3142 *
3143 * @param b - The second string of interest.
3144 *
3145 * @returns `-1` if `a < b`, else `1` if `a > b`, else `0`.
3146 */
3147 function cmp(a, b) {
3148 return a < b ? -1 : a > b ? 1 : 0;
3149 }
3150 StringExt.cmp = cmp;
3151})(StringExt || (StringExt = {}));
3152
3153// Copyright (c) Jupyter Development Team.
3154/**
3155 * Take a fixed number of items from an iterable.
3156 *
3157 * @param object - The iterable or array-like object of interest.
3158 *
3159 * @param count - The number of items to take from the iterable.
3160 *
3161 * @returns An iterator which yields the specified number of items
3162 * from the source iterable.
3163 *
3164 * #### Notes
3165 * The returned iterator will exhaust early if the source iterable
3166 * contains an insufficient number of items.
3167 */
3168function take(object, count) {
3169 return new TakeIterator(iter(object), count);
3170}
3171/**
3172 * An iterator which takes a fixed number of items from a source.
3173 */
3174var TakeIterator = /** @class */ (function () {
3175 /**
3176 * Construct a new take iterator.
3177 *
3178 * @param source - The iterator of interest.
3179 *
3180 * @param count - The number of items to take from the source.
3181 */
3182 function TakeIterator(source, count) {
3183 this._source = source;
3184 this._count = count;
3185 }
3186 /**
3187 * Get an iterator over the object's values.
3188 *
3189 * @returns An iterator which yields the object's values.
3190 */
3191 TakeIterator.prototype.iter = function () {
3192 return this;
3193 };
3194 /**
3195 * Create an independent clone of the iterator.
3196 *
3197 * @returns A new independent clone of the iterator.
3198 */
3199 TakeIterator.prototype.clone = function () {
3200 return new TakeIterator(this._source.clone(), this._count);
3201 };
3202 /**
3203 * Get the next value from the iterator.
3204 *
3205 * @returns The next value from the iterator, or `undefined`.
3206 */
3207 TakeIterator.prototype.next = function () {
3208 if (this._count <= 0) {
3209 return undefined;
3210 }
3211 var value = this._source.next();
3212 if (value === undefined) {
3213 return undefined;
3214 }
3215 this._count--;
3216 return value;
3217 };
3218 return TakeIterator;
3219}());
3220
3221// Copyright (c) Jupyter Development Team.
3222/**
3223 * Iterate several iterables in lockstep.
3224 *
3225 * @param objects - The iterable or array-like objects of interest.
3226 *
3227 * @returns An iterator which yields successive tuples of values where
3228 * each value is taken in turn from the provided iterables. It will
3229 * be as long as the shortest provided iterable.
3230 *
3231 * #### Example
3232 * ```typescript
3233 * import { zip, toArray } from '@lumino/algorithm';
3234 *
3235 * let data1 = [1, 2, 3];
3236 * let data2 = [4, 5, 6];
3237 *
3238 * let stream = zip(data1, data2);
3239 *
3240 * toArray(stream); // [[1, 4], [2, 5], [3, 6]]
3241 * ```
3242 */
3243function zip() {
3244 var objects = [];
3245 for (var _i = 0; _i < arguments.length; _i++) {
3246 objects[_i] = arguments[_i];
3247 }
3248 return new ZipIterator(objects.map(iter));
3249}
3250/**
3251 * An iterator which iterates several sources in lockstep.
3252 */
3253var ZipIterator = /** @class */ (function () {
3254 /**
3255 * Construct a new zip iterator.
3256 *
3257 * @param source - The iterators of interest.
3258 */
3259 function ZipIterator(source) {
3260 this._source = source;
3261 }
3262 /**
3263 * Get an iterator over the object's values.
3264 *
3265 * @returns An iterator which yields the object's values.
3266 */
3267 ZipIterator.prototype.iter = function () {
3268 return this;
3269 };
3270 /**
3271 * Create an independent clone of the iterator.
3272 *
3273 * @returns A new independent clone of the iterator.
3274 */
3275 ZipIterator.prototype.clone = function () {
3276 return new ZipIterator(this._source.map(function (it) { return it.clone(); }));
3277 };
3278 /**
3279 * Get the next value from the iterator.
3280 *
3281 * @returns The next value from the iterator, or `undefined`.
3282 */
3283 ZipIterator.prototype.next = function () {
3284 var result = new Array(this._source.length);
3285 for (var i = 0, n = this._source.length; i < n; ++i) {
3286 var value = this._source[i].next();
3287 if (value === undefined) {
3288 return undefined;
3289 }
3290 result[i] = value;
3291 }
3292 return result;
3293 };
3294 return ZipIterator;
3295}());
3296
3297export { ArrayExt, ArrayIterator, ChainIterator, EmptyIterator, EnumerateIterator, FilterIterator, FnIterator, ItemIterator, KeyIterator, MapIterator, RangeIterator, RepeatIterator, RetroArrayIterator, StrideIterator, StringExt, TakeIterator, ValueIterator, ZipIterator, chain, each, empty, enumerate, every, filter, find, findIndex, iter, iterFn, iterItems, iterKeys, iterValues, map, max, min, minmax, once, range, reduce, repeat, retro, some, stride, take, toArray, toObject, topologicSort, zip };
3298//# sourceMappingURL=index.es6.js.map