Repository: marpple/FxTS
Pull request #325 (2025-06-13 11:38:09)

fix: Improve `when` function's type safety for type guard predicates
**This PR enhances the `when` utility by correcting its return type signature** when used with a type guard predicate, significantly improving its type safety and predictability.

## The Problem
**This issue stems from a fundamental aspect of TypeScript's design: type checking occurs at compile-time without executing the code.** The type system cannot predict the runtime outcome of the predicate function (whether it will return `true` or `false`). **Therefore, a function's type signature must correctly account for all possible return paths.**
The previous signature for when with a type guard `((input: T) => input is S)` incorrectly returned `Exclude<T, S>`. This signature only described the outcome for a `false` predicate, creating a serious mismatch when the predicate was `true` at runtime.
For example, with the old signature:
```ts
type Shape = { type: "circle"; r: number } | { type: "square"; s: number };
const myShape: Shape = { type: "circle", r: 10 };

const result = when(
  (s): s is { type: "circle"; r: number } => s.type === "circle",
  (circle) => `Area: ${Math.PI * circle.r ** 2}`, // Returns a string (R)
  myShape
);

// At runtime, `result` is the string "Area: 314.15..."
// BUT, at compile-time, TypeScript would incorrectly infer the type of `result` as { type: "square", s: number }.
// This would lead to compile errors on valid operations (e.g. `result.toUpperCase()`)
// and allow invalid operations that would fail at runtime (e.g. `result.s`).
```

## The Solution
**The function's overloads have been updated to return `R | Exclude<T, S>`. This signature correctly represents all possible outcomes**:
`R`: The result of the callback function if the predicate is `true`.
`Exclude<T, S>`: The original value with its type narrowed to exclude `S` if the predicate is `false`.
This change makes the function's type signature "honest," **aligning the static type with the actual runtime behavior**.

## Testing
To support this change:
Type-check tests (`type-check/when.test.ts`) have been added to verify that the compiler correctly infers the new, more accurate `R | Exclude<T, S>` union type.
Runtime tests (`test/when.spec.ts`) have been added to confirm that the function behaves as expected with type guards, returning the correct value in both `true` and `false` scenarios.


Patch:
diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml
index 3bb8b65b..7ec7a198 100644
--- a/.github/workflows/website.yml
+++ b/.github/workflows/website.yml
@@ -8,13 +8,12 @@ jobs:
       - uses: actions/setup-node@v2
         with:
           node-version: 18.x
-          cache: npm
       - name: Build website
         working-directory: website
         run: |
           npm ci
-          npm install -g @microsoft/api-extractor@7.20.0
-          npm install -g @microsoft/api-documenter@7.20.0
+          npm install -g @microsoft/api-extractor@7.52.6
+          npm install -g @microsoft/api-documenter@7.26.26
           make all
           npm run build
       - name: Deploy to GitHub Pages
diff --git a/package-lock.json b/package-lock.json
index c685f6e3..852ed2c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "@fxts/core",
-  "version": "1.12.0",
+  "version": "1.13.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "@fxts/core",
-      "version": "1.12.0",
+      "version": "1.13.2",
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.0"
diff --git a/package.json b/package.json
index 69996ff2..9b937a2f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@fxts/core",
-  "version": "1.12.0",
+  "version": "1.13.2",
   "description": "A functional library for TypeScript/JavaScript programmers.",
   "main": "dist/cjs/index.js",
   "module": "dist/esm/index.js",
