diff --git a/README.md b/README.md
index ede1b0929..18dec6097 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-An [Array] is a collection of values, stored contiguously.
+An [array] is a collection of values, stored contiguously.
📦 [Node.js](https://www.npmjs.com/package/extra-array),
🌐 [Web](https://www.npmjs.com/package/extra-array.web),
📜 [Files](https://unpkg.com/extra-array/),
@@ -27,7 +27,7 @@ tag from the [jsDelivr CDN].
> Stability: [Experimental](https://www.youtube.com/watch?v=L1j93RnIxEo).
-[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
+[array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
[jsDelivr CDN]: https://cdn.jsdelivr.net/npm/extra-array.web/index.js
@@ -49,7 +49,7 @@ var x = [1, 2, 3, 4];
xarray.rotate(x, 1);
// → [4, 1, 2, 3]
-[...xarray.permutations([1, 2, 3])];
+xarray.permutations([1, 2, 3]);
// → [
// [], [ 1 ],
// [ 2 ], [ 3 ],
@@ -70,54 +70,66 @@ xarray.rotate(x, 1);
| Property | Description |
| ---- | ---- |
-| [is] | Check if value is an array. |
-| [keys] | List all indices. |
-| [values] | List all values. |
-| [entries] | List all index-value pairs. |
-| | |
-| [from] | Convert an iterable to array. |
-| [from$] | Convert an iterable to array. |
+| [fromIterable] | Convert an iterable to array. |
+| [fromIterable$] | Convert an iterable to array! |
| [fromRange] | Generate array from given number range. |
| [fromInvocation] | Generate array from repeated function invocation. |
| [fromApplication] | Generate array from repeated function application. |
| | |
-| [compare] | Compare two arrays (lexicographically). |
-| [isEqual] | Check if two arrays are equal. |
+| [shallowClone] | Shallow clone an array. |
+| [deepClone] | Deep clone an array. |
+| | |
+| [is] | Check if value is an array. |
+| [isSorted] | Examine if array is sorted. |
+| [keys] | Obtain all indices. |
+| [values] | Get all values. |
+| [values$] | Get all values! |
+| [entries] | Obtain all index-value pairs. |
+| [ikeys] | List all indices. |
+| [ivalues] | List all values. |
+| [ientries] | List all index-value pairs. |
| | |
-| [index] | Get zero-based index for element in array. |
-| [indexRange] | Get index range for part of array. |
+| [index] | Get zero-based index for an element in array. |
+| [indexRange] | Get zero-based index range for part of array. |
| [length] | Find the length of an array. |
| [isEmpty] | Check if an array is empty. |
+| [resize$] | Resize an array to given length! |
+| [clear$] | Remove all elements from an array! |
| | |
| [get] | Get value at index. |
| [getAll] | Get values at indices. |
| [getPath] | Get value at path in a nested array. |
| [hasPath] | Check if nested array has a path. |
| [set] | Set value at index. |
-| [set$] | Set value at index. |
-| [setPath$] | Set value at path in a nested array. |
+| [set$] | Set value at index! |
+| [setPath$] | Set value at path in a nested array! |
| [swap] | Exchange two values. |
-| [swap$] | Exchange two values. |
+| [swap$] | Exchange two values! |
+| [swapRanges] | Exchange two ranges of values. |
+| [swapRanges$] | Exchange two ranges of values! |
| [remove] | Remove value at index. |
-| [remove$] | Remove value at index. |
-| [removePath$] | Remove value at path in a nested array. |
+| [remove$] | Remove value at index! |
+| [removePath$] | Remove value at path in a nested array! |
| | |
| [count] | Count values which satisfy a test. |
-| [countAs] | Count occurrences of values. |
-| [min] | Find smallest value. |
-| [minEntry] | Find smallest entry. |
-| [max] | Find largest value. |
-| [maxEntry] | Find largest entry. |
+| [countEach] | Count occurrences of each distinct value. |
+| [min] | Find first smallest value. |
+| [minEntry] | Find first smallest entry. |
+| [max] | Find first largest value. |
+| [maxEntry] | Find first largest entry. |
| [range] | Find smallest and largest values. |
| [rangeEntries] | Find smallest and largest entries. |
| | |
-| [slice] | Get part of an array. |
-| [slice$] | Get part of an array. |
+| [compare] | Compare two arrays (lexicographically). |
+| [isEqual] | Examine if two arrays are equal. |
+| | |
| [head] | Get first value. |
| [last] | Get last value. |
+| [middle] | Get values from middle. |
| [tail] | Get values except first. |
| [init] | Get values except last. |
-| [middle] | Get values from middle. |
+| [slice] | Get part of an array. |
+| [slice$] | Get part of an array! |
| [take] | Keep first n values only. |
| [takeRight] | Keep last n values only. |
| [takeWhile] | Keep values from left, while a test passes. |
@@ -127,18 +139,23 @@ xarray.rotate(x, 1);
| [dropWhile] | Discard values from left, while a test passes. |
| [dropWhileRight] | Discard values from right, while a test passes. |
| | |
-| [prefixes] | List all possible prefixes. |
-| [suffixes] | List all possible suffixes. |
-| [infixes] | List all possible infixes. |
-| [subsequences] | List all possible subsequences. |
-| [permutations] | List all possible permutations. |
+| [prefixes] | Obtain all possible prefixes. |
+| [suffixes] | Obtain all possible suffixes. |
+| [infixes] | Obtain all possible infixes. |
+| [subsequences] | Obtain all possible subsequences. |
+| [permutations] | Obtain all possible permutations. |
+| [iprefixes] | List all possible prefixes. |
+| [isuffixes] | List all possible suffixes. |
+| [iinfixes] | List all possible infixes. |
+| [isubsequences] | List all possible subsequences. |
+| [ipermutations] | List all possible permutations. |
| [randomValue] | Pick an arbitrary value. |
| [randomPrefix] | Pick an arbitrary prefix. |
| [randomSuffix] | Pick an arbitrary suffix. |
| [randomInfix] | Pick an arbitrary infix. |
| [randomSubsequence] | Pick an arbitrary subsequence. |
| [randomPermutation] | Pick an arbitrary permutation. |
-| [randomPermutation$] | Pick an arbitrary permutation. |
+| [randomPermutation$] | Pick an arbitrary permutation! |
| | |
| [includes] | Check if array has a value. |
| [indexOf] | Find first index of a value. |
@@ -155,29 +172,41 @@ xarray.rotate(x, 1);
| [searchValue] | Find first index of a value. |
| [searchValueRight] | Find last index of a value. |
| [searchValueAll] | Find indices of value. |
+| [searchMinimumValue] | Find first index of minimum value. |
+| [searchMaximumValue] | Find first index of maximum value. |
+| [searchUnsortedValue] | Find first index of an unsorted value. |
+| [searchAdjacentDuplicateValue] | Find first index of an adjacent duplicate value. |
+| [searchMismatchedValue] | Find first index where two arrays differ. |
| [searchInfix] | Find first index of an infix. |
| [searchInfixRight] | Find last index of an infix. |
| [searchInfixAll] | Find indices of an infix. |
| [searchSubsequence] | Find first index of a subsequence. |
-| [hasValue] | Check if array has a value. |
-| [hasPrefix] | Check if array starts with a prefix. |
-| [hasSuffix] | Check if array ends with a suffix. |
-| [hasInfix] | Check if array contains an infix. |
-| [hasSubsequence] | Check if array has a subsequence. |
-| [hasPermutation] | Check if array has a permutation. |
+| [hasValue] | Examine if array has a value. |
+| [hasUnsortedValue] | Examine if array has an unsorted value. |
+| [hasPrefix] | Examine if array starts with a prefix. |
+| [hasSuffix] | Examine if array ends with a suffix. |
+| [hasInfix] | Examine if array contains an infix. |
+| [hasSubsequence] | Examine if array has a subsequence. |
+| [hasPermutation] | Examine if array has a permutation. |
| | |
| [forEach] | Call a function for each value. |
-| [some] | Check if any value satisfies a test. |
-| [every] | Check if all values satisfy a test. |
+| [some] | Examine if any value satisfies a test. |
+| [every] | Examine if all values satisfy a test. |
| [map] | Transform values of an array. |
-| [map$] | Transform values of an array. |
+| [map$] | Transform values of an array! |
| [reduce] | Reduce values of array to a single value. |
| [reduceRight] | Reduce values from right, to a single value. |
+| [exclusiveScan] | Perform exclusive prefix scan from left to right. |
+| [exclusiveScan$] | Perform exclusive prefix scan from left to right! |
+| [inclusiveScan] | Perform inclusive prefix scan from left to right. |
+| [inclusiveScan$] | Perform inclusive prefix scan from left to right! |
+| [adjacentCombine] | Combine adjacent values of an array. |
+| [adjacentCombine$] | Combine adjacent values of an array! |
| [filter] | Keep values which pass a test. |
-| [filter$] | Keep values which pass a test. |
+| [filter$] | Keep values which pass a test! |
| [filterAt] | Keep values at given indices. |
| [reject] | Discard values which pass a test. |
-| [reject$] | Discard values which pass a test. |
+| [reject$] | Discard values which pass a test! |
| [rejectAt] | Discard values at given indices. |
| [accumulate] | Produce accumulating values. |
| [flat] | Flatten nested array to given depth. |
@@ -185,25 +214,25 @@ xarray.rotate(x, 1);
| [zip] | Combine values from arrays. |
| | |
| [fill] | Fill with given value. |
-| [fill$] | Fill with given value. |
+| [fill$] | Fill with given value! |
| [sort] | Arrange values in order. |
-| [sort$] | Arrange values in order. |
+| [sort$] | Arrange values in order! |
| [push] | Add value to the end. |
-| [push$] | Add values to the end. |
+| [push$] | Add values to the end! |
| [pop] | Remove last value. |
-| [pop$] | Remove last value. |
+| [pop$] | Remove last value! |
| [shift] | Remove first value. |
-| [shift$] | Remove first value. |
+| [shift$] | Remove first value! |
| [unshift] | Add values to the start. |
-| [unshift$] | Add values to the start. |
+| [unshift$] | Add values to the start! |
| [copy] | Copy part of array to another. |
-| [copy$] | Copy part of array to another. |
+| [copy$] | Copy part of array to another! |
| [copyWithin] | Copy part of array within. |
-| [copyWithin$] | Copy part of array within. |
+| [copyWithin$] | Copy part of array within! |
| [moveWithin] | Move part of array within. |
-| [moveWithin$] | Move part of array within. |
+| [moveWithin$] | Move part of array within! |
| [splice] | Remove or replace existing values. |
-| [splice$] | Remove or replace existing values. |
+| [splice$] | Remove or replace existing values! |
| [split] | Break array considering test as separator. |
| [splitAt] | Break array considering indices as separator. |
| [cut] | Break array when test passes. |
@@ -211,33 +240,44 @@ xarray.rotate(x, 1);
| [cutAt] | Break array at given indices. |
| [cutAtRight] | Break array after given indices. |
| [group] | Keep similar values together and in order. |
-| [partition] | Segregate values by test result. |
-| [partitionAs] | Segregate values by similarity. |
+| [segregate] | Segregate values by test result. |
+| [segregateEach] | Segregate each distinct value. |
| [chunk] | Break array into chunks of given size. |
| [cycle] | Obtain values that cycle through array. |
| [repeat] | Repeat an array given times. |
| [reverse] | Reverse the values. |
-| [reverse$] | Reverse the values. |
+| [reverse$] | Reverse the values! |
| [rotate] | Rotate values in array. |
-| [rotate$] | Rotate values in array. |
+| [rotate$] | Rotate values in array! |
| [intersperse] | Place a separator between every value. |
| [interpolate] | Estimate new values between existing ones. |
| [intermix] | Place values of an array between another. |
| [interleave] | Place values from iterables alternately. |
| | |
| [concat] | Append values from arrays. |
-| [concat$] | Append values from arrays. |
+| [concat$] | Append values from arrays! |
| [join] | Join values together into a string. |
| | |
-| [isUnique] | Check if there are no duplicate values. |
-| [isDisjoint] | Check if arrays have no value in common. |
+| [isUnique] | Examine if there are no duplicate values. |
+| [isDisjoint] | Examine if arrays have no value in common. |
| [unique] | Remove duplicate values. |
| [union] | Obtain values present in any array. |
-| [union$] | Obtain values present in any array. |
+| [union$] | Obtain values present in any array! |
| [intersection] | Obtain values present in both arrays. |
| [difference] | Obtain values not present in another array. |
| [symmetricDifference] | Obtain values not present in both arrays. |
-| [cartesianProduct] | List cartesian product of arrays. |
+| [cartesianProduct] | Obtain cartesian product of arrays. |
+
+
+
+
+
+## References
+
+- [Prefix sum array and difference array : Woburn C.I. PEGWiki](https://wcipeg.com/wiki/Prefix_sum_array_and_difference_array)
+- [How to get the count of each distinct value in a column?](https://stackoverflow.com/q/7053902/1413259)
+- [How to add region in java script file, visual studio](https://stackoverflow.com/a/51550649/1413259)
+- [Operator precedence - JavaScript : MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence)
@@ -255,8 +295,8 @@ xarray.rotate(x, 1);
[keys]: https://github.com/nodef/extra-array/wiki/keys
[values]: https://github.com/nodef/extra-array/wiki/values
[entries]: https://github.com/nodef/extra-array/wiki/entries
-[from]: https://github.com/nodef/extra-array/wiki/from
-[from$]: https://github.com/nodef/extra-array/wiki/from$
+[fromIterable]: https://github.com/nodef/extra-array/wiki/fromIterable
+[fromIterable$]: https://github.com/nodef/extra-array/wiki/fromIterable$
[fromRange]: https://github.com/nodef/extra-array/wiki/fromRange
[fromInvocation]: https://github.com/nodef/extra-array/wiki/fromInvocation
[fromApplication]: https://github.com/nodef/extra-array/wiki/fromApplication
@@ -279,7 +319,7 @@ xarray.rotate(x, 1);
[remove$]: https://github.com/nodef/extra-array/wiki/remove$
[removePath$]: https://github.com/nodef/extra-array/wiki/removePath$
[count]: https://github.com/nodef/extra-array/wiki/count
-[countAs]: https://github.com/nodef/extra-array/wiki/countAs
+[countEach]: https://github.com/nodef/extra-array/wiki/countEach
[min]: https://github.com/nodef/extra-array/wiki/min
[minEntry]: https://github.com/nodef/extra-array/wiki/minEntry
[max]: https://github.com/nodef/extra-array/wiki/max
@@ -382,8 +422,8 @@ xarray.rotate(x, 1);
[cutAt]: https://github.com/nodef/extra-array/wiki/cutAt
[cutAtRight]: https://github.com/nodef/extra-array/wiki/cutAtRight
[group]: https://github.com/nodef/extra-array/wiki/group
-[partition]: https://github.com/nodef/extra-array/wiki/partition
-[partitionAs]: https://github.com/nodef/extra-array/wiki/partitionAs
+[segregate]: https://github.com/nodef/extra-array/wiki/segregate
+[segregateEach]: https://github.com/nodef/extra-array/wiki/segregateEach
[chunk]: https://github.com/nodef/extra-array/wiki/chunk
[cycle]: https://github.com/nodef/extra-array/wiki/cycle
[repeat]: https://github.com/nodef/extra-array/wiki/repeat
@@ -407,3 +447,33 @@ xarray.rotate(x, 1);
[difference]: https://github.com/nodef/extra-array/wiki/difference
[symmetricDifference]: https://github.com/nodef/extra-array/wiki/symmetricDifference
[cartesianProduct]: https://github.com/nodef/extra-array/wiki/cartesianProduct
+[shallowClone]: https://github.com/nodef/extra-array/wiki/shallowClone
+[deepClone]: https://github.com/nodef/extra-array/wiki/deepClone
+[isSorted]: https://github.com/nodef/extra-array/wiki/isSorted
+[ikeys]: https://github.com/nodef/extra-array/wiki/ikeys
+[values$]: https://github.com/nodef/extra-array/wiki/values$
+[ivalues]: https://github.com/nodef/extra-array/wiki/ivalues
+[ientries]: https://github.com/nodef/extra-array/wiki/ientries
+[resize$]: https://github.com/nodef/extra-array/wiki/resize$
+[clear$]: https://github.com/nodef/extra-array/wiki/clear$
+[countEach]: https://github.com/nodef/extra-array/wiki/countEach
+[iprefixes]: https://github.com/nodef/extra-array/wiki/iprefixes
+[isuffixes]: https://github.com/nodef/extra-array/wiki/isuffixes
+[iinfixes]: https://github.com/nodef/extra-array/wiki/iinfixes
+[isubsequences]: https://github.com/nodef/extra-array/wiki/isubsequences
+[ipermutations]: https://github.com/nodef/extra-array/wiki/ipermutations
+[searchUnsortedValue]: https://github.com/nodef/extra-array/wiki/searchUnsortedValue
+[hasUnsortedValue]: https://github.com/nodef/extra-array/wiki/hasUnsortedValue
+[partitionEach]: https://github.com/nodef/extra-array/wiki/partitionEach
+[swapRanges]: https://github.com/nodef/extra-array/wiki/swapRanges
+[swapRanges$]: https://github.com/nodef/extra-array/wiki/swapRanges$
+[searchAdjacentDuplicateValue]: https://github.com/nodef/extra-array/wiki/searchAdjacentDuplicateValue
+[searchMismatchedValue]: https://github.com/nodef/extra-array/wiki/searchMismatchedValue
+[exclusiveScan]: https://github.com/nodef/extra-array/wiki/exclusiveScan
+[exclusiveScan$]: https://github.com/nodef/extra-array/wiki/exclusiveScan$
+[inclusiveScan]: https://github.com/nodef/extra-array/wiki/inclusiveScan
+[inclusiveScan$]: https://github.com/nodef/extra-array/wiki/inclusiveScan$
+[adjacentCombine]: https://github.com/nodef/extra-array/wiki/adjacentCombine
+[searchMinimumValue]: https://github.com/nodef/extra-array/wiki/searchMinimumValue
+[searchMaximumValue]: https://github.com/nodef/extra-array/wiki/searchMaximumValue
+[adjacentCombine$]: https://github.com/nodef/extra-array/wiki/adjacentCombine$
diff --git a/TODO b/TODO
index 42206197f..580d8dc22 100644
--- a/TODO
+++ b/TODO
@@ -1,12 +1,4 @@
-NAMING
-- keys(), keyList()
-- push(), push$(), pushTo$()
-
-
-TESTS
-
-
-SORTS, IN PAIR, ISSORTED
+SORTS, IN PAIR
Instead of mapFn, provide pair array to define sort mapping.
selectionSort, insertionSort, bubbleSort, mergeSort, (are all stable?)
@@ -32,41 +24,74 @@ PARSE, OTHERS
INDEX -VE
- moveWithin
-knuth-shuffle-seeded
-Description
-The Fisher-Yates (aka Knuth) shuffle for Node.js, with seeding support
-
-
+OLD SORT ALGORITHMS
+/**
+ * Arrange values in order!
+ * @param x an array (updated!)
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @param fs swap function (x, i, j)
+ * @returns x | x[i] ≤ x[j] ∀ i ≤ j
+ */
+function bubbleSort$(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null, fs: SwapFunction | null=null): T[] {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY; // TODO: use map function
+ var fs = fs || swap$;
+ var X = x.length;
+ for (var i=0; i 0) fs(x, i, j);
+ }
+ return x;
+}
-// HELPERS
-// -------
-// Convert an array to set, using a map function.
-function setFrom(x: T[], fm: MapFunction): Set {
- var a = new Set();
- for (var i=0, I=x.length; i(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null, fs: SwapFunction | null=null): T[] {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY; // TODO: use map function
+ var fs = fs || swap$;
+ var X = x.length;
+ for (var i=0; i 0) l = j;
+ fs(x, i, l);
+ }
+ return x;
}
-// Find indices of an infix as a list.
-function* iterableSearchInfixAll(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): IterableIterator {
+// TODO: Check if this is correct!
+/**
+ * Arrange values in order!
+ * @param x an array (updated!)
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @param fs swap function (x, i, j)
+ * @returns x | x[i] ≤ x[j] ∀ i ≤ j
+ */
+function insertionSortOld$(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null, fs: SwapFunction | null=null): T[] {
var fc = fc || COMPARE;
- var fm = fm || IDENTITY;
- var y1 = [...map(y, fm)];
- var Y = y1.length;
- if (Y===0) { yield* fromRange(0, x.length); return; }
- var m = new Array(Y).fill(false);
- var i = -1, J = 0;
- for (var vx of x) {
- var wx = fm(vx, ++i, x);
- for (var j=J; j>0; --j)
- m[j] = m[j-1] && fc(wx, y1[j])===0;
- m[0] = fc(wx, y1[0])===0;
- J = Math.min(J+1, Y-1);
- if (m[Y-1]) yield i-Y+1;
+ var fm = fm || IDENTITY; // TODO: use map function
+ var fs = fs || swap$; // TODO: use swap function
+ var X = x.length;
+ for (var i=X-2; i>=0; --i) {
+ var xv = x[i], mv = x[i];
+ for (var j=i+1; j=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz",
- "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==",
+ "version": "7.21.8",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz",
+ "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.21.4",
- "@babel/generator": "^7.21.4",
- "@babel/helper-compilation-targets": "^7.21.4",
- "@babel/helper-module-transforms": "^7.21.2",
- "@babel/helpers": "^7.21.0",
- "@babel/parser": "^7.21.4",
+ "@babel/generator": "^7.21.5",
+ "@babel/helper-compilation-targets": "^7.21.5",
+ "@babel/helper-module-transforms": "^7.21.5",
+ "@babel/helpers": "^7.21.5",
+ "@babel/parser": "^7.21.8",
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.21.4",
- "@babel/types": "^7.21.4",
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -103,12 +101,12 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz",
- "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz",
+ "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.21.4",
+ "@babel/types": "^7.21.5",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
@@ -118,12 +116,12 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz",
- "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz",
+ "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==",
"dev": true,
"dependencies": {
- "@babel/compat-data": "^7.21.4",
+ "@babel/compat-data": "^7.21.5",
"@babel/helper-validator-option": "^7.21.0",
"browserslist": "^4.21.3",
"lru-cache": "^5.1.1",
@@ -146,9 +144,9 @@
}
},
"node_modules/@babel/helper-environment-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
- "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz",
+ "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -192,40 +190,40 @@
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.21.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
- "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz",
+ "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==",
"dev": true,
"dependencies": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-environment-visitor": "^7.21.5",
+ "@babel/helper-module-imports": "^7.21.4",
+ "@babel/helper-simple-access": "^7.21.5",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.21.2",
- "@babel/types": "^7.21.2"
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
- "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz",
+ "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-simple-access": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
- "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz",
+ "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.20.2"
+ "@babel/types": "^7.21.5"
},
"engines": {
"node": ">=6.9.0"
@@ -244,9 +242,9 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.19.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
- "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz",
+ "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -271,14 +269,14 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz",
- "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz",
+ "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==",
"dev": true,
"dependencies": {
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.21.0",
- "@babel/types": "^7.21.0"
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5"
},
"engines": {
"node": ">=6.9.0"
@@ -370,9 +368,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz",
- "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
+ "version": "7.21.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz",
+ "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -573,19 +571,19 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz",
- "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz",
+ "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.21.4",
- "@babel/generator": "^7.21.4",
- "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/generator": "^7.21.5",
+ "@babel/helper-environment-visitor": "^7.21.5",
"@babel/helper-function-name": "^7.21.0",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.21.4",
- "@babel/types": "^7.21.4",
+ "@babel/parser": "^7.21.5",
+ "@babel/types": "^7.21.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -594,12 +592,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz",
- "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz",
+ "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==",
"dev": true,
"dependencies": {
- "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-string-parser": "^7.21.5",
"@babel/helper-validator-identifier": "^7.19.1",
"to-fast-properties": "^2.0.0"
},
@@ -1071,9 +1069,9 @@
}
},
"node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==",
+ "version": "17.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.1.1.tgz",
+ "integrity": "sha512-/X7Gh/qWiWaooJmUnYD48SYy72fyrk2ceisOSe89JojK7r0j8YrTwYpDi76kI+c6QiqX1KSgdoBTMJvktsDkYw==",
"dev": true
},
"node_modules/@octokit/plugin-paginate-rest": {
@@ -1163,12 +1161,12 @@
}
},
"node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.1.tgz",
+ "integrity": "sha512-Vx4keMiD/CAiwVFasLcH0xBSVbKIHebIZke9i7ZbUWGNN4vJFWSYH6Nvga7UY9NIJCGa6x3QG849XTbi5wYmkA==",
"dev": true,
"dependencies": {
- "@octokit/openapi-types": "^16.0.0"
+ "@octokit/openapi-types": "^17.1.1"
}
},
"node_modules/@rollup/plugin-commonjs": {
@@ -1300,18 +1298,18 @@
}
},
"node_modules/@types/babel__traverse": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
- "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
+ "version": "7.18.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.5.tgz",
+ "integrity": "sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==",
"dev": true,
"dependencies": {
"@babel/types": "^7.3.0"
}
},
"node_modules/@types/estree": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
- "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
"dev": true
},
"node_modules/@types/graceful-fs": {
@@ -1348,9 +1346,9 @@
}
},
"node_modules/@types/jest": {
- "version": "29.5.0",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz",
- "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==",
+ "version": "29.5.1",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.1.tgz",
+ "integrity": "sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@@ -1358,9 +1356,9 @@
}
},
"node_modules/@types/node": {
- "version": "18.15.11",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz",
- "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==",
+ "version": "20.1.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz",
+ "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==",
"dev": true
},
"node_modules/@types/prettier": {
@@ -1673,9 +1671,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001478",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz",
- "integrity": "sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==",
+ "version": "1.0.30001485",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001485.tgz",
+ "integrity": "sha512-8aUpZ7sjhlOyiNsg+pgcrTTPUXKh+rg544QYHSvQErljVEKJzvkYkCR/hUFeeVoEfTToUtY9cUKNRC7+c45YkA==",
"dev": true,
"funding": [
{
@@ -1875,9 +1873,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.359",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.359.tgz",
- "integrity": "sha512-OoVcngKCIuNXtZnsYoqlCvr0Cf3NIPzDIgwUfI9bdTFjXCrr79lI0kwQstLPZ7WhCezLlGksZk/BFAzoXC7GDw==",
+ "version": "1.4.385",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.385.tgz",
+ "integrity": "sha512-L9zlje9bIw0h+CwPQumiuVlfMcV4boxRjFIWDcLfFqTZNbkwOExBzfmswytHawObQX4OUhtNv8gIiB21kOurIg==",
"dev": true
},
"node_modules/emittery": {
@@ -2014,12 +2012,6 @@
"integrity": "sha512-Njei3Q8nY+rwWpcUARkTAqqBmCzREHWWe1D5ysuuPKMD91yBss4TuR8+eawG7K9EO1BJRgtnVxne7S31dG04Fw==",
"dev": true
},
- "node_modules/extra-iterable": {
- "version": "3.2.13",
- "resolved": "https://registry.npmjs.org/extra-iterable/-/extra-iterable-3.2.13.tgz",
- "integrity": "sha512-yi9l6ZiMofA47MILQAg1kpow8uk7H9e3mVBB7JEDIiB4ZwLCPx8vBWClRt9E7OY8WHi1xBiHcpqrv0TshlbEgQ==",
- "dev": true
- },
"node_modules/extra-javascript-text": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/extra-javascript-text/-/extra-javascript-text-0.1.14.tgz",
@@ -2044,12 +2036,6 @@
"integrity": "sha512-d2+ACy9mY0GcoNITnYM+bO+Omb509jiorUmXjZSt4oLDbnJlXDJElmGg8X7r2K58grTR8RPALct6FF7yMVG2XQ==",
"dev": true
},
- "node_modules/extra-set": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/extra-set/-/extra-set-3.1.6.tgz",
- "integrity": "sha512-b61Z69/euJNCFTjp583dT8agtvrwdwS4nFyXphKozrby8wOX7Lt+8uvKA7SnVnms7GJ0hextzbU7uOcrRCzYlw==",
- "dev": true
- },
"node_modules/extra-typedoc-theme": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/extra-typedoc-theme/-/extra-typedoc-theme-0.1.10.tgz",
@@ -3623,9 +3609,9 @@
}
},
"node_modules/pure-rand": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz",
- "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz",
+ "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==",
"dev": true,
"funding": [
{
@@ -3701,9 +3687,9 @@
}
},
"node_modules/rollup": {
- "version": "3.20.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz",
- "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
+ "version": "3.21.5",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.5.tgz",
+ "integrity": "sha512-a4NTKS4u9PusbUJcfF4IMxuqjFzjm6ifj76P54a7cKnvVzJaG12BLVR+hgU2YDGHzyMMQNxLAZWuALsn8q2oQg==",
"dev": true,
"peer": true,
"bin": {
@@ -3783,9 +3769,9 @@
"dev": true
},
"node_modules/semver": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz",
- "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
+ "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -3837,9 +3823,9 @@
}
},
"node_modules/shiki": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz",
- "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==",
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.2.tgz",
+ "integrity": "sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==",
"dev": true,
"dependencies": {
"ansi-sequence-parser": "^1.1.0",
@@ -4169,14 +4155,14 @@
}
},
"node_modules/typedoc": {
- "version": "0.24.1",
- "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.1.tgz",
- "integrity": "sha512-u4HwjZcSQhQSkkhLjgcs0ooAf6HrFVLDHHrwU2xZW8WxH0KnGZlNkaWxiOcK5Gagj7mxJSgwWx0dv8ACDAOXAQ==",
+ "version": "0.24.6",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.6.tgz",
+ "integrity": "sha512-c3y3h45xJv3qYwKDAwU6Cl+26CjT0ZvblHzfHJ+SjQDM4p1mZxtgHky4lhmG0+nNarRht8kADfZlbspJWdZarQ==",
"dev": true,
"dependencies": {
"lunr": "^2.3.9",
- "marked": "^4.2.12",
- "minimatch": "^7.1.3",
+ "marked": "^4.3.0",
+ "minimatch": "^9.0.0",
"shiki": "^0.14.1"
},
"bin": {
@@ -4190,15 +4176,15 @@
}
},
"node_modules/typedoc/node_modules/minimatch": {
- "version": "7.4.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
- "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
+ "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -4225,9 +4211,9 @@
"dev": true
},
"node_modules/update-browserslist-db": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
- "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
+ "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
"dev": true,
"funding": [
{
@@ -4237,6 +4223,10 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
@@ -4244,7 +4234,7 @@
"picocolors": "^1.0.0"
},
"bin": {
- "browserslist-lint": "cli.js"
+ "update-browserslist-db": "cli.js"
},
"peerDependencies": {
"browserslist": ">= 4.21.0"
@@ -4374,9 +4364,9 @@
"dev": true
},
"node_modules/yargs": {
- "version": "17.7.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
- "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"dependencies": {
"cliui": "^8.0.1",
diff --git a/package.json b/package.json
index efc0da25b..8e55effe0 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "extra-array",
- "version": "3.1.11",
- "description": "An Array is a collection of values, stored contiguously.",
+ "version": "4.0.1",
+ "description": "An array is a collection of values, stored contiguously.",
"main": "index.js",
"module": "index.mjs",
"sideEffects": false,
@@ -32,12 +32,10 @@
"devDependencies": {
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-node-resolve": "^15.0.2",
- "@types/jest": "^29.5.0",
+ "@types/jest": "^29.5.1",
"extra-build": "^2.2.42",
"extra-function": "^1.1.32",
- "extra-iterable": "^3.2.13",
"extra-math": "^1.3.55",
- "extra-set": "^3.1.6",
"jest": "^29.5.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-dts": "^5.3.0",
diff --git a/src/index.ts b/src/index.ts
index 05d00f5d3..2af9a2fb0 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,23 +3,23 @@ import {
IDENTITY,
COMPARE,
} from "extra-function";
-import {
- MapFunction as IterableMapFunction,
- searchInfixAll as iterableSearchInfixAll,
-} from "extra-iterable";
-// TYPES
-// =====
+// #region TYPES
+// =============
-/** Entries is a list of key-value pairs, with unique keys (indices). */
-export type Entries = Iterable<[number, T]>;
+/** Entries is an array of index-value pairs, with unique indices. */
+export type Entries = [number, T][];
+/** IEntries is a list of index-value pairs, with unique indices. */
+export type IEntries = Iterable<[number, T]>;
-/** Lists is a pair of key list and value list, with unique keys (indices). */
-export type Lists = [Iterable, Iterable];
+/** Lists is a pair of index array and value array, with unique indices. */
+export type Lists = [number[], T[]];
+/** ILists is a pair of index iterable list and value iterable list, with unique indices. */
+export type ILists = [Iterable, Iterable];
/**
@@ -95,92 +95,61 @@ export type ReduceFunction = (acc: U, v: T, i: number, x: T[]) => U;
export type EndFunction = (dones: boolean[]) => boolean;
+/**
+ * Handle swapping of two values in an array.
+ * @param x an array (updated!)
+ * @param i an index
+ * @param j another index
+ * @returns x | x[i] ⇔ x[j]
+ */
+type SwapFunction = (x: T[], i: number, j: number) => T[];
+// #endregion
+
+
-// METHODS
-// =======
+// #region METHODS
+// ===============
-// HELPERS
-// -------
+// #region HELPERS
+// ---------------
/** Convert an iterable to set. */
-function toSet(x: Iterable, fm: IterableMapFunction | null=null): Set {
+function toSet(x: T[], fm: MapFunction | null=null): Set {
if (!fm) return new Set(x);
var a = new Set(), i = -1;
for (var v of x)
a.add(fm(v, ++i, x));
return a;
}
+// #endregion
-// ABOUT
-// -----
-
-/**
- * Check if value is an array.
- * @param v a value
- * @returns v is an array?
- */
-export function is(v: any): v is any[] {
- return Array.isArray(v);
-}
-
-
-/**
- * List all indices.
- * @param x an array
- * @returns 0, 1, ..., |x|-1
- */
-export function keys(x: T[]): IterableIterator {
- return x.keys();
-}
-
-
-/**
- * List all values.
- * @param x an array
- * @returns v₀, v₁, ... | vᵢ = x[i]
- */
-export function values(x: T[]): IterableIterator {
- return x.values();
-}
-
-
-/**
- * List all index-value pairs.
- * @param x an array
- * @returns [0, v₀], [1, v₁], ... | vᵢ = x[i]
- */
-export function entries(x: T[]): Entries {
- return x.entries();
-}
-
-
-
-
-// GENERATE
-// --------
+// #region GENERATE
+// ----------------
/**
* Convert an iterable to array.
* @param x an iterable
* @returns x as array
*/
-export function from(x: Iterable): T[] {
+export function fromIterable(x: Iterable): T[] {
return [...x];
}
+export {fromIterable as from};
/**
- * Convert an iterable to array.
+ * Convert an iterable to array!
* @param x an iterable (updatable if array!)
* @returns x as array
*/
-export function from$(x: Iterable): T[] {
+export function fromIterable$(x: Iterable): T[] {
return Array.isArray(x)? x : [...x];
}
+export {fromIterable$ as from$};
/**
@@ -228,59 +197,143 @@ export function fromApplication(fm: MapFunction, v: T, n: number): T[]
return a;
}
export {fromApplication as fromApply};
+// #endregion
-// COMPARE
-// -------
+// #region CLONE
+// -------------
/**
- * Compare two arrays (lexicographically).
+ * Shallow clone an array.
* @param x an array
- * @param y another array
- * @param fc compare function (a, b)
- * @param fm map function (v, i, x)
- * @returns xy: +ve
+ * @returns shallow clone of x
*/
-export function compare(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
- var fc = fc || COMPARE;
- var fm = fm || IDENTITY;
- var X = x.length;
- var Y = y.length;
- for (var i=0, I=Math.min(X, Y); i(x: T[]): T[] {
+ return x.slice();
}
+export {shallowClone as clone};
/**
- * Check if two arrays are equal.
+ * Deep clone an array.
+ * @param x an array
+ * @returns deep clone of x
+ */
+export function deepClone(x: T[]): T[] {
+ return structuredClone(x);
+}
+// #endregion
+
+
+
+
+// #region ABOUT
+// -------------
+
+/**
+ * Check if value is an array.
+ * @param v a value
+ * @returns v is an array?
+ */
+export function is(v: any): v is any[] {
+ return Array.isArray(v);
+}
+
+
+/**
+ * Examine if array is sorted.
* @param x an array
- * @param y another array
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
- * @returns x = y?
+ * @returns x is sorted?
*/
-export function isEqual(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
- var X = x.length, Y = y.length;
- return X===Y && compare(x, y, fc, fm)===0;
+export function isSorted(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
+ return searchUnsortedValue(x, fc, fm) === -1;
}
+/**
+ * Obtain all indices.
+ * @param x an array
+ * @returns [0, 1, ..., |x|-1]
+ */
+export function keys(x: T[]): number[] {
+ return [...x.keys()];
+}
-// LENGTH
-// ------
+/**
+ * List all indices.
+ * @param x an array
+ * @returns 0, 1, ..., |x|-1
+ */
+export function ikeys(x: T[]): IterableIterator {
+ return x.keys();
+}
+
/**
- * Get zero-based index for element in array.
+ * Get all values.
* @param x an array
- * @param i index (-ve: from right)
+ * @returns [v₀, v₁, ...] | vᵢ = x[i]
+ */
+export function values(x: T[]): T[] {
+ return x.slice();
+}
+
+
+/**
+ * Get all values!
+ * @param x an array
+ * @returns x (reference!)
+ */
+export function values$(x: T[]): T[] {
+ return x;
+}
+
+
+/**
+ * List all values.
+ * @param x an array
+ * @returns v₀, v₁, ... | vᵢ = x[i]
+ */
+export function ivalues(x: T[]): IterableIterator {
+ return x.values();
+}
+
+
+/**
+ * Obtain all index-value pairs.
+ * @param x an array
+ * @returns [[0, v₀], [1, v₁], ...] | vᵢ = x[i]
+ */
+export function entries(x: T[]): Entries {
+ return [...x.entries()];
+}
+
+
+/**
+ * List all index-value pairs.
+ * @param x an array
+ * @returns [0, v₀], [1, v₁], ... | vᵢ = x[i]
+ */
+export function ientries(x: T[]): IEntries {
+ return x.entries();
+}
+// #endregion
+
+
+
+
+// #region LENGTH
+// --------------
+
+/**
+ * Get zero-based index for an element in array.
+ * @param x an array
+ * @param i ±index
* @returns i' | x[i'] = x[i]; i' ∈ [0, |x|]
*/
export function index(x: T[], i: number): number {
@@ -290,10 +343,10 @@ export function index(x: T[], i: number): number {
/**
- * Get index range for part of array.
+ * Get zero-based index range for part of array.
* @param x an array
- * @param i start index (-ve: from right) [0]
- * @param I end index (-ve: from right) [|x|]
+ * @param i start ±index [0]
+ * @param I end ±index (exclusive) [|x|]
* @returns [i', I'] | i' ≤ I'; i', I' ∈ [0, |x|]
*/
export function indexRange(x: T[], i: number=0, I: number=x.length): [number, number] {
@@ -307,8 +360,8 @@ export function indexRange(x: T[], i: number=0, I: number=x.length): [number,
/**
* Find the length of an array.
* @param x an array
- * @param i start index [0]
- * @param I end index [X]
+ * @param i start ±index [0]
+ * @param I end ±index (exclusive) [X]
* @returns |x[i..I]|
*/
export function length(x: T[], i: number=0, I: number=x.length): number {
@@ -328,10 +381,36 @@ export function isEmpty(x: T[]): boolean {
}
+/**
+ * Resize an array to given length!
+ * @param x an array
+ * @param n new length
+ * @param vd default value
+ * @returns resized x
+ */
+export function resize$(x: T[], n: number, vd: T) {
+ var X = x.length; x.length = n;
+ if (n>X) x.fill(vd, X);
+ return x;
+}
+
+
+/**
+ * Remove all elements from an array!
+ * @param x an array (updated!)
+ * @returns cleared x
+ */
+export function clear$(x: T[]) {
+ x.length = 0;
+ return x;
+}
+// #endregion
-// GET/SET
-// -------
+
+
+// #region GET/SET
+// ---------------
/**
* Get value at index.
@@ -342,6 +421,11 @@ export function isEmpty(x: T[]): boolean {
export function get(x: T[], i: number): T {
return x[index(x, i)];
}
+export {get as at};
+
+
+// Get values at index range.
+// export {slice as getRange};
/**
@@ -393,11 +477,12 @@ export function hasPath(x: any[], p: number[]): boolean {
export function set(x: T[], i: number, v: T): T[] {
return set$(x.slice(), i, v);
}
+export {set as with};
/**
- * Set value at index.
- * @param x an array (updated)
+ * Set value at index!
+ * @param x an array (updated!)
* @param i index
* @param v value
* @returns x | x[i] = v
@@ -408,9 +493,13 @@ export function set$(x: T[], i: number, v: T): T[] {
}
+// TODO: setRange$()
+// TODO: setAll$()
+
+
/**
- * Set value at path in a nested array.
- * @param x a nested array (updated)
+ * Set value at path in a nested array!
+ * @param x a nested array (updated!)
* @param p path
* @param v value
* @returns x | x[i₀][i₁][...] = v; [i₀, i₁, ...] = p
@@ -435,11 +524,11 @@ export function swap(x: T[], i: number, j: number): T[] {
/**
- * Exchange two values.
- * @param x an array (updated)
+ * Exchange two values!
+ * @param x an array (updated!)
* @param i an index
* @param j another index
- * @returns x | x[i] ↔ x[j]
+ * @returns x | x[i] ⇔ x[j]
*/
export function swap$(x: T[], i: number, j: number): T[] {
var i = index(x, i), j = index(x, j);
@@ -448,6 +537,60 @@ export function swap$(x: T[], i: number, j: number): T[] {
}
+/**
+ * Exchange two values!
+ * @param x an array (updated!)
+ * @param i an +ve index
+ * @param j another +ve index
+ * @returns x | x[i] ⇔ x[j]
+ */
+function swapRaw$(x: T[], i: number, j: number): T[] {
+ var t = x[i]; x[i] = x[j]; x[j] = t;
+ return x;
+}
+// NOTE: May also be called swapUnchecked$().
+
+
+/**
+ * Exchange two ranges of values.
+ * @param x an array
+ * @param i start index of first range
+ * @param I end index of first range (exclusive)
+ * @param j start index of second range
+ * @param J end index of second range (exclusive)
+ * @returns x' | x' = x; x'[i..I] = x[j..J]; x'[j..J] = x[i..I]
+ */
+export function swapRanges(x: T[], i: number, I: number, j: number, J: number): T[] {
+ var [i, I] = indexRange(x, i, I);
+ var [j, J] = indexRange(x, j, J);
+ if (j(x: T[], i: number, I: number, j: number, J: number): T[] {
+ var [i, I] = indexRange(x, i, I);
+ var [j, J] = indexRange(x, j, J);
+ if (j(x: T[], i: number): T[] {
/**
- * Remove value at index.
- * @param x an array (updated)
+ * Remove value at index!
+ * @param x an array (updated!)
* @param i index
* @returns x \\: [i]
*/
@@ -473,8 +616,8 @@ export function remove$(x: T[], i: number): T[] {
/**
- * Remove value at path in a nested array.
- * @param x a nested array (updated)
+ * Remove value at path in a nested array!
+ * @param x a nested array (updated!)
* @param p path
* @returns x \\: [i₀][i₁][...] | [i₀, i₁, ...] = p
*/
@@ -483,12 +626,13 @@ export function removePath$(x: any[], p: number[]): any[] {
if (is(y)) y.splice(last(p), 1);
return x;
}
+// #endregion
-// PROPERTY
-// --------
+// #region PROPERTY
+// ----------------
/**
* Count values which satisfy a test.
@@ -505,12 +649,12 @@ export function count(x: T[], ft: TestFunction): number {
/**
- * Count occurrences of values.
+ * Count occurrences of each distinct value.
* @param x an array
* @param fm map function (v, i, x)
* @returns Map \{value ⇒ count\}
*/
-export function countAs(x: T[], fm: MapFunction | null=null): Map {
+export function countEach(x: T[], fm: MapFunction | null=null): Map {
var fm = fm || IDENTITY;
var i = -1, a = new Map();
for (var v of x) {
@@ -519,53 +663,58 @@ export function countAs(x: T[], fm: MapFunction | null=null): Ma
}
return a;
}
+export {countEach as countAs}; // DEPRECATED
/**
- * Find smallest value.
+ * Find first smallest value.
* @param x an array
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns v | v ≤ vᵢ; vᵢ ∈ x
*/
export function min(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): T {
- return rangeEntries(x, fc, fm)[0][1];
+ var i = searchMinimumValue(x, fc, fm);
+ return x[i];
}
/**
- * Find smallest entry.
+ * Find first smallest entry.
* @param x an array
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns [min_index, min_value]
*/
export function minEntry(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): [number, T] {
- return rangeEntries(x, fc, fm)[0];
+ var i = searchMinimumValue(x, fc, fm);
+ return [i, x[i]];
}
/**
- * Find largest value.
+ * Find first largest value.
* @param x an array
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns v | v ≥ vᵢ; vᵢ ∈ x
*/
export function max(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): T {
- return rangeEntries(x, fc, fm)[1][1];
+ var i = searchMaximumValue(x, fc, fm);
+ return x[i];
}
/**
- * Find largest entry.
+ * Find first largest entry.
* @param x an array
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns [max_index, max_value]
*/
export function maxEntry(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): [number, T] {
- return rangeEntries(x, fc, fm)[1];
+ var i = searchMaximumValue(x, fc, fm);
+ return [i, x[i]];
}
@@ -604,38 +753,13 @@ export function rangeEntries(x: T[], fc: CompareFunction | null=nul
}
return [[mi, mv], [ni, nv]];
}
+// #endregion
-// PART
-// ----
-
-/**
- * Get part of an array.
- * @param x an array
- * @param i start index [0]
- * @param I end index [|x|]
- * @returns x[i..I]
- */
-export function slice(x: T[], i: number=0, I: number=x.length): T[] {
- return x.slice(i, I);
-}
-
-
-/**
- * Get part of an array.
- * @param x an array (updated)
- * @param i start index [0]
- * @param I end index [|x|]
- * @returns x = x[i..I]
- */
-export function slice$(x: T[], i: number=0, I: number=x.length): T[] {
- x.copyWithin(0, i, I);
- x.length = length(x, i, I);
- return x;
-}
-
+// #region PART
+// ------------
/**
* Get first value.
@@ -662,6 +786,18 @@ export function last(x: T[], vd?: T): T {
export {last as back};
+/**
+ * Get values from middle.
+ * @param x an array
+ * @param i start index
+ * @param n number of values [1]
+ * @returns x[i..i+n]
+ */
+export function middle(x: T[], i: number, n: number=1): T[] {
+ return x.slice(i, i+n);
+}
+
+
/**
* Get values except first.
* @param x an array
@@ -683,14 +819,28 @@ export function init(x: T[]): T[] {
/**
- * Get values from middle.
+ * Get part of an array.
* @param x an array
- * @param i start index
- * @param n number of values [1]
- * @returns x[i..i+n]
+ * @param i start index [0]
+ * @param I end index [|x|]
+ * @returns x[i..I]
*/
-export function middle(x: T[], i: number, n: number=1): T[] {
- return x.slice(i, i+n);
+export function slice(x: T[], i: number=0, I: number=x.length): T[] {
+ return x.slice(i, I);
+}
+
+
+/**
+ * Get part of an array!
+ * @param x an array (updated!)
+ * @param i start index [0]
+ * @param I end index [|x|]
+ * @returns x = x[i..I]
+ */
+export function slice$(x: T[], i: number=0, I: number=x.length): T[] {
+ x.copyWithin(0, i, I);
+ x.length = length(x, i, I);
+ return x;
}
@@ -782,12 +932,24 @@ export function dropWhile(x: T[], ft: TestFunction): T[] {
export function dropWhileRight(x: T[], ft: TestFunction): T[] {
return x.slice(0, scanWhileRight(x, ft));
}
+// #endregion
-// ARRANGEMENTS
-// ------------
+// #region ARRANGEMENTS
+// --------------------
+
+/**
+ * Obtain all possible prefixes.
+ * @param x an array
+ * @param n number of values [-1 ⇒ any]
+ * @returns [[], x[..1], x[..2], ...] if n<0; [x[..n]] otherwise
+ */
+export function prefixes(x: T[], n: number=-1): T[][] {
+ return [...iprefixes(x, n)];
+}
+
/**
* List all possible prefixes.
@@ -795,7 +957,7 @@ export function dropWhileRight(x: T[], ft: TestFunction): T[] {
* @param n number of values [-1 ⇒ any]
* @returns [], x[..1], x[..2], ... if n<0; x[..n] otherwise
*/
-export function* prefixes(x: T[], n: number=-1): IterableIterator {
+export function* iprefixes(x: T[], n: number=-1): IterableIterator {
var X = x.length;
if (n>X) return;
if (n>=0) { yield x.slice(0, n); return; }
@@ -804,13 +966,24 @@ export function* prefixes(x: T[], n: number=-1): IterableIterator {
}
+/**
+ * Obtain all possible suffixes.
+ * @param x an array
+ * @param n number of values [-1 ⇒ any]
+ * @returns [x[0..], x[1..], x[2..], ...] if n<0; [x[-n..]] otherwise
+ */
+export function suffixes(x: T[], n: number=-1): T[][] {
+ return [...isuffixes(x, n)];
+}
+
+
/**
* List all possible suffixes.
* @param x an array
* @param n number of values [-1 ⇒ any]
* @returns x[0..], x[1..], x[2..], ... if n<0; x[-n..] otherwise
*/
-export function* suffixes(x: T[], n: number=-1): IterableIterator {
+export function* isuffixes(x: T[], n: number=-1): IterableIterator {
var X = x.length;
if (n>X) return;
if (n>=0) { yield x.slice(x.length - n); return; }
@@ -819,13 +992,24 @@ export function* suffixes(x: T[], n: number=-1): IterableIterator {
}
+/**
+ * Obtain all possible infixes.
+ * @param x an array
+ * @param n number of values [-1 ⇒ any]
+ * @returns [[], x[0..1], x[0..2], ..., x[1..2], ...] if n<0; [only of length n] otherwise
+ */
+export function infixes(x: T[], n: number=-1): T[][] {
+ return [...iinfixes(x, n)];
+}
+
+
/**
* List all possible infixes.
* @param x an array
* @param n number of values [-1 ⇒ any]
* @returns [], x[0..1], x[0..2], ..., x[1..2], ... if n<0; only of length n otherwise
*/
-export function infixes(x: T[], n: number=-1): IterableIterator {
+export function iinfixes(x: T[], n: number=-1): IterableIterator {
if (n>=0) return infixesFixed(x, n);
else return infixesAll(x);
}
@@ -847,47 +1031,69 @@ function* infixesAll(x: T[]): IterableIterator {
}
+/**
+ * Obtain all possible subsequences.
+ * @param x an array
+ * @param n number of values [-1 ⇒ any]
+ * @returns [elements selected by bit from 0..2^|x|] if n<0; [only of length n] otherwise
+ */
+export function subsequences(x: T[], n: number=-1): T[][] {
+ return [...isubsequences(x, n)];
+}
+
+
/**
* List all possible subsequences.
* @param x an array
* @param n number of values [-1 ⇒ any]
* @returns elements selected by bit from 0..2^|x| if n<0; only of length n otherwise
*/
-export function* subsequences(x: T[], n: number=-1): IterableIterator {
+export function* isubsequences(x: T[], n: number=-1): IterableIterator {
var X = x.length;
if (n>X) return;
if (n===X) { yield x; return; }
if (n===0 || X===0) { yield []; return; }
var y = x.slice(0, -1);
- yield* subsequences(y, n);
- for (var s of subsequences(y, n-1)) {
+ yield* isubsequences(y, n);
+ for (var s of isubsequences(y, n-1)) {
s.push(x[X-1]);
yield s;
}
}
+/**
+ * Obtain all possible permutations.
+ * @param x an array
+ * @param n number of values [-1 ⇒ any]
+ * @returns [[], arrangements of length 1, of length 2, ...] if n<0; [only of length n] otherwise
+ */
+export function permutations(x: T[], n: number=-1): T[][] {
+ return [...ipermutations(x, n)];
+}
+
+
/**
* List all possible permutations.
* @param x an array
* @param n number of values [-1 ⇒ any]
* @returns [], arrangements of length 1, of length 2, ... if n<0; only of length n otherwise
*/
-export function* permutations(x: T[], n: number=-1): IterableIterator {
+export function* ipermutations(x: T[], n: number=-1): IterableIterator {
var X = x.length;
if (n>X) return;
var i = n<0? 0 : n;
var I = n<0? X : n
for (; i<=I; ++i)
- yield* permutationsFixed(x, i);
+ yield* ipermutationsFixed(x, i);
}
-function* permutationsFixed(x: T[], n: number): IterableIterator {
+function* ipermutationsFixed(x: T[], n: number): IterableIterator {
var X = x.length;
if (X===0 || n===0) { yield []; return; }
for (var i=0; i(x: T[], n: number=-1, fr: ReadFunction(x: T[], ft: TestFunction): number {
export function search(x: T[], ft: TestFunction): number {
return x.findIndex(ft);
}
+export {search as findIndex};
/**
@@ -1169,6 +1378,7 @@ export function searchRight(x: T[], ft: TestFunction): number {
if (ft(x[i], i, x)) return i;
return -1;
}
+export {searchRight as findLastIndex};
/**
@@ -1246,6 +1456,116 @@ export function searchValueAll(x: T[], v: T, fc: CompareFunction |
}
+/**
+ * Find first index of minimum value.
+ * @param x an array
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @returns first index of minimum value, -1 if empty
+ */
+export function searchMinimumValue(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length;
+ if (X===0) return -1;
+ var mi = 0, mw = fm(x[0], 0, x);
+ for (var i=1; i(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length;
+ if (X===0) return -1;
+ var ni = 0, nw = fm(x[0], 0, x);
+ for (var i=1; i0) { ni = i; nw = w; }
+ }
+ return ni;
+}
+
+
+/**
+ * Find first index of an unsorted value.
+ * @param x an array
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @returns index of first unsorted value, -1 if sorted
+ */
+export function searchUnsortedValue(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length;
+ if (X<=1) return -1;
+ var w0 = fm(x[0], 0, x);
+ for (var i=1; i0) return i;
+ w0 = w;
+ }
+ return -1;
+}
+
+
+/**
+ * Find first index of an adjacent duplicate value.
+ * @param x an array
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @returns index of first adjacent duplicate value, -1 if none
+ */
+export function searchAdjacentDuplicateValue(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length;
+ if (X<=1) return -1;
+ var w0 = fm(x[0], 0, x);
+ for (var i=1; i(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length;
+ var Y = y.length;
+ for (var i=0, I=Math.min(X, Y); i(x: T[], v: T, fc: CompareFunction |
* @returns first i | x[i..i+|y|] = y else -1
*/
export function searchInfix(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
- for (var i of iterableSearchInfixAll(x, y, fc, fm))
- return i;
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length, Y = y.length;
+ for (var i=0; i<=X-Y; ++i)
+ if (isInfixAt(x, y, i, fc, fm)) return i;
return -1;
}
@@ -1270,10 +1593,12 @@ export function searchInfix(x: T[], y: T[], fc: CompareFunction | n
* @returns first i | x[i..i+|y|] = y else -1
*/
export function searchInfixRight(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
- var a = -1;
- for (var i of iterableSearchInfixAll(x, y, fc, fm))
- a = i;
- return a;
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length, Y = y.length;
+ for (var i=X-Y; i>=0; --i)
+ if (isInfixAt(x, y, i, fc, fm)) return i;
+ return -1;
}
@@ -1286,7 +1611,23 @@ export function searchInfixRight(x: T[], y: T[], fc: CompareFunction(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number[] {
- return [...iterableSearchInfixAll(x, y, fc, fm)];
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length, Y = y.length, a = [];
+ for (var i=0; i<=X-Y; ++i)
+ if (isInfixAt(x, y, i, fc, fm)) a.push(i);
+ return a;
+}
+
+
+function isInfixAt(x: T[], y: T[], i: number, fc: CompareFunction, fm: MapFunction): boolean {
+ var Y = y.length;
+ for (var j=0; j(x: T[], y: T[], fc: CompareFunction(x: T[], v: T, fc: CompareFunction | null=n
/**
- * Check if array starts with a prefix.
+ * Examine if array has an unsorted value.
+ * @param x an array
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @returns x is not sorted?
+ */
+export function hasUnsortedValue(x: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
+ return searchUnsortedValue(x, fc, fm) >= 0;
+}
+
+
+/**
+ * Examine if array starts with a prefix.
* @param x an array
* @param y search prefix
* @param fc compare function (a, b)
@@ -1338,10 +1691,11 @@ export function hasPrefix(x: T[], y: T[], fc: CompareFunction | nul
var Y = y.length;
return Y===0 || compare(x.slice(0, Y), y, fc, fm)===0;
}
+export {hasPrefix as startsWith};
/**
- * Check if array ends with a suffix.
+ * Examine if array ends with a suffix.
* @param x an array
* @param y search suffix
* @param fc compare function (a, b)
@@ -1352,10 +1706,11 @@ export function hasSuffix(x: T[], y: T[], fc: CompareFunction | nul
var Y = y.length;
return Y===0 || compare(x.slice(-Y), y, fc, fm)===0;
}
+export {hasSuffix as endsWith};
/**
- * Check if array contains an infix.
+ * Examine if array contains an infix.
* @param x an array
* @param y search infix
* @param fc compare function (a, b)
@@ -1368,37 +1723,81 @@ export function hasInfix(x: T[], y: T[], fc: CompareFunction | null
/**
- * Check if array has a subsequence.
+ * Examine if array has a subsequence.
+ * @param x an array
+ * @param y search subsequence
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @returns x[i₀] ⧺ x[i₁] ⧺ ... = y, for some i₀, i₁, ...? | i₀ < i₁ < ...
+ */
+export function hasSubsequence(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
+ return searchSubsequence(x, y, fc, fm) >= 0;
+}
+
+
+/**
+ * Examine if array has a permutation.
+ * @param x an array
+ * @param y search permutation
+ * @param fc map function (v, i, x)
+ * @param fm compare function (a, b)
+ * @returns x contains a shuffled version of y?
+ */
+export function hasPermutation(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
+ var x1 = fm? x.map(fm) : x.slice();
+ var y1 = fm? y.map(fm) : y.slice();
+ return hasSubsequence(x1.sort(), y1.sort(), fc, fm);
+}
+// #endregion
+
+
+
+
+// #region COMPARE
+// ---------------
+
+/**
+ * Compare two arrays (lexicographically).
+ * @param x an array
+ * @param y another array
+ * @param fc compare function (a, b)
+ * @param fm map function (v, i, x)
+ * @returns xy: +ve
+ */
+export function compare(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): number {
+ var fc = fc || COMPARE;
+ var fm = fm || IDENTITY;
+ var X = x.length;
+ var Y = y.length;
+ for (var i=0, I=Math.min(X, Y); i(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
- return searchSubsequence(x, y, fc, fm) >= 0;
-}
-
-
-/**
- * Check if array has a permutation.
- * @param x an array
- * @param y search permutation
- * @param fc map function (v, i, x)
- * @param fm compare function (a, b)
- * @returns x contains a shuffled version of y?
+ * @returns x = y?
*/
-export function hasPermutation(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
- var x1 = fm? x.map(fm) : x.slice();
- var y1 = fm? y.map(fm) : y.slice();
- return hasSubsequence(x1.sort(), y1.sort(), fc, fm);
+export function isEqual(x: T[], y: T[], fc: CompareFunction | null=null, fm: MapFunction | null=null): boolean {
+ var X = x.length, Y = y.length;
+ return X===Y && compare(x, y, fc, fm)===0;
}
+// #endregion
-// FUNCTIONAL
-// ----------
+// #region FUNCTIONAL
+// ------------------
/**
* Call a function for each value.
@@ -1411,7 +1810,7 @@ export function forEach(x: T[], fp: ProcessFunction): void {
/**
- * Check if any value satisfies a test.
+ * Examine if any value satisfies a test.
* @param x an array
* @param ft test function (v, i, x)
* @returns true if ft(vᵢ) = true for some vᵢ ∈ x
@@ -1430,7 +1829,7 @@ function someBoolean(x: T[]): boolean {
/**
- * Check if all values satisfy a test.
+ * Examine if all values satisfy a test.
* @param x an array
* @param ft test function (v, i, x)
* @returns true if ft(vᵢ) = true for all vᵢ ∈ x
@@ -1460,8 +1859,8 @@ export function map(x: T[], fm: MapFunction): (T|U)[] {
/**
- * Transform values of an array.
- * @param x an array (updated)
+ * Transform values of an array!
+ * @param x an array (updated!)
* @param fm map function (v, i, x)
* @returns x = [fm(v₀), fm(v₁), ...]; vᵢ ∈ x
*/
@@ -1502,6 +1901,109 @@ export function reduceRight