diff --git a/src/Lazy/concurrentPool.ts b/src/Lazy/concurrentPool.ts
index c77622d9..065aa45c 100644
--- a/src/Lazy/concurrentPool.ts
+++ b/src/Lazy/concurrentPool.ts
@@ -21,7 +21,7 @@ type Item<T> = {
  *   map((a) => delay(100 * a, a)),
  *   concurrentPool(3),
  *   each(console.log), // log 1, 2, 3, 4, 5, 6
- * ); // 2 seconds
+ * ); // 0.9 seconds
  * ```
  */
 function concurrentPool<A>(
diff --git a/src/Lazy/index.ts b/src/Lazy/index.ts
index a0093060..a1789260 100644
--- a/src/Lazy/index.ts
+++ b/src/Lazy/index.ts
@@ -38,6 +38,7 @@ import takeUntil from "./takeUntil";
 import takeUntilInclusive from "./takeUntilInclusive";
 import takeWhile from "./takeWhile";
 import toAsync from "./toAsync";
+import transpose from "./transpose";
 import uniq from "./uniq";
 import uniqBy from "./uniqBy";
 import values from "./values";
@@ -89,6 +90,7 @@ export {
   toAsync,
   uniq,
   uniqBy,
+  transpose,
   values,
   zip,
   zipWith,
diff --git a/src/Lazy/transpose.ts b/src/Lazy/transpose.ts
new file mode 100644
index 00000000..5b293678
--- /dev/null
+++ b/src/Lazy/transpose.ts
@@ -0,0 +1,137 @@
+import { isAsyncIterable, isIterable, toIterator } from "../_internal/utils";
+import isUndefined from "../isUndefined";
+import max from "../max";
+import nth from "../nth";
+import pipe from "../pipe";
+import size from "../size";
+import toArray from "../toArray";
+import type ReturnZipType from "../types/ReturnZipType";
+import type { UniversalIterable } from "../types/Utils";
+import filter from "./filter";
+import map from "./map";
+import toAsync from "./toAsync";
+
+function* sync(
+  iterable: Iterable<Iterable<unknown>>,
+): IterableIterator<Iterable<unknown>> {
+  const maxLen = pipe(iterable, map(size), max);
+
+  for (let index = 0; index < maxLen; index++) {
+    yield pipe(
+      iterable,
+      map(nth(index)),
+      filter((value) => !isUndefined(value)),
+      toArray,
+    );
+  }
+}
+
+function async(
+  iterable: Iterable<UniversalIterable>,
+): AsyncIterableIterator<UniversalIterable> {
+  const iterators = toArray(map(toIterator, iterable as any));
+
+  return {
+    [Symbol.asyncIterator]() {
+      return this;
+    },
+    async next(_concurrent) {
+      const headIterators = await pipe(
+        toAsync(iterators),
+        map((iterator) => iterator.next(_concurrent)),
+        toArray,
+      );
+
+      const done = headIterators.every(({ done }) => done);
+
+      if (done) return { done: true, value: undefined };
+
+      return {
+        done: false,
+        value: pipe(
+          headIterators,
+          map(({ value }) => value),
+          filter((value) => !isUndefined(value)),
+          toArray,
+        ),
+      };
+    },
+  };
+}
+
+/**
+ * The transpose function takes multiple iterators as input and returns a transposed 2D array—swapping rows with columns.
+ *
+ * Unlike the existing zip function, transpose behaves as shown in the example below:
+ *
+ * @example
+ * ```ts
+ * const iter = transpose([1, 'a'], [2, 'b'], [3, 'c']);
+ * iter.next() // {done:false, value: [1, 2, 3]}
+ * iter.next() // {done:false, value: ['a', 'b', 'c']}
+ * iter.next() // {done:true, value: undefined}
+ *
+ * const iter = transpose([1, 2, 3], ['a', 'b', 'c']);
+ * iter.next() // {done:false, value: [1, 'a']}
+ * iter.next() // {done:false, value: [2, 'b']}
+ * iter.next() // {done:false, value: [3, 'c']}
+ * iter.next() // {done:true, value: undefined}
+ *
+ * // How transpose differs from `zip`
+ * const iter = zip([1, 2], [3], [], [4, 5, 6], [7], [8, 9]);
+ * iter.next() // {done:true, value: undefined}
+ * // Because zip stops at the shortest input, passing an empty array causes it to exit immediately.
+ *
+ * // with pipe
+ * pipe(
+ *   [4, 5, 6, 7],
+ *   transpose([1, 2, 3]),
+ *   toArray,
+ * ) // [[ 1, 4 ], [ 2, 5 ], [ 3, 6 ], [7]]
+ *
+ * pipe(
+ *   Promise.resolve([4, 5, 6, 7]),
+ *   transpose([1, 2, 3]),
+ *   toArray,
+ * ) // [[ 1, 4 ], [ 2, 5 ], [ 3, 6 ], [7]]
+ *
+ * // with toAsync
+ * pipe(
+ *   [Promise.resolve(4), Promise.resolve(5), Promise.resolve(6), Promise.resolve(7)],
+ *   toAsync,
+ *   transpose([1, 2, 3]),
+ *   toArray,
+ * ) // [[ 1, 4 ], [ 2, 5 ], [ 3, 6 ], [7]]
+ * ```
+ */
+
+function transpose<T extends UniversalIterable, R extends UniversalIterable[]>(
+  iterables: T,
+): (...args: R) => ReturnZipType<[T, ...R]>;
+function transpose<T extends UniversalIterable[]>(
+  ...args: T
+): ReturnZipType<[...T]>;
+
+function transpose<R extends UniversalIterable[]>(...iterables: R[]) {
+  if (size(iterables) < 2)
+    return (...args: UniversalIterable[]) =>
+      transpose(...iterables, ...args) as ReturnZipType<R>;
+
+  if (
+    iterables.some((value) => !isIterable(value) && !isAsyncIterable(value))
+  ) {
+    throw new TypeError("'iterable' must be type of Iterable or AsyncIterable");
+  }
+
+  const hasAsyncIterable = iterables.some((iterable) =>
+    isAsyncIterable(iterable),
+  );
+
+  if (hasAsyncIterable) {
+    return async(iterables) as ReturnZipType<R>;
+  }
+
+  return sync(iterables);
+}
+
+export default transpose;
diff --git a/src/Util/debounce.ts b/src/Util/debounce.ts
new file mode 100644
index 00000000..d31f4168
--- /dev/null
+++ b/src/Util/debounce.ts
@@ -0,0 +1,68 @@
+/**
+ * `debounce` function is used to delay the execution of a provided function until after a specified time period has passed since the last time the debounced function was invoked.
+ * The function is useful to optimize performance by limiting the rate at which a function is executed, especially in scenarios like handling user input events, scrolling, or resizing.
+ * Additionally, the debounce function allows you to execute the function immediately on the first call (when leading is set to true), and it can be canceled manually using the `.cancel()` method.
+ *
+ * @example
+ * ```ts
+ * const debounced1 = debounce((val: number)=>{
+ *   console.log('val', val);
+ * }, 100);
+ *
+ * debounced1();
+ * debounced1();
+ * debounced1(); // invoke func after 100ms
+ *
+ * const debounced2 = debounce((val: number)=>{
+ *   console.log('val', val);
+ * }, 100, { leading:true });
+ * debounced2(); // immediately invoked func
+ * debounced2();
+ * debounced2(); // invoked func after 100ms
+ * 
+ 
+ * const debounced3 = debounce((val: number)=>{
+ *   console.log('val', val);
+ * }, 100);
+ * debounced3();
+ * debounced3();
+ * debounced3.cancel(); // cancel func
+ * ```
+ */
+function debounce<T extends (...args: any[]) => void>(
+  func: T,
+  wait: number,
+  options = { leading: false },
+): ((...args: Parameters<T>) => void) & { cancel: () => void } {
+  let timeoutId: ReturnType<typeof setTimeout> | undefined;
+
+  const debounced = function (...args: Parameters<T>) {
+    const callNow = options.leading && !timeoutId;
+
+    if (timeoutId) {
+      clearTimeout(timeoutId);
+    }
+
+    timeoutId = setTimeout(() => {
+      timeoutId = undefined;
+      if (!options.leading) {
+        func(...args);
+      }
+    }, wait);
+
+    if (callNow) {
+      func(...args);
+    }
+  };
+
+  debounced.cancel = () => {
+    if (timeoutId) {
+      clearTimeout(timeoutId);
+      timeoutId = undefined;
+    }
+  };
+
+  return debounced;
+}
+
+export default debounce;
diff --git a/src/Util/index.ts b/src/Util/index.ts
new file mode 100644
index 00000000..6e0b3583
--- /dev/null
+++ b/src/Util/index.ts
@@ -0,0 +1,3 @@
+import debounce from "./debounce";
+
+export { debounce };
diff --git a/src/index.ts b/src/index.ts
index 7921b402..ff0496aa 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -141,3 +141,4 @@ export {
 };
 
 export * from "./Lazy/index";
+export * from "./Util/index";
diff --git a/src/isArray.ts b/src/isArray.ts
index af728e4f..4fd42483 100644
--- a/src/isArray.ts
+++ b/src/isArray.ts
@@ -7,7 +7,8 @@
  * isArray(2); // false
  * ```
  */
-const isArray = <T>(input: T): input is T & (unknown[] | Readonly<unknown[]>) =>
-  Array.isArray(input);
+const isArray = <T>(
+  input: T,
+): input is Extract<T, unknown[] | Readonly<unknown[]>> => Array.isArray(input);
 
 export default isArray;
diff --git a/src/when.ts b/src/when.ts
index 3f9ef38b..e95ffe61 100644
--- a/src/when.ts
+++ b/src/when.ts
@@ -43,7 +43,7 @@ import isUndefined from "./isUndefined";
 function when<T, S extends T, R>(
   predicate: (input: T) => input is S,
   callback: (input: S) => R,
-): (a: T) => Exclude<T, S>;
+): (a: T) => R | Exclude<T, S>;
 function when<T, R>(
   predicate: (input: T) => boolean,
   callback: (input: T) => R,
@@ -52,7 +52,7 @@ function when<T, S extends T, R>(
   predicate: (input: T) => input is S,
   callback: (input: S) => R,
   a: T,
-): Exclude<T, S>;
+): R | Exclude<T, S>;
 function when<T, R>(
   predicate: (input: T) => boolean,
   callback: (input: T) => R,
diff --git a/website/README.md b/website/README.md
index 1be0873f..99c6c452 100644
--- a/website/README.md
+++ b/website/README.md
@@ -4,11 +4,11 @@
 
 - api-extractor
   ```
-  npm install -g @microsoft/api-extractor@7.20.0
+  npm install -g @microsoft/api-extractor@7.52.6
   ```
 - api-documenter
   ```
-  npm install -g @microsoft/api-documenter@7.20.0
+  npm install -g @microsoft/api-documenter@7.26.26
   ```
 
 ## Install / Update plugin markdown-plugin
diff --git a/website/function.json b/website/function.json
index bed8e42c..fbe81116 100644
--- a/website/function.json
+++ b/website/function.json
@@ -39,6 +39,7 @@
     "takeUntilInclusive",
     "takeWhile",
     "toAsync",
+    "transpose",
     "uniq",
     "uniqBy",
     "values",
@@ -112,5 +113,6 @@
     "unicodeToArray",
     "unless",
     "when"
-  ]
+  ],
+  "Util": ["debounce"]
 }
diff --git a/website/markdown-plugin/package-lock.json b/website/markdown-plugin/package-lock.json
index 71a400a8..7ef46a5c 100644
--- a/website/markdown-plugin/package-lock.json
+++ b/website/markdown-plugin/package-lock.json
@@ -9,7 +9,7 @@
       "version": "1.0.0",
       "license": "MIT",
       "dependencies": {
-        "@microsoft/api-documenter": "^7.13.63",
+        "@microsoft/api-documenter": "7.26.26",
         "@microsoft/api-extractor-model": "^7.13.13",
         "@microsoft/tsdoc": "^0.13.2"
       },
@@ -18,111 +18,160 @@
       }
     },
     "node_modules/@microsoft/api-documenter": {
-      "version": "7.13.63",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.13.63.tgz",
-      "integrity": "sha512-NIg9IEHBcVG7yPhLYVmKGvL6TmNXzUM1lKaUTroEx/qj+fw/PU1PuMUAb8k2D8zySq6Y5x8zAjbURXeqkW8NzQ==",
+      "version": "7.26.26",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.26.26.tgz",
+      "integrity": "sha512-085FwdwQcXGvwtMJFajwhu5eZOQ3PXsyLIoq3WXAQr/7M6Vn59GMGjuB/+lIXqmWKkxzeFAX5f9sKqr9X7zI3g==",
+      "license": "MIT",
       "dependencies": {
-        "@microsoft/api-extractor-model": "7.13.13",
-        "@microsoft/tsdoc": "0.13.2",
-        "@rushstack/node-core-library": "3.42.3",
-        "@rushstack/ts-command-line": "4.10.2",
-        "colors": "~1.2.1",
+        "@microsoft/api-extractor-model": "7.30.6",
+        "@microsoft/tsdoc": "~0.15.1",
+        "@rushstack/node-core-library": "5.13.1",
+        "@rushstack/terminal": "0.15.3",
+        "@rushstack/ts-command-line": "5.0.1",
         "js-yaml": "~3.13.1",
-        "resolve": "~1.17.0"
+        "resolve": "~1.22.1"
       },
       "bin": {
         "api-documenter": "bin/api-documenter"
       }
     },
+    "node_modules/@microsoft/api-documenter/node_modules/@microsoft/tsdoc": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+      "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==",
+      "license": "MIT"
+    },
     "node_modules/@microsoft/api-extractor-model": {
-      "version": "7.13.13",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.13.tgz",
-      "integrity": "sha512-4Hz2TOL4TljsAfMQe7a8tm+Am8+AkrcgkbnH62S9YuaIC3Cw6jE4H2qP8WC2JJInWJP4pg/ZrUlHrtmtgrqn9Q==",
+      "version": "7.30.6",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.6.tgz",
+      "integrity": "sha512-znmFn69wf/AIrwHya3fxX6uB5etSIn6vg4Q4RB/tb5VDDs1rqREc+AvMC/p19MUN13CZ7+V/8pkYPTj7q8tftg==",
+      "license": "MIT",
       "dependencies": {
-        "@microsoft/tsdoc": "0.13.2",
-        "@microsoft/tsdoc-config": "~0.15.2",
-        "@rushstack/node-core-library": "3.42.3"
+        "@microsoft/tsdoc": "~0.15.1",
+        "@microsoft/tsdoc-config": "~0.17.1",
+        "@rushstack/node-core-library": "5.13.1"
       }
     },
+    "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+      "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==",
+      "license": "MIT"
+    },
     "node_modules/@microsoft/tsdoc": {
       "version": "0.13.2",
       "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz",
       "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg=="
     },
     "node_modules/@microsoft/tsdoc-config": {
-      "version": "0.15.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz",
-      "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz",
+      "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==",
+      "license": "MIT",
       "dependencies": {
-        "@microsoft/tsdoc": "0.13.2",
-        "ajv": "~6.12.6",
+        "@microsoft/tsdoc": "0.15.1",
+        "ajv": "~8.12.0",
         "jju": "~1.4.0",
-        "resolve": "~1.19.0"
+        "resolve": "~1.22.2"
       }
     },
-    "node_modules/@microsoft/tsdoc-config/node_modules/resolve": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
-      "dependencies": {
-        "is-core-module": "^2.1.0",
-        "path-parse": "^1.0.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
+    "node_modules/@microsoft/tsdoc-config/node_modules/@microsoft/tsdoc": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+      "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==",
+      "license": "MIT"
     },
     "node_modules/@rushstack/node-core-library": {
-      "version": "3.42.3",
-      "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.42.3.tgz",
-      "integrity": "sha512-xtiJsHtO4Sf/hVKyf/8d58p3zQh2JAZNs1mmDNCyIlgSRYGdqUkpadvvn5mz7EwF6lwn+xTTaTV5/a32xKjbdw==",
+      "version": "5.13.1",
+      "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz",
+      "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==",
+      "license": "MIT",
       "dependencies": {
-        "@types/node": "12.20.24",
-        "colors": "~1.2.1",
-        "fs-extra": "~7.0.1",
+        "ajv": "~8.13.0",
+        "ajv-draft-04": "~1.0.0",
+        "ajv-formats": "~3.0.1",
+        "fs-extra": "~11.3.0",
         "import-lazy": "~4.0.0",
         "jju": "~1.4.0",
-        "resolve": "~1.17.0",
-        "semver": "~7.3.0",
-        "timsort": "~0.3.0",
-        "z-schema": "~3.18.3"
+        "resolve": "~1.22.1",
+        "semver": "~7.5.4"
+      },
+      "peerDependencies": {
+        "@types/node": "*"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
       }
     },
-    "node_modules/@rushstack/node-core-library/node_modules/@types/node": {
-      "version": "12.20.24",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz",
-      "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ=="
+    "node_modules/@rushstack/node-core-library/node_modules/ajv": {
+      "version": "8.13.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz",
+      "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2",
+        "uri-js": "^4.4.1"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/@rushstack/terminal": {
+      "version": "0.15.3",
+      "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.3.tgz",
+      "integrity": "sha512-DGJ0B2Vm69468kZCJkPj3AH5nN+nR9SPmC0rFHtzsS4lBQ7/dgOwtwVxYP7W9JPDMuRBkJ4KHmWKr036eJsj9g==",
+      "license": "MIT",
+      "dependencies": {
+        "@rushstack/node-core-library": "5.13.1",
+        "supports-color": "~8.1.1"
+      },
+      "peerDependencies": {
+        "@types/node": "*"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
     },
     "node_modules/@rushstack/ts-command-line": {
-      "version": "4.10.2",
-      "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.2.tgz",
-      "integrity": "sha512-Weq8B7oJeCQ4ITsaVLhOQombipyg+idpkdkhA6UqLtKvuzq8zTtPpAfhP5ff5L+RCmo1CFCVOBE3i+MvzUR5vA==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.1.tgz",
+      "integrity": "sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==",
+      "license": "MIT",
       "dependencies": {
+        "@rushstack/terminal": "0.15.3",
         "@types/argparse": "1.0.38",
         "argparse": "~1.0.9",
-        "colors": "~1.2.1",
         "string-argv": "~0.3.1"
       }
     },
     "node_modules/@types/argparse": {
       "version": "1.0.38",
       "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
-      "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA=="
+      "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==",
+      "license": "MIT"
     },
     "node_modules/@types/node": {
       "version": "16.11.2",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.2.tgz",
       "integrity": "sha512-w34LtBB0OkDTs19FQHXy4Ig/TOXI4zqvXS2Kk1PAsRKZ0I+nik7LlMYxckW0tSNGtvWmzB+mrCTbuEjuB9DVsw==",
-      "dev": true
+      "devOptional": true
     },
     "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "version": "8.12.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+      "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+      "license": "MIT",
       "dependencies": {
         "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2",
         "uri-js": "^4.2.2"
       },
       "funding": {
@@ -130,6 +179,37 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
+    "node_modules/ajv-draft-04": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
+      "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
+      "license": "MIT",
+      "peerDependencies": {
+        "ajv": "^8.5.0"
+      },
+      "peerDependenciesMeta": {
+        "ajv": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/ajv-formats": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+      "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ajv": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -138,20 +218,6 @@
         "sprintf-js": "~1.0.2"
       }
     },
-    "node_modules/colors": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz",
-      "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==",
-      "engines": {
-        "node": ">=0.1.90"
-      }
-    },
-    "node_modules/commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "optional": true
-    },
     "node_modules/esprima": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@@ -167,61 +233,78 @@
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "license": "MIT"
     },
     "node_modules/fs-extra": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
-      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+      "version": "11.3.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+      "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+      "license": "MIT",
       "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
       },
       "engines": {
-        "node": ">=6 <7 || >=8"
+        "node": ">=14.14"
       }
     },
     "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
     "node_modules/graceful-fs": {
-      "version": "4.2.8",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "license": "ISC"
     },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "license": "MIT",
       "dependencies": {
-        "function-bind": "^1.1.1"
+        "function-bind": "^1.1.2"
       },
       "engines": {
-        "node": ">= 0.4.0"
+        "node": ">= 0.4"
       }
     },
     "node_modules/import-lazy": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
       "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
-      "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
+      "version": "2.16.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+      "license": "MIT",
       "dependencies": {
-        "has": "^1.0.3"
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -230,7 +313,8 @@
     "node_modules/jju": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
-      "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo="
+      "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
+      "license": "MIT"
     },
     "node_modules/js-yaml": {
       "version": "3.13.1",
@@ -245,32 +329,28 @@
       }
     },
     "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "license": "MIT"
     },
     "node_modules/jsonfile": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "license": "MIT",
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
       "optionalDependencies": {
         "graceful-fs": "^4.1.6"
       }
     },
-    "node_modules/lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
-    },
-    "node_modules/lodash.isequal": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
-    },
     "node_modules/lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
       "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "license": "ISC",
       "dependencies": {
         "yallist": "^4.0.0"
       },
@@ -281,31 +361,52 @@
     "node_modules/path-parse": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "license": "MIT"
     },
     "node_modules/punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+      "license": "MIT",
       "engines": {
         "node": ">=6"
       }
     },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/resolve": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
-      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "version": "1.22.10",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+      "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+      "license": "MIT",
       "dependencies": {
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.16.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.5.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "license": "ISC",
       "dependencies": {
         "lru-cache": "^6.0.0"
       },
@@ -322,87 +423,103 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
     },
     "node_modules/string-argv": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
-      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+      "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+      "license": "MIT",
       "engines": {
         "node": ">=0.6.19"
       }
     },
-    "node_modules/timsort": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
-      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
+    "node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
     "node_modules/universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "license": "MIT",
       "engines": {
-        "node": ">= 4.0.0"
+        "node": ">= 10.0.0"
       }
     },
     "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
       "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "license": "BSD-2-Clause",
       "dependencies": {
         "punycode": "^2.1.0"
       }
     },
-    "node_modules/validator": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz",
-      "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==",
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
     "node_modules/yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-    },
-    "node_modules/z-schema": {
-      "version": "3.18.4",
-      "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz",
-      "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==",
-      "dependencies": {
-        "lodash.get": "^4.0.0",
-        "lodash.isequal": "^4.0.0",
-        "validator": "^8.0.0"
-      },
-      "bin": {
-        "z-schema": "bin/z-schema"
-      },
-      "optionalDependencies": {
-        "commander": "^2.7.1"
-      }
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "license": "ISC"
     }
   },
   "dependencies": {
     "@microsoft/api-documenter": {
-      "version": "7.13.63",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.13.63.tgz",
-      "integrity": "sha512-NIg9IEHBcVG7yPhLYVmKGvL6TmNXzUM1lKaUTroEx/qj+fw/PU1PuMUAb8k2D8zySq6Y5x8zAjbURXeqkW8NzQ==",
+      "version": "7.26.26",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.26.26.tgz",
+      "integrity": "sha512-085FwdwQcXGvwtMJFajwhu5eZOQ3PXsyLIoq3WXAQr/7M6Vn59GMGjuB/+lIXqmWKkxzeFAX5f9sKqr9X7zI3g==",
       "requires": {
-        "@microsoft/api-extractor-model": "7.13.13",
-        "@microsoft/tsdoc": "0.13.2",
-        "@rushstack/node-core-library": "3.42.3",
-        "@rushstack/ts-command-line": "4.10.2",
-        "colors": "~1.2.1",
+        "@microsoft/api-extractor-model": "7.30.6",
+        "@microsoft/tsdoc": "~0.15.1",
+        "@rushstack/node-core-library": "5.13.1",
+        "@rushstack/terminal": "0.15.3",
+        "@rushstack/ts-command-line": "5.0.1",
         "js-yaml": "~3.13.1",
-        "resolve": "~1.17.0"
+        "resolve": "~1.22.1"
+      },
+      "dependencies": {
+        "@microsoft/tsdoc": {
+          "version": "0.15.1",
+          "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+          "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw=="
+        }
       }
     },
     "@microsoft/api-extractor-model": {
-      "version": "7.13.13",
-      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.13.tgz",
-      "integrity": "sha512-4Hz2TOL4TljsAfMQe7a8tm+Am8+AkrcgkbnH62S9YuaIC3Cw6jE4H2qP8WC2JJInWJP4pg/ZrUlHrtmtgrqn9Q==",
+      "version": "7.30.6",
+      "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.6.tgz",
+      "integrity": "sha512-znmFn69wf/AIrwHya3fxX6uB5etSIn6vg4Q4RB/tb5VDDs1rqREc+AvMC/p19MUN13CZ7+V/8pkYPTj7q8tftg==",
       "requires": {
-        "@microsoft/tsdoc": "0.13.2",
-        "@microsoft/tsdoc-config": "~0.15.2",
-        "@rushstack/node-core-library": "3.42.3"
+        "@microsoft/tsdoc": "~0.15.1",
+        "@microsoft/tsdoc-config": "~0.17.1",
+        "@rushstack/node-core-library": "5.13.1"
+      },
+      "dependencies": {
+        "@microsoft/tsdoc": {
+          "version": "0.15.1",
+          "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+          "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw=="
+        }
       }
     },
     "@microsoft/tsdoc": {
@@ -411,58 +528,68 @@
       "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg=="
     },
     "@microsoft/tsdoc-config": {
-      "version": "0.15.2",
-      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz",
-      "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz",
+      "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==",
       "requires": {
-        "@microsoft/tsdoc": "0.13.2",
-        "ajv": "~6.12.6",
+        "@microsoft/tsdoc": "0.15.1",
+        "ajv": "~8.12.0",
         "jju": "~1.4.0",
-        "resolve": "~1.19.0"
+        "resolve": "~1.22.2"
       },
       "dependencies": {
-        "resolve": {
-          "version": "1.19.0",
-          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-          "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
-          "requires": {
-            "is-core-module": "^2.1.0",
-            "path-parse": "^1.0.6"
-          }
+        "@microsoft/tsdoc": {
+          "version": "0.15.1",
+          "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+          "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw=="
         }
       }
     },
     "@rushstack/node-core-library": {
-      "version": "3.42.3",
-      "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.42.3.tgz",
-      "integrity": "sha512-xtiJsHtO4Sf/hVKyf/8d58p3zQh2JAZNs1mmDNCyIlgSRYGdqUkpadvvn5mz7EwF6lwn+xTTaTV5/a32xKjbdw==",
+      "version": "5.13.1",
+      "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz",
+      "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==",
       "requires": {
-        "@types/node": "12.20.24",
-        "colors": "~1.2.1",
-        "fs-extra": "~7.0.1",
+        "ajv": "~8.13.0",
+        "ajv-draft-04": "~1.0.0",
+        "ajv-formats": "~3.0.1",
+        "fs-extra": "~11.3.0",
         "import-lazy": "~4.0.0",
         "jju": "~1.4.0",
-        "resolve": "~1.17.0",
-        "semver": "~7.3.0",
-        "timsort": "~0.3.0",
-        "z-schema": "~3.18.3"
+        "resolve": "~1.22.1",
+        "semver": "~7.5.4"
       },
       "dependencies": {
-        "@types/node": {
-          "version": "12.20.24",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz",
-          "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ=="
+        "ajv": {
+          "version": "8.13.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz",
+          "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
+          "requires": {
+            "fast-deep-equal": "^3.1.3",
+            "json-schema-traverse": "^1.0.0",
+            "require-from-string": "^2.0.2",
+            "uri-js": "^4.4.1"
+          }
         }
       }
     },
+    "@rushstack/terminal": {
+      "version": "0.15.3",
+      "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.3.tgz",
+      "integrity": "sha512-DGJ0B2Vm69468kZCJkPj3AH5nN+nR9SPmC0rFHtzsS4lBQ7/dgOwtwVxYP7W9JPDMuRBkJ4KHmWKr036eJsj9g==",
+      "requires": {
+        "@rushstack/node-core-library": "5.13.1",
+        "supports-color": "~8.1.1"
+      }
+    },
     "@rushstack/ts-command-line": {
-      "version": "4.10.2",
-      "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.2.tgz",
-      "integrity": "sha512-Weq8B7oJeCQ4ITsaVLhOQombipyg+idpkdkhA6UqLtKvuzq8zTtPpAfhP5ff5L+RCmo1CFCVOBE3i+MvzUR5vA==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.1.tgz",
+      "integrity": "sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==",
       "requires": {
+        "@rushstack/terminal": "0.15.3",
         "@types/argparse": "1.0.38",
         "argparse": "~1.0.9",
-        "colors": "~1.2.1",
         "string-argv": "~0.3.1"
       }
     },
@@ -475,19 +602,33 @@
       "version": "16.11.2",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.2.tgz",
       "integrity": "sha512-w34LtBB0OkDTs19FQHXy4Ig/TOXI4zqvXS2Kk1PAsRKZ0I+nik7LlMYxckW0tSNGtvWmzB+mrCTbuEjuB9DVsw==",
-      "dev": true
+      "devOptional": true
     },
     "ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "version": "8.12.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+      "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
       "requires": {
         "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2",
         "uri-js": "^4.2.2"
       }
     },
+    "ajv-draft-04": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
+      "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
+      "requires": {}
+    },
+    "ajv-formats": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+      "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+      "requires": {
+        "ajv": "^8.0.0"
+      }
+    },
     "argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -496,17 +637,6 @@
         "sprintf-js": "~1.0.2"
       }
     },
-    "colors": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz",
-      "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg=="
-    },
-    "commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "optional": true
-    },
     "esprima": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@@ -517,37 +647,37 @@
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
     },
-    "fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
-    },
     "fs-extra": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
-      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+      "version": "11.3.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+      "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
       "requires": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
       }
     },
     "function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
     },
     "graceful-fs": {
-      "version": "4.2.8",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
     },
-    "has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+    "has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+    },
+    "hasown": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
       "requires": {
-        "function-bind": "^1.1.1"
+        "function-bind": "^1.1.2"
       }
     },
     "import-lazy": {
@@ -556,17 +686,17 @@
       "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw=="
     },
     "is-core-module": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
-      "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
+      "version": "2.16.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
       "requires": {
-        "has": "^1.0.3"
+        "hasown": "^2.0.2"
       }
     },
     "jju": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
-      "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo="
+      "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA=="
     },
     "js-yaml": {
       "version": "3.13.1",
@@ -578,28 +708,19 @@
       }
     },
     "json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
     },
     "jsonfile": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
       "requires": {
-        "graceful-fs": "^4.1.6"
+        "graceful-fs": "^4.1.6",
+        "universalify": "^2.0.0"
       }
     },
-    "lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
-    },
-    "lodash.isequal": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
-    },
     "lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -614,22 +735,29 @@
       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
     },
     "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
+    },
+    "require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
     },
     "resolve": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
-      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "version": "1.22.10",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+      "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
       "requires": {
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.16.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
       }
     },
     "semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.5.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
       "requires": {
         "lru-cache": "^6.0.0"
       }
@@ -640,19 +768,27 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
     },
     "string-argv": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
-      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg=="
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+      "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="
+    },
+    "supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "requires": {
+        "has-flag": "^4.0.0"
+      }
     },
-    "timsort": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
-      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
     },
     "universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="
     },
     "uri-js": {
       "version": "4.4.1",
@@ -662,26 +798,10 @@
         "punycode": "^2.1.0"
       }
     },
-    "validator": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz",
-      "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA=="
-    },
     "yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-    },
-    "z-schema": {
-      "version": "3.18.4",
-      "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz",
-      "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==",
-      "requires": {
-        "commander": "^2.7.1",
-        "lodash.get": "^4.0.0",
-        "lodash.isequal": "^4.0.0",
-        "validator": "^8.0.0"
-      }
     }
   }
 }
diff --git a/website/markdown-plugin/package.json b/website/markdown-plugin/package.json
index 0d443967..a791632d 100644
--- a/website/markdown-plugin/package.json
+++ b/website/markdown-plugin/package.json
@@ -12,7 +12,7 @@
   "author": "",
   "license": "MIT",
   "dependencies": {
-    "@microsoft/api-documenter": "^7.13.63",
+    "@microsoft/api-documenter": "7.26.26",
     "@microsoft/api-extractor-model": "^7.13.13",
     "@microsoft/tsdoc": "^0.13.2"
   },
diff --git a/website/markdown-plugin/src/MarkdownFeature.ts b/website/markdown-plugin/src/MarkdownFeature.ts
index 679146c0..624a88de 100644
--- a/website/markdown-plugin/src/MarkdownFeature.ts
+++ b/website/markdown-plugin/src/MarkdownFeature.ts
@@ -11,7 +11,6 @@ import FunctionJson from "./function.json"; // Same file as /website/function.js
 
 import {
   FuncParameters,
-  FuncReturn,
   Signature,
   SignatureOut,
   SignatureType,
@@ -29,7 +28,6 @@ const packageNameMap = new Map(); // to find an exact filename
 type MarkDownType =
   | typeof Signature
   | typeof FuncParameters
-  | typeof FuncReturn
   | typeof SignatureOut;
 
 class MarkdownFeature extends MarkdownDocumenterFeature {
@@ -69,13 +67,12 @@ class MarkdownFeature extends MarkdownDocumenterFeature {
     this.saveSignatureInfo(eventArgs, splitedPageContent);
     this.removeUnlessText(splitedPageContent);
 
-    // prettier-ignore
     eventArgs.pageContent = [
       this.header.join("\n"),
       splitedPageContent.join("\n\n"),
       this.sourceCodeLink.join("\n"),
-      this.footer.join("\n")
-    ].join('\n');
+      this.footer.join("\n"),
+    ].join("\n");
     this._apiItemsWithPages.add(eventArgs.apiItem);
   }
 
@@ -116,11 +113,7 @@ class MarkdownFeature extends MarkdownDocumenterFeature {
       splitedPageContent,
       FuncParameters,
     );
-    const returnStartEndIdx = this.findTextStartEndIndex(
-      splitedPageContent,
-      FuncReturn,
-    );
-    this.spliceText(splitedPageContent, returnStartEndIdx);
+
     this.spliceText(splitedPageContent, paramterStartEndIdx);
   }
 
diff --git a/website/markdown-plugin/src/Signature.ts b/website/markdown-plugin/src/Signature.ts
index 48b1dc12..dfb535fe 100644
--- a/website/markdown-plugin/src/Signature.ts
+++ b/website/markdown-plugin/src/Signature.ts
@@ -20,16 +20,18 @@ export const SignatureOut = {
 
 export const FuncParameters = {
   text: "## Parameters",
-  skip: 2,
-};
+  skip: (index: number, splited: string[]) => {
+    for (let i = index + 1; i < splited.length; i++) {
+      if (splited[i] === "## Example") {
+        return i - index;
+      }
+    }
 
-export const FuncReturn = {
-  text: "<b>Returns:</b>",
-  skip: 2,
+    return 0;
+  },
 };
 
 export type SignatureType =
   | typeof Signature
   | typeof SignatureOut
-  | typeof FuncParameters
-  | typeof FuncReturn;
+  | typeof FuncParameters;
diff --git a/website/markdown-plugin/src/function.json b/website/markdown-plugin/src/function.json
index bed8e42c..fbe81116 100644
--- a/website/markdown-plugin/src/function.json
+++ b/website/markdown-plugin/src/function.json
@@ -39,6 +39,7 @@
     "takeUntilInclusive",
     "takeWhile",
     "toAsync",
+    "transpose",
     "uniq",
     "uniqBy",
     "values",
@@ -112,5 +113,6 @@
     "unicodeToArray",
     "unless",
     "when"
-  ]
+  ],
+  "Util": ["debounce"]
 }
diff --git a/website/tsdoc-metadata.json b/website/tsdoc-metadata.json
index ba67d300..0598432e 100644
--- a/website/tsdoc-metadata.json
+++ b/website/tsdoc-metadata.json
@@ -5,7 +5,7 @@
   "toolPackages": [
     {
       "packageName": "@microsoft/api-extractor",
-      "packageVersion": "7.20.0"
+      "packageVersion": "7.52.6"
     }
   ]
 }


Test patch:
diff --git a/test/Lazy/transpose.spec.ts b/test/Lazy/transpose.spec.ts
new file mode 100644
index 00000000..bd101e12
--- /dev/null
+++ b/test/Lazy/transpose.spec.ts
@@ -0,0 +1,207 @@
+import {
+  concurrent,
+  delay,
+  join,
+  map,
+  pipe,
+  sum,
+  take,
+  toArray,
+  toAsync,
+  transpose,
+} from "../../src/index";
+import { Concurrent } from "../../src/Lazy/concurrent";
+import { generatorMock } from "../utils";
+
+describe("transpose", function () {
+  describe("sync", function () {
+    it("should be merged values of each 'Iterable' with value at the corresponding position", function () {
+      const res = toArray(transpose([1, "a"], [2, "b"], [3, "c"], [4, "d"]));
+
+      expect(res).toEqual([
+        [1, 2, 3, 4],
+        ["a", "b", "c", "d"],
+      ]);
+      expect(toArray(transpose(...res))).toEqual([
+        [1, "a"],
+        [2, "b"],
+        [3, "c"],
+        [4, "d"],
+      ]);
+    });
+
+    it("should be transposed if the iterables have different size", function () {
+      const res = toArray(transpose([1, 2], [3], [], [4, 5, 6], [7], [8, 9]));
+
+      expect(res).toEqual([[1, 3, 4, 7, 8], [2, 5, 9], [6]]);
+    });
+
+    it("should be able to be used in the pipeline", function () {
+      const res = pipe(
+        [1, 5],
+        (a) => transpose(a, [2, 6], [3, 7], [4, 8, 9]),
+        take(2),
+        map(sum),
+        toArray,
+      );
+
+      expect(res).toEqual([10, 26]);
+    });
+
+    it("should be transposed each 'Iterable' having a different type", function () {
+      const res = pipe(
+        ["a", 1],
+        (a) => transpose(a, ["b", 2], ["c", 3]),
+        map((value) => join("-", value)),
+        toArray,
+      );
+
+      expect(res).toEqual(["a-b-c", "1-2-3"]);
+    });
+
+    it("should be able to be used as a curried function in the pipeline", async function () {
+      const res = pipe([5, 6, 7, 8], transpose([1, 2, 3, 4]), toArray);
+
+      expect(res).toEqual([
+        [1, 5],
+        [2, 6],
+        [3, 7],
+        [4, 8],
+      ]);
+    });
+  });
+
+  describe("async", function () {
+    it("should be merged values of each 'AsyncIterable' with value at the corresponding position", async function () {
+      const res = await toArray(
+        transpose(
+          toAsync([1, 5]),
+          toAsync([2, 6]),
+          toAsync([3, 7]),
+          toAsync([4, 8]),
+        ),
+      );
+
+      expect(res).toEqual([
+        [1, 2, 3, 4],
+        [5, 6, 7, 8],
+      ]);
+    });
+
+    it("should be transposed if the iterables have different size", async function () {
+      const res = await toArray(
+        transpose(
+          toAsync([1, 2]),
+          toAsync([3]),
+          toAsync([]),
+          toAsync([4, 5, 6]),
+          toAsync([7]),
+          toAsync([8, 9]),
+        ),
+      );
+
+      expect(res).toEqual([[1, 3, 4, 7, 8], [2, 5, 9], [6]]);
+    });
+
+    it("should be transposed 'Iterable' and 'AsyncIterable'", async function () {
+      const res = await toArray(
+        transpose(
+          [1, 2, 3, 4],
+          // prettier-ignore
+          toAsync([5, 6, 7, 8]),
+        ),
+      );
+
+      expect(res).toEqual([
+        [1, 5],
+        [2, 6],
+        [3, 7],
+        [4, 8],
+      ]);
+    });
+
+    it("should be able to be used in the pipeline", async function () {
+      const res = await pipe(
+        toAsync([1, 2, 3, 4]),
+        (a) => transpose(a, [5, 6, 7, 8]),
+        toArray,
+      );
+
+      expect(res).toEqual([
+        [1, 5],
+        [2, 6],
+        [3, 7],
+        [4, 8],
+      ]);
+    });
+
+    it("should be transposed each 'AsyncIterable' having a different type", async function () {
+      const res = await pipe(
+        ["a", "b", "c", "d"],
+        (a) => transpose(a, toAsync([1, 2, 3, 4])),
+        map((a) => Object.fromEntries([a])),
+        toArray,
+      );
+      expect(res).toEqual([{ a: 1 }, { b: 2 }, { c: 3 }, { d: 4 }]);
+    });
+
+    it("should be transposed sequentially", async function () {
+      const res = await pipe(
+        toAsync([5, 6, 7, 8]),
+        map((nums) => delay(1000, nums)),
+        transpose([1, 2, 3, 4]),
+        toArray,
+      );
+
+      expect(res).toEqual([
+        [1, 5],
+        [2, 6],
+        [3, 7],
+        [4, 8],
+      ]);
+    }, 4050);
+
+    it("should be transposed concurrently: transpose - map", async function () {
+      const res = await pipe(
+        toAsync([5, 6, 7, 8]),
+        transpose([1, 2, 3, 4]),
+        map((nums) => delay(1000, nums)),
+        concurrent(4),
+        toArray,
+      );
+
+      expect(res).toEqual([
+        [1, 5],
+        [2, 6],
+        [3, 7],
+        [4, 8],
+      ]);
+    }, 1050);
+
+    it("should be transposed concurrently: map - transpose", async function () {
+      const res = await pipe(
+        toAsync([5, 6, 7, 8]),
+        map((nums) => delay(1000, nums)),
+        transpose([1, 2, 3, 4]),
+        concurrent(4),
+        toArray,
+      );
+
+      expect(res).toEqual([
+        [1, 5],
+        [2, 6],
+        [3, 7],
+        [4, 8],
+      ]);
+    }, 1050);
+
+    it("should be passed concurrent object when job works concurrently", async function () {
+      const mock = generatorMock();
+      const iter = transpose([1, 2, 3], mock);
+      const concurrent = Concurrent.of(2) as any;
+
+      await iter.next(concurrent);
+      expect((mock as any).getConcurrent()).toEqual(concurrent);
+    });
+  });
+});
diff --git a/test/Util/debounce.spec.ts b/test/Util/debounce.spec.ts
new file mode 100644
index 00000000..d327f7c8
--- /dev/null
+++ b/test/Util/debounce.spec.ts
@@ -0,0 +1,76 @@
+import { debounce } from "../../src";
+
+jest.useFakeTimers();
+
+describe("debounce", () => {
+  let callback: jest.Mock;
+
+  beforeEach(() => {
+    callback = jest.fn();
+  });
+
+  test("should delay the function call", () => {
+    const debounced = debounce(callback, 100);
+
+    debounced();
+    expect(callback).not.toBeCalled();
+
+    jest.advanceTimersByTime(50);
+    expect(callback).not.toBeCalled();
+
+    jest.advanceTimersByTime(50);
+    expect(callback).toBeCalledTimes(1);
+  });
+
+  test("should reset delay if called again before wait time", () => {
+    const debounced = debounce(callback, 100);
+
+    debounced();
+    jest.advanceTimersByTime(50);
+    debounced();
+    jest.advanceTimersByTime(50);
+    expect(callback).not.toBeCalled();
+
+    jest.advanceTimersByTime(50);
+    expect(callback).toBeCalledTimes(1);
+  });
+
+  test("should call immediately if immediate is true", () => {
+    const debounced = debounce(callback, 100, { leading: true });
+
+    debounced();
+    expect(callback).toBeCalledTimes(1);
+
+    debounced();
+    debounced();
+    expect(callback).toBeCalledTimes(1);
+
+    jest.advanceTimersByTime(100);
+
+    debounced();
+    expect(callback).toBeCalledTimes(2);
+  });
+
+  test("should use latest arguments", () => {
+    const cb = jest.fn((val: number) => val);
+    const debounced = debounce(cb, 100);
+
+    debounced(1);
+    debounced(2);
+    debounced(3);
+
+    jest.advanceTimersByTime(100);
+    expect(cb).toBeCalledWith(3);
+    expect(cb).toBeCalledTimes(1);
+  });
+
+  test("should cancel the delayed execution", () => {
+    const debounced = debounce(callback, 100);
+
+    debounced();
+    debounced.cancel();
+
+    jest.advanceTimersByTime(100);
+    expect(callback).not.toBeCalled();
+  });
+});
diff --git a/test/when.spec.ts b/test/when.spec.ts
index 1f606a74..8a2f65bb 100644
--- a/test/when.spec.ts
+++ b/test/when.spec.ts
@@ -1,37 +1,80 @@
 import { isString, pipe, when } from "../src";
 
 describe("when", function () {
-  const test = <T>(value: T) =>
-    when(
-      (value) => value === 100,
-      (value) => {
-        expect(value).toBeTruthy();
-      },
-      value,
-    );
-  const withPipe = <T>(value: T) =>
-    pipe(
-      value,
-      test,
-      when(isString, () => "Hello fxts"),
-    );
-
-  it("If the input value is a number, it will be filtered out by the first 'when' function. And throw undefined.", () => {
-    const INPUT_VALUE = 100;
-
-    test(INPUT_VALUE);
-    withPipe(INPUT_VALUE);
-  });
-  it("If the input value is a string, it will be filtered out by the second 'when' function. And return value is 'Hello fxts'", () => {
-    const INPUT_VALUE = "Hello World";
+  describe("with a general predicate", () => {
+    const test = <T>(value: T) =>
+      when(
+        (value) => value === 100,
+        (value) => {
+          expect(value).toBeTruthy();
+          return "value is 100";
+        },
+        value,
+      );
+    const withPipe = <T>(value: T) =>
+      pipe(
+        value,
+        test,
+        when(isString, () => "Hello fxts"),
+      );
+
+    it("If the input value is a number 100, the callback is executed and returns its result.", () => {
+      const INPUT_VALUE = 100;
+      expect(test(INPUT_VALUE)).toBe("value is 100");
+    });
+
+    it("If the input value does not match predicate, it returns the original value.", () => {
+      const INPUT_VALUE = "Hello World";
+      expect(test(INPUT_VALUE)).toBe("Hello World");
+    });
 
-    expect(test(INPUT_VALUE)).toBe("Hello World");
-    expect(withPipe(INPUT_VALUE)).toBe("Hello fxts");
+    it("If nothing matches, all 'when' functions will be passed.", () => {
+      const INPUT_VALUE = [1, 2, 3, 4];
+      expect(test(INPUT_VALUE)).toEqual(INPUT_VALUE);
+      expect(withPipe(INPUT_VALUE)).toEqual(INPUT_VALUE);
+    });
   });
-  it("If nothing matches, all 'when' functions will be passed.", () => {
-    const INPUT_VALUE = [1, 2, 3, 4];
 
-    expect(test(INPUT_VALUE)).toEqual(INPUT_VALUE);
-    expect(withPipe(INPUT_VALUE)).toEqual(INPUT_VALUE);
+  describe("with a type guard predicate", () => {
+    type Shape =
+      | { type: "circle"; radius: number }
+      | { type: "square"; side: number };
+
+    const isCircle = (
+      shape: Shape,
+    ): shape is { type: "circle"; radius: number } => shape.type === "circle";
+
+    it("should return the result of the callback when the type guard is true", () => {
+      const myShape: Shape = { type: "circle", radius: 10 };
+      const result = when(
+        isCircle,
+        (circle) => `A circle with radius ${circle.radius}`,
+        myShape,
+      );
+      expect(result).toBe("A circle with radius 10");
+    });
+
+    it("should return the original value when the type guard is false", () => {
+      const anotherShape: Shape = { type: "square", side: 5 };
+      const result = when(
+        isCircle,
+        (circle) => `A circle with radius ${circle.radius}`,
+        anotherShape,
+      );
+      expect(result).toEqual(anotherShape);
+    });
+
+    it("should work correctly with pipe", () => {
+      const myShape: Shape = { type: "circle", radius: 10 };
+      const anotherShape: Shape = { type: "square", side: 5 };
+
+      const shapeHandler = when(
+        isCircle,
+        (circle) => `A circle with radius ${circle.radius}`,
+      );
+
+      expect(pipe(myShape, shapeHandler)).toBe("A circle with radius 10");
+      expect(pipe(anotherShape, shapeHandler)).toEqual(anotherShape);
+    });
   });
 });
diff --git a/type-check/Lazy/transpose.test.ts b/type-check/Lazy/transpose.test.ts
new file mode 100644
index 00000000..5f1d7f5f
--- /dev/null
+++ b/type-check/Lazy/transpose.test.ts
@@ -0,0 +1,26 @@
+import { pipe, toAsync, transpose } from "../../src";
+import * as Test from "../../src/types/Test";
+
+const { checks, check } = Test;
+
+const res1 = transpose([1, 2, 3], "abc", [true, false, true]);
+const res2 = transpose([1, 2, 3], "abcde", [true, false, true]);
+const res3 = transpose([1, 2, 3], toAsync("abc"), [true, false, true]);
+
+const res4 = pipe([1, 2, 3], transpose("abc"));
+const res5 = pipe([1, 2, 3], toAsync, transpose("abc"));
+const res6 = pipe([1, 2, 3], transpose(toAsync("abc")));
+
+checks([
+  check<typeof res1, IterableIterator<[number, string, boolean]>, Test.Pass>(),
+  check<typeof res2, IterableIterator<[number, string, boolean]>, Test.Pass>(),
+  check<
+    typeof res3,
+    AsyncIterableIterator<[number, string, boolean]>,
+    Test.Pass
+  >(),
+
+  check<typeof res4, IterableIterator<[string, number]>, Test.Pass>(),
+  check<typeof res5, AsyncIterableIterator<[string, number]>, Test.Pass>(),
+  check<typeof res6, AsyncIterableIterator<[string, number]>, Test.Pass>(),
+]);
diff --git a/type-check/Util/debounce.test.ts b/type-check/Util/debounce.test.ts
new file mode 100644
index 00000000..6111bdca
--- /dev/null
+++ b/type-check/Util/debounce.test.ts
@@ -0,0 +1,9 @@
+import { debounce } from "../../src";
+import * as Test from "../../src/types/Test";
+
+const { checks, check } = Test;
+
+declare function fn(a: number): void;
+const res1 = debounce(fn, 300);
+
+checks([check<typeof res1, typeof fn & { cancel: () => void }, Test.Pass>()]);
diff --git a/type-check/isArray.test.ts b/type-check/isArray.test.ts
index 2549f7dc..c5d00406 100644
--- a/type-check/isArray.test.ts
+++ b/type-check/isArray.test.ts
@@ -1,4 +1,4 @@
-import { isArray, negate, pipe, throwIf } from "../src";
+import { isArray, negate, pipe, prop, throwIf } from "../src";
 import * as Test from "../src/types/Test";
 
 const { checks, check } = Test;
@@ -18,9 +18,27 @@ const res4 = pipe(
   throwIf(negate(isArray)),
 );
 
+type Profile = {
+  thumbnail: string;
+  nickname?: string;
+  id: string;
+};
+
+type UserState = {
+  profiles: Profile[];
+};
+
+declare const state: UserState;
+
+const res5 = pipe(prop("profiles", state), throwIf(negate(isArray)));
+
 checks([
   check<typeof res1, boolean, Test.Pass>(),
   check<typeof res2, boolean, Test.Pass>(),
   check<typeof res3, readonly [1, 2, 3], Test.Pass>(),
   check<typeof res4, number[], Test.Pass>(),
+
+  // this type test prove #317 issue is resolved
+  // isArray type guard infer generic type `T` to `Profile[]` type instead of `unknown[]` type
+  check<typeof res5, Profile[], Test.Pass>(),
 ]);
diff --git a/type-check/when.test.ts b/type-check/when.test.ts
index a96d61ce..63a3a336 100644
--- a/type-check/when.test.ts
+++ b/type-check/when.test.ts
@@ -19,10 +19,48 @@ const check4 = when(
   VALUE_2,
 );
 
+// New test cases for R | Exclude<T, S>
+type Shape =
+  | { type: "circle"; radius: number }
+  | { type: "square"; side: number };
+const myShape: Shape = { type: "circle", radius: 10 };
+const anotherShape: Shape = { type: "square", side: 5 };
+
+const isCircle = (
+  shape: Shape,
+): shape is { type: "circle"; radius: number } => {
+  return shape.type === "circle";
+};
+
+// When predicate is a type guard and is true at runtime
+const check5 = when(
+  isCircle,
+  (circle) => `A circle with radius ${circle.radius}`, // R = string
+  myShape,
+);
+
+// When predicate is a type guard and is false at runtime
+const check6 = when(
+  isCircle,
+  (circle) => `A circle with radius ${circle.radius}`, // R = string
+  anotherShape,
+);
+
+// Curried version
+const curriedWhen = when(
+  isCircle,
+  (circle) => `A circle with radius ${circle.radius}`,
+);
+const check7 = curriedWhen(myShape);
+
 checks([
   check<typeof VALUE_1, 100, Test.Pass>(),
   check<typeof check1, string, Test.Pass>(),
-  check<typeof check2, number, Test.Pass>(),
+  check<typeof check2, string | number, Test.Pass>(),
   check<typeof check3, typeof VALUE_2 | string, Test.Pass>(),
   check<typeof check4, typeof VALUE_2 | string, Test.Pass>(),
+  // --- Added Tests ---
+  check<typeof check5, string, Test.Pass>(),
+  check<typeof check6, string | { type: "square"; side: number }, Test.Pass>(),
+  check<typeof check7, string | { type: "square"; side: number }, Test.Pass>(),
 ]);