diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index df3ddcb..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.json linguist-language=JSON-with-Comments \ No newline at end of file diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 5668ea8..ead28e2 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -2,7 +2,7 @@ name: reviewdog on: [pull_request] jobs: biome: - name: runner / Biome + name: Biome Linter runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41b8d37..999c5b6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,13 +29,13 @@ jobs: bun-version: latest - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Setup zig - uses: mlugg/setup-zig@v1 + run: bun install --frozen-lockfile --ignore-scripts --no-save + + - name: Install node-gyp + run: bun add -g node-gyp - name: Build - run: bun run build.ts + run: bun run build - name: Upload artifact uses: actions/upload-artifact@v4 @@ -78,7 +78,10 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Install dependencies - run: npm install + run: npm ci --ignore-scripts + + - name: Install semantic-release plugins + run: npm install @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/npm @semantic-release/github @semantic-release/git - name: Run semantic-release run: npx semantic-release diff --git a/.gitignore b/.gitignore index 3d19d15..95cb72f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules lib +build .vscode .vs .windsurfrules diff --git a/.npmignore b/.npmignore index 4ceb0fd..37dbd8d 100644 --- a/.npmignore +++ b/.npmignore @@ -5,8 +5,16 @@ !lib/ !lib/** +# Keep the assets directory and its contents +!assets/ +!assets/** + # Keep essential files !package.json !README.md !LICENSE -!CHANGELOG.md \ No newline at end of file +!CHANGELOG.md + +# Keep the lock files +!package-lock.json +!bun.lockb \ No newline at end of file diff --git a/README.md b/README.md index b170c90..c9ec0e5 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,3 @@ -> ⚠️ **WARNING:** -> This package relies heavily on **Bun's native FFI (`bun:ffi`)** for performance and interacting with system APIs. -> Furthermore, it interacts directly with the Windows API and is therefore **only compatible with Windows**. -> -> Currently, Bun does not provide a polyfill for `bun:ffi` when building for Node.js (`target: 'node'`). Therefore, this package is **only compatible with the Bun runtime** and **will not work** if run directly with Node.js. -> -> While Bun intends to add polyfills for `bun:*` modules in the future to improve Node.js compatibility for bundled code (see [Bundler Docs](https://bun.sh/docs/bundler#target)), this is not yet implemented for `bun:ffi`. -> -> **Requirements:** -> * Bun v1.2.9 or later (required to run the code) - ---- -

Banner
@@ -32,69 +19,65 @@

-## Current Status - -This package is currently under active development. The following core functions are implemented and available for use: - -* `openProcess(processIdentifier: string | number): ProcessObject`: Opens a process by its name or ID. -* `closeProcess(handle: number): void`: Closes an opened process handle. -* `readMemory(handle: number, address: number, dataType: MemoryDataType): number`: Reads memory from a specific address in the target process. **Note:** Currently returns `number` for all types, including strings (returning the address). String content reading is planned. -* `writeMemory(handle: number, address: number, value: MemoryValueType, dataType: MemoryDataType): void`: Writes memory to a specific address in the target process. - -The `ProcessObject` object returned by `openProcess` contains information about the opened process: - -```typescript -interface ProcessObject { - dwSize: number; // Size of the structure, in bytes - th32ProcessID: number; // Process identifier (PID) - cntThreads: number; // Number of execution threads started by the process - th32ParentProcessID: number; // PID of the parent process - pcPriClassBase: number; // Base priority of threads created by this process - szExeFile: string; // Path to the executable file - handle: number; // Process handle (for read/write operations) - modBaseAddr: number; // Base address of the process's primary module -} -``` - -More functions are planned for future releases to expand the capabilities of this library. - -## Data Types - -The `dataType` parameter in `readMemory` and `writeMemory` specifies the type of data to be read or written. It accepts a specific set of string literals defined by the `MemoryDataType` type in TypeScript. The `value` parameter for `writeMemory` should correspond to this type, as defined by `MemoryValueType` (number, string, or boolean). - -### Supported Data Type Strings - -The following data type strings (and their aliases) are supported: - -* **8-bit Signed:** `byte`, `int8`, `char` -* **8-bit Unsigned:** `ubyte`, `uint8`, `uchar` -* **16-bit Signed:** `short`, `int16` -* **16-bit Unsigned:** `ushort`, `uint16`, `word` -* **32-bit Signed:** `int`, `int32`, `long` -* **32-bit Unsigned:** `uint`, `uint32`, `ulong`, `dword` -* **64-bit Signed:** `longlong`, `int64` (uses BigInt) -* **64-bit Unsigned:** `ulonglong`, `uint64` (uses BigInt) -* **Floating Point:** `float` (4 bytes), `double` (8 bytes) -* **Boolean:** `bool` (1 byte, 0 or 1) -* **String:** `string`, `str` (Null-terminated UTF-8) - -### TypeScript Type Definitions - -```typescript -/** Represents the valid data types for memory operations. */ -export type MemoryDataType = - | "byte" | "int8" | "char" // 8-bit signed - | "ubyte" | "uint8" | "uchar" // 8-bit unsigned - | "short" | "int16" // 16-bit signed - | "ushort" | "uint16" | "word" // 16-bit unsigned - | "int" | "int32" | "long" // 32-bit signed - | "uint" | "uint32" | "ulong" | "dword" // 32-bit unsigned - | "float" // 32-bit float - | "double" // 64-bit float - | "longlong" | "int64" // 64-bit signed (Note: JS Number limitations apply) - | "ulonglong" | "uint64" // 64-bit unsigned (Note: JS Number limitations apply) - | "bool" - | "string" | "str"; // Null-terminated string - -/** Represents the possible value types corresponding to MemoryDataType. */ -export type MemoryValueType = number | string | boolean; +--- + +## 📖 API References (`src`) + +### Main Functions + +- **openProcess(processIdentifier: string | number, callback?): Process** + Opens a process by name or ID. Returns the process handle or undefined if not found. + +- **closeHandle(handle: number): boolean** + Closes a process handle. + +- **getProcesses(callback?): Process[]** + Returns the list of running processes. + +- **findModule(moduleName: string, processId: number, callback?): Module | undefined** + Finds a module by name in a process. + +- **getModules(processId: number, callback?): Module[]** + Returns the modules loaded by a process. + +- **readMemory(handle: number, address: number, dataType: T, callback?): MemoryData | undefined** + Reads a value from a process's memory. + +- **writeMemory(handle: number, address: number, value: any, dataType: DataType): boolean** + Writes a value to a process's memory. + +- **findPattern(...)** + Scans memory patterns (multiple overloads). + +- **callFunction(handle: number, args: any[], returnType: number, address: number, callback?): any** + Calls a function in the process's memory. + +- **Debugger** + Utility class for process debugging. Main methods: `attach`, `detach`, `setHardwareBreakpoint`, `removeHardwareBreakpoint`, `monitor`. + +- **virtualAllocEx, virtualProtectEx, getRegions, virtualQueryEx, injectDll, unloadDll, openFileMapping, mapViewOfFile** + Advanced memory and DLL manipulation functions. + +### Main Types and Constants (`types.ts`) + +- **type DataType** + Supported data types for memory read/write: `'byte'`, `'int32'`, `'float'`, `'string'`, `'vector3'`, etc. + +- **type MemoryData** + Maps a `DataType` to its corresponding JS type (`number`, `bigint`, `string`, `{x,y,z}`...) + +- **interface Process** + Information about an opened process (PID, handle, etc). + +- **interface Module** + Information about a module loaded in a process. + +- **type Protection, PageProtection, AllocationType, BreakpointTriggerType** + Auxiliary types for memory flags and protection. + +- **const FunctionTypes, SignatureTypes, MemoryAccessFlags, MemoryPageFlags, HardwareDebugRegisters, BreakpointTriggerTypes** + Constants for flags and function types. + +--- + +> See the [`src`](./src) folder for full details and comments on each function/type. \ No newline at end of file diff --git a/binding.gyp b/binding.gyp new file mode 100644 index 0000000..15de595 --- /dev/null +++ b/binding.gyp @@ -0,0 +1,20 @@ +{ + "targets": [ + { + "target_name": "native", + "include_dirs" : [ + "=6" } }, "sha512-n5KPteiF7pWKgBIBJSk8qzoZWcUkza2O6A0za97pMGVrGfPdltxrfmfF5GucHYvHGZD8BdaZmmHGz5cX/3gdpw=="], - - "@octokit/plugin-retry": ["@octokit/plugin-retry@7.2.1", "", { "dependencies": { "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-wUc3gv0D6vNHpGxSaR3FlqJpTXGWgqmk607N9L3LvPL4QjaxDgX/1nY2mGpT37Khn+nlIXdljczkRnNdTTV3/A=="], - - "@octokit/plugin-throttling": ["@octokit/plugin-throttling@9.6.1", "", { "dependencies": { "@octokit/types": "^13.7.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": "^6.1.3" } }, "sha512-bt3EBUkeKUzDQXRCcFrR9SWVqlLFRRqcCrr6uAorWt6NXTyjMKqcGrFmXqJy9NCbnKgiIZ2OXWq04theFc76Jg=="], - - "@octokit/request": ["@octokit/request@9.2.3", "", { "dependencies": { "@octokit/endpoint": "^10.1.4", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-Ma+pZU8PXLOEYzsWf0cn/gY+ME57Wq8f49WTXA8FMHp2Ps9djKw//xYJ1je8Hm0pR2lU9FUGeJRWOtxq6olt4w=="], - - "@octokit/request-error": ["@octokit/request-error@6.1.8", "", { "dependencies": { "@octokit/types": "^14.0.0" } }, "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ=="], - - "@octokit/types": ["@octokit/types@14.0.0", "", { "dependencies": { "@octokit/openapi-types": "^25.0.0" } }, "sha512-VVmZP0lEhbo2O1pdq63gZFiGCKkm8PPp8AUOijlwPO6hojEVjspA0MWKP7E4hbvGxzFKNqKr6p0IYtOH/Wf/zA=="], - - "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], - - "@pnpm/network.ca-file": ["@pnpm/network.ca-file@1.0.2", "", { "dependencies": { "graceful-fs": "4.2.10" } }, "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA=="], - - "@pnpm/npm-conf": ["@pnpm/npm-conf@2.3.1", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw=="], - - "@rushstack/node-core-library": ["@rushstack/node-core-library@5.13.0", "", { "dependencies": { "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.22.1", "semver": "~7.5.4" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-IGVhy+JgUacAdCGXKUrRhwHMTzqhWwZUI+qEPcdzsb80heOw0QPbhhoVsoiMF7Klp8eYsp7hzpScMXmOa3Uhfg=="], - - "@rushstack/rig-package": ["@rushstack/rig-package@0.5.3", "", { "dependencies": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" } }, "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow=="], - - "@rushstack/terminal": ["@rushstack/terminal@0.15.2", "", { "dependencies": { "@rushstack/node-core-library": "5.13.0", "supports-color": "~8.1.1" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-7Hmc0ysK5077R/IkLS9hYu0QuNafm+TbZbtYVzCMbeOdMjaRboLKrhryjwZSRJGJzu+TV1ON7qZHeqf58XfLpA=="], - - "@rushstack/ts-command-line": ["@rushstack/ts-command-line@4.23.7", "", { "dependencies": { "@rushstack/terminal": "0.15.2", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" } }, "sha512-Gr9cB7DGe6uz5vq2wdr89WbVDKz0UeuFEn5H2CfWDe7JvjFFaiV15gi6mqDBTbHhHCWS7w8mF1h3BnIfUndqdA=="], - - "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], - - "@semantic-release/commit-analyzer": ["@semantic-release/commit-analyzer@13.0.1", "", { "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "micromatch": "^4.0.2" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ=="], - - "@semantic-release/error": ["@semantic-release/error@3.0.0", "", {}, "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw=="], - - "@semantic-release/git": ["@semantic-release/git@10.0.1", "", { "dependencies": { "@semantic-release/error": "^3.0.0", "aggregate-error": "^3.0.0", "debug": "^4.0.0", "dir-glob": "^3.0.0", "execa": "^5.0.0", "lodash": "^4.17.4", "micromatch": "^4.0.0", "p-reduce": "^2.0.0" }, "peerDependencies": { "semantic-release": ">=18.0.0" } }, "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w=="], - - "@semantic-release/github": ["@semantic-release/github@11.0.1", "", { "dependencies": { "@octokit/core": "^6.0.0", "@octokit/plugin-paginate-rest": "^11.0.0", "@octokit/plugin-retry": "^7.0.0", "@octokit/plugin-throttling": "^9.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "debug": "^4.3.4", "dir-glob": "^3.0.1", "globby": "^14.0.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "issue-parser": "^7.0.0", "lodash-es": "^4.17.21", "mime": "^4.0.0", "p-filter": "^4.0.0", "url-join": "^5.0.0" }, "peerDependencies": { "semantic-release": ">=24.1.0" } }, "sha512-Z9cr0LgU/zgucbT9cksH0/pX9zmVda9hkDPcgIE0uvjMQ8w/mElDivGjx1w1pEQ+MuQJ5CBq3VCF16S6G4VH3A=="], - - "@semantic-release/npm": ["@semantic-release/npm@12.0.1", "", { "dependencies": { "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "execa": "^9.0.0", "fs-extra": "^11.0.0", "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^8.0.0", "npm": "^10.5.0", "rc": "^1.2.8", "read-pkg": "^9.0.0", "registry-auth-token": "^5.0.0", "semver": "^7.1.2", "tempy": "^3.0.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw=="], - - "@semantic-release/release-notes-generator": ["@semantic-release/release-notes-generator@14.0.3", "", { "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "get-stream": "^7.0.0", "import-from-esm": "^2.0.0", "into-stream": "^7.0.0", "lodash-es": "^4.17.21", "read-package-up": "^11.0.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-XxAZRPWGwO5JwJtS83bRdoIhCiYIx8Vhr+u231pQAsdFIAbm19rSVJLdnBN+Avvk7CKvNQE/nJ4y7uqKH6WTiw=="], - - "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], - - "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="], - - "@types/argparse": ["@types/argparse@1.0.38", "", {}, "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA=="], - - "@types/bun": ["@types/bun@1.2.9", "", { "dependencies": { "bun-types": "1.2.9" } }, "sha512-epShhLGQYc4Bv/aceHbmBhOz1XgUnuTZgcxjxk+WXwNyDXavv5QHD1QEFV0FwbTSQtNq6g4ZcV6y0vZakTjswg=="], - - "@types/conventional-commits-parser": ["@types/conventional-commits-parser@5.0.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ=="], - - "@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="], - - "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], - - "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], - - "JSONStream": ["JSONStream@1.3.5", "", { "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" }, "bin": { "JSONStream": "./bin.js" } }, "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ=="], - - "agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="], - - "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - - "ajv": ["ajv@8.12.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA=="], - - "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], - - "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], - - "ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="], - - "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], - - "ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], - - "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], - - "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], - - "argv-formatter": ["argv-formatter@1.0.0", "", {}, "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw=="], - - "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], - - "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="], - - "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], - - "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], - - "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - - "bun-types": ["bun-types@1.2.9", "", { "dependencies": { "@types/node": "*", "@types/ws": "*" } }, "sha512-dk/kOEfQbajENN/D6FyiSgOKEuUi9PWfqKQJEgwKrCMWbjS/S6tEXp178mWvWAcUSYm9ArDlWHZKO3T/4cLXiw=="], - - "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - - "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], - - "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], - - "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], - - "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], - - "cli-table3": ["cli-table3@0.6.5", "", { "dependencies": { "string-width": "^4.2.0" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ=="], - - "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], - - "color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], - - "color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], - - "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], - - "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], - - "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], - - "conventional-changelog-angular": ["conventional-changelog-angular@8.0.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA=="], - - "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@7.0.2", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w=="], - - "conventional-changelog-writer": ["conventional-changelog-writer@8.0.1", "", { "dependencies": { "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", "semver": "^7.5.2" }, "bin": { "conventional-changelog-writer": "dist/cli/index.js" } }, "sha512-hlqcy3xHred2gyYg/zXSMXraY2mjAYYo0msUCpK+BGyaVJMFCKWVXPIHiaacGO2GGp13kvHWXFhYmxT4QQqW3Q=="], - - "conventional-commits-filter": ["conventional-commits-filter@5.0.0", "", {}, "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q=="], - - "conventional-commits-parser": ["conventional-commits-parser@6.1.0", "", { "dependencies": { "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-5nxDo7TwKB5InYBl4ZC//1g9GRwB/F3TXOGR9hgUjMGfvSP4Vu5NkpNro2+1+TIEy1vwxApl5ircECr2ri5JIw=="], - - "convert-hrtime": ["convert-hrtime@5.0.0", "", {}, "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg=="], - - "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], - - "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], - - "cosmiconfig-typescript-loader": ["cosmiconfig-typescript-loader@6.1.0", "", { "dependencies": { "jiti": "^2.4.1" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g=="], - - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], - - "crypto-random-string": ["crypto-random-string@4.0.0", "", { "dependencies": { "type-fest": "^1.0.1" } }, "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA=="], - - "dargs": ["dargs@8.1.0", "", {}, "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw=="], - - "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], - - "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], - - "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], - - "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], - - "duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "^2.0.2" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="], - - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "emojilib": ["emojilib@2.4.0", "", {}, "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw=="], - - "env-ci": ["env-ci@11.1.0", "", { "dependencies": { "execa": "^8.0.0", "java-properties": "^1.0.2" } }, "sha512-Z8dnwSDbV1XYM9SBF2J0GcNVvmfmfh3a49qddGIROhBoVro6MZVTji15z/sJbQ2ko2ei8n988EU1wzoLU/tF+g=="], - - "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], - - "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], - - "error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="], - - "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - - "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], - - "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], - - "fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="], - - "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - - "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], - - "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], - - "figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="], - - "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - - "find-up": ["find-up@7.0.0", "", { "dependencies": { "locate-path": "^7.2.0", "path-exists": "^5.0.0", "unicorn-magic": "^0.1.0" } }, "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g=="], - - "find-up-simple": ["find-up-simple@1.0.1", "", {}, "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ=="], - - "find-versions": ["find-versions@6.0.0", "", { "dependencies": { "semver-regex": "^4.0.5", "super-regex": "^1.0.0" } }, "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA=="], - - "from2": ["from2@2.3.0", "", { "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g=="], - - "fs-extra": ["fs-extra@11.3.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew=="], - - "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], - - "function-timeout": ["function-timeout@1.0.2", "", {}, "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA=="], - - "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], - - "get-stream": ["get-stream@7.0.1", "", {}, "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ=="], - - "git-log-parser": ["git-log-parser@1.2.1", "", { "dependencies": { "argv-formatter": "~1.0.0", "spawn-error-forwarder": "~1.0.0", "split2": "~1.0.0", "stream-combiner2": "~1.1.1", "through2": "~2.0.0", "traverse": "0.6.8" } }, "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ=="], - - "git-raw-commits": ["git-raw-commits@4.0.0", "", { "dependencies": { "dargs": "^8.0.0", "meow": "^12.0.1", "split2": "^4.0.0" }, "bin": { "git-raw-commits": "cli.mjs" } }, "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ=="], - - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - - "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="], - - "globby": ["globby@14.1.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.3", "ignore": "^7.0.3", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA=="], - - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], - - "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], - - "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - - "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], - - "hook-std": ["hook-std@3.0.0", "", {}, "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw=="], - - "hosted-git-info": ["hosted-git-info@8.1.0", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw=="], - - "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], - - "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - - "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], - - "ignore": ["ignore@7.0.3", "", {}, "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA=="], - - "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], - - "import-from-esm": ["import-from-esm@2.0.0", "", { "dependencies": { "debug": "^4.3.4", "import-meta-resolve": "^4.0.0" } }, "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g=="], - - "import-lazy": ["import-lazy@4.0.0", "", {}, "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw=="], - - "import-meta-resolve": ["import-meta-resolve@4.1.0", "", {}, "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw=="], - - "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], - - "index-to-position": ["index-to-position@1.1.0", "", {}, "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg=="], - - "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], - - "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], - - "into-stream": ["into-stream@7.0.0", "", { "dependencies": { "from2": "^2.3.0", "p-is-promise": "^3.0.0" } }, "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw=="], - - "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], - - "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], - - "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - - "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], - - "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - - "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], - - "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], - - "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], - - "is-text-path": ["is-text-path@2.0.0", "", { "dependencies": { "text-extensions": "^2.0.0" } }, "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw=="], - - "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], - - "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], - - "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - - "issue-parser": ["issue-parser@7.0.1", "", { "dependencies": { "lodash.capitalize": "^4.2.1", "lodash.escaperegexp": "^4.1.2", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.uniqby": "^4.7.0" } }, "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg=="], - - "java-properties": ["java-properties@1.0.2", "", {}, "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ=="], - - "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], - - "jju": ["jju@1.4.0", "", {}, "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA=="], - - "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - - "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - - "json-parse-better-errors": ["json-parse-better-errors@1.0.2", "", {}, "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="], - - "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], - - "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - - "jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="], - - "jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], - - "lefthook": ["lefthook@1.11.10", "", { "optionalDependencies": { "lefthook-darwin-arm64": "1.11.10", "lefthook-darwin-x64": "1.11.10", "lefthook-freebsd-arm64": "1.11.10", "lefthook-freebsd-x64": "1.11.10", "lefthook-linux-arm64": "1.11.10", "lefthook-linux-x64": "1.11.10", "lefthook-openbsd-arm64": "1.11.10", "lefthook-openbsd-x64": "1.11.10", "lefthook-windows-arm64": "1.11.10", "lefthook-windows-x64": "1.11.10" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-nuiRqBADcRiU6dzwf2H1zBCsdcWGEOsxY8hqoXw5nkEuoTEYN1Bwi2vskHXjIzJ62iCOCo4FZhcHBAzT9gwL5g=="], - - "lefthook-darwin-arm64": ["lefthook-darwin-arm64@1.11.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Rufl8BRP77GRFtgNwW95/FHPD0VDfu5bRyzASPcyVrFczJiBK1glAHRdYrErBDNqJhEEjkyv9+EkCZS/MnDKPQ=="], - - "lefthook-darwin-x64": ["lefthook-darwin-x64@1.11.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-3ReMyC103S+RozcYQlej9RVa1tKr9t8/PGqXbCiWcPAgA9To3GywPk8533qzTs7Nz9fYDiqJMYyQoXovX0Q4SA=="], - - "lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@1.11.10", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UQOdQuvoVEe0HnoVX4Uz8beegndBDKE6Igo5flV3OkrBuO1Cz7dGbTQwzsYg6gBLYUOa8Ecb3Xur80oviQqwnA=="], - - "lefthook-freebsd-x64": ["lefthook-freebsd-x64@1.11.10", "", { "os": "freebsd", "cpu": "x64" }, "sha512-IkoywmTzw9dKDtN34HJ8AZkbY3CGu1XpAVU08pIIvlhv0y7PlLGHYTdmx90SC1d4FhTlTMyiANgXyIaAnXjucw=="], - - "lefthook-linux-arm64": ["lefthook-linux-arm64@1.11.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-l/lH4FSljNSIetcptPKLI5sTBpjS6dJZ4gk9oXoGM0ftvb22AlLcZI4l6NFCC1oLVWM0CbhkbStDGTI5txsVaA=="], - - "lefthook-linux-x64": ["lefthook-linux-x64@1.11.10", "", { "os": "linux", "cpu": "x64" }, "sha512-yAIIP711p7t0Z9zLfPtdSx1d7pSgtnuVC5B9PANud3I0JOs82aCzmqpc9Q/zp+imWXdI2PpZlFyKx8GLrDW5BQ=="], - - "lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@1.11.10", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-OAqg9BLsTaeioCJduzZrRLupA2dhTOwHOX0GkO4HTSrOD85JuEPqr5RbYoJ7zuzTQcJEXTJYzaeATM2QHjp/aQ=="], - - "lefthook-openbsd-x64": ["lefthook-openbsd-x64@1.11.10", "", { "os": "openbsd", "cpu": "x64" }, "sha512-EiUU3mFvqcUdnj3gt0V0gRpQQp0b70cLDSA0LgZyFMM4UimeMbA7OgNYl72RKJgrHcTPHrQc4Vj7Mowbhb/X5w=="], - - "lefthook-windows-arm64": ["lefthook-windows-arm64@1.11.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-clKfI95dCpzxJ1zVgcuYWlSl2oNbtAALoMGqYrzJsoy+CAi+vIs54sqJoGOE60+zrVbdk65z8hriCoYNr98SgA=="], - - "lefthook-windows-x64": ["lefthook-windows-x64@1.11.10", "", { "os": "win32", "cpu": "x64" }, "sha512-zpf/0sG50xsGnwVG/a2giUbmaM/g0uIRqxN5qBbmwKCf0P4PPD2r1xiFZNDb520+tUTC1lWe0RWVoSSwZbBQRA=="], - - "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], - - "load-json-file": ["load-json-file@4.0.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw=="], - - "locate-path": ["locate-path@7.2.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA=="], - - "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], - - "lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], - - "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], - - "lodash.capitalize": ["lodash.capitalize@4.2.1", "", {}, "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw=="], - - "lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="], - - "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="], - - "lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="], - - "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], - - "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], - - "lodash.mergewith": ["lodash.mergewith@4.6.2", "", {}, "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="], - - "lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="], - - "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], - - "lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="], - - "lodash.uniqby": ["lodash.uniqby@4.7.0", "", {}, "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww=="], - - "lodash.upperfirst": ["lodash.upperfirst@4.3.1", "", {}, "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg=="], - - "lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - - "marked": ["marked@12.0.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="], - - "marked-terminal": ["marked-terminal@7.3.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "peerDependencies": { "marked": ">=1 <16" } }, "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw=="], - - "meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], - - "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], - - "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - - "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - - "mime": ["mime@4.0.7", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ=="], - - "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], - - "minimatch": ["minimatch@3.0.8", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q=="], - - "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], - - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - - "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], - - "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="], - - "nerf-dart": ["nerf-dart@1.0.0", "", {}, "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g=="], - - "node-emoji": ["node-emoji@2.2.0", "", { "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" } }, "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw=="], - - "normalize-package-data": ["normalize-package-data@6.0.2", "", { "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g=="], - - "normalize-url": ["normalize-url@8.0.1", "", {}, "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w=="], - - "npm": ["npm@10.9.2", "", { "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^8.0.0", "@npmcli/config": "^9.0.0", "@npmcli/fs": "^4.0.0", "@npmcli/map-workspaces": "^4.0.2", "@npmcli/package-json": "^6.1.0", "@npmcli/promise-spawn": "^8.0.2", "@npmcli/redact": "^3.0.0", "@npmcli/run-script": "^9.0.1", "@sigstore/tuf": "^3.0.0", "abbrev": "^3.0.0", "archy": "~1.0.0", "cacache": "^19.0.1", "chalk": "^5.3.0", "ci-info": "^4.1.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", "hosted-git-info": "^8.0.2", "ini": "^5.0.0", "init-package-json": "^7.0.2", "is-cidr": "^5.1.0", "json-parse-even-better-errors": "^4.0.0", "libnpmaccess": "^9.0.0", "libnpmdiff": "^7.0.0", "libnpmexec": "^9.0.0", "libnpmfund": "^6.0.0", "libnpmhook": "^11.0.0", "libnpmorg": "^7.0.0", "libnpmpack": "^8.0.0", "libnpmpublish": "^10.0.1", "libnpmsearch": "^8.0.0", "libnpmteam": "^7.0.0", "libnpmversion": "^7.0.0", "make-fetch-happen": "^14.0.3", "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^11.0.0", "nopt": "^8.0.0", "normalize-package-data": "^7.0.0", "npm-audit-report": "^6.0.0", "npm-install-checks": "^7.1.1", "npm-package-arg": "^12.0.0", "npm-pick-manifest": "^10.0.0", "npm-profile": "^11.0.1", "npm-registry-fetch": "^18.0.2", "npm-user-validate": "^3.0.0", "p-map": "^4.0.0", "pacote": "^19.0.1", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", "read": "^4.0.0", "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", "ssri": "^12.0.0", "supports-color": "^9.4.0", "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", "validate-npm-package-name": "^6.0.0", "which": "^5.0.0", "write-file-atomic": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" } }, "sha512-iriPEPIkoMYUy3F6f3wwSZAU93E0Eg6cHwIR6jzzOXWSy+SD/rOODEs74cVONHKSx2obXtuUoyidVEhISrisgQ=="], - - "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], - - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], - - "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], - - "p-each-series": ["p-each-series@3.0.0", "", {}, "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw=="], - - "p-filter": ["p-filter@4.1.0", "", { "dependencies": { "p-map": "^7.0.1" } }, "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw=="], - - "p-is-promise": ["p-is-promise@3.0.0", "", {}, "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ=="], - - "p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], - - "p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], - - "p-map": ["p-map@7.0.3", "", {}, "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA=="], - - "p-reduce": ["p-reduce@2.1.0", "", {}, "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw=="], - - "p-try": ["p-try@1.0.0", "", {}, "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww=="], - - "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], - - "parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="], - - "parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="], - - "parse5": ["parse5@5.1.1", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="], - - "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@6.0.1", "", { "dependencies": { "parse5": "^6.0.1" } }, "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="], - - "path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], - - "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], - - "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], - - "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - - "pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="], - - "pkg-conf": ["pkg-conf@2.1.0", "", { "dependencies": { "find-up": "^2.0.0", "load-json-file": "^4.0.0" } }, "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g=="], - - "pretty-ms": ["pretty-ms@9.2.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg=="], - - "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], - - "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="], - - "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - - "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], - - "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], - - "read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="], - - "read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], - - "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], - - "registry-auth-token": ["registry-auth-token@5.1.0", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw=="], - - "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], - - "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], - - "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], - - "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], - - "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - - "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], - - "semantic-release": ["semantic-release@24.2.3", "", { "dependencies": { "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^11.0.0", "@semantic-release/npm": "^12.0.0", "@semantic-release/release-notes-generator": "^14.0.0-beta.1", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^3.0.0", "hosted-git-info": "^8.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^12.0.0", "marked-terminal": "^7.0.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", "read-package-up": "^11.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "semver-diff": "^4.0.0", "signale": "^1.2.1", "yargs": "^17.5.1" }, "bin": { "semantic-release": "bin/semantic-release.js" } }, "sha512-KRhQG9cUazPavJiJEFIJ3XAMjgfd0fcK3B+T26qOl8L0UG5aZUjeRfREO0KM5InGtYwxqiiytkJrbcYoLDEv0A=="], - - "semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="], - - "semver-diff": ["semver-diff@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA=="], - - "semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="], - - "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], - - "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - - "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - - "signale": ["signale@1.4.0", "", { "dependencies": { "chalk": "^2.3.2", "figures": "^2.0.0", "pkg-conf": "^2.1.0" } }, "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w=="], - - "skin-tone": ["skin-tone@2.0.0", "", { "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" } }, "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA=="], - - "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="], - - "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - - "spawn-error-forwarder": ["spawn-error-forwarder@1.0.0", "", {}, "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g=="], - - "spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], - - "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], - - "spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], - - "spdx-license-ids": ["spdx-license-ids@3.0.21", "", {}, "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg=="], - - "split2": ["split2@1.0.0", "", { "dependencies": { "through2": "~2.0.0" } }, "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg=="], - - "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], - - "stream-combiner2": ["stream-combiner2@1.1.1", "", { "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw=="], - - "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], - - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - - "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], - - "strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], - - "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], - - "super-regex": ["super-regex@1.0.0", "", { "dependencies": { "function-timeout": "^1.0.1", "time-span": "^5.1.0" } }, "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg=="], - - "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], - - "supports-hyperlinks": ["supports-hyperlinks@3.2.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig=="], - - "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - - "temp-dir": ["temp-dir@3.0.0", "", {}, "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw=="], - - "tempy": ["tempy@3.1.0", "", { "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", "type-fest": "^2.12.2", "unique-string": "^3.0.0" } }, "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g=="], - - "text-extensions": ["text-extensions@2.4.0", "", {}, "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g=="], - - "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], - - "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], - - "through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="], - - "through2": ["through2@2.0.5", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="], - - "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], - - "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], - - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - - "traverse": ["traverse@0.6.8", "", {}, "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA=="], - - "type-fest": ["type-fest@4.40.0", "", {}, "sha512-ABHZ2/tS2JkvH1PEjxFDTUWC8dB5OsIGZP4IFLhR293GqT5Y5qB1WwL2kMPYhQW9DVgVD8Hd7I8gjwPIf5GFkw=="], - - "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], - - "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], - - "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], - - "unicode-emoji-modifier-base": ["unicode-emoji-modifier-base@1.0.0", "", {}, "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g=="], - - "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], - - "unique-string": ["unique-string@3.0.0", "", { "dependencies": { "crypto-random-string": "^4.0.0" } }, "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ=="], - - "universal-user-agent": ["universal-user-agent@7.0.2", "", {}, "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="], - - "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], - - "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], - - "url-join": ["url-join@5.0.0", "", {}, "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA=="], - - "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - - "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], - - "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - - "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], - - "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], - - "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], - - "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - - "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - - "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - - "yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="], - - "yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="], - - "@commitlint/config-validator/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], - - "@commitlint/is-ignored/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], - - "@commitlint/parse/conventional-changelog-angular": ["conventional-changelog-angular@7.0.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ=="], - - "@commitlint/parse/conventional-commits-parser": ["conventional-commits-parser@5.0.0", "", { "dependencies": { "JSONStream": "^1.3.5", "is-text-path": "^2.0.0", "meow": "^12.0.1", "split2": "^4.0.0" }, "bin": { "conventional-commits-parser": "cli.mjs" } }, "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA=="], - - "@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], - - "@octokit/plugin-throttling/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], - - "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], - - "@rushstack/node-core-library/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], - - "@semantic-release/github/@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], - - "@semantic-release/github/aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], - - "@semantic-release/npm/@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], - - "@semantic-release/npm/aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], - - "@semantic-release/npm/execa": ["execa@9.5.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.3", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.0", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.0.0" } }, "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q=="], - - "ajv-formats/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], - - "cli-highlight/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - - "cli-highlight/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], - - "conventional-changelog-writer/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], - - "cosmiconfig/parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], - - "crypto-random-string/type-fest": ["type-fest@1.4.0", "", {}, "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="], - - "env-ci/execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], - - "execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], - - "find-up/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], - - "git-raw-commits/meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], - - "git-raw-commits/split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], - - "global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="], - - "globby/path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="], - - "hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], - - "js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], - - "load-json-file/parse-json": ["parse-json@4.0.0", "", { "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw=="], - - "normalize-package-data/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], - - "npm/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - - "npm/@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], - - "npm/@isaacs/string-locale-compare": ["@isaacs/string-locale-compare@1.1.0", "", { "bundled": true }, "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ=="], - - "npm/@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="], - - "npm/@npmcli/arborist": ["@npmcli/arborist@8.0.0", "", { "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^4.0.0", "@npmcli/installed-package-contents": "^3.0.0", "@npmcli/map-workspaces": "^4.0.1", "@npmcli/metavuln-calculator": "^8.0.0", "@npmcli/name-from-folder": "^3.0.0", "@npmcli/node-gyp": "^4.0.0", "@npmcli/package-json": "^6.0.1", "@npmcli/query": "^4.0.0", "@npmcli/redact": "^3.0.0", "@npmcli/run-script": "^9.0.1", "bin-links": "^5.0.0", "cacache": "^19.0.1", "common-ancestor-path": "^1.0.1", "hosted-git-info": "^8.0.0", "json-parse-even-better-errors": "^4.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^10.2.2", "minimatch": "^9.0.4", "nopt": "^8.0.0", "npm-install-checks": "^7.1.0", "npm-package-arg": "^12.0.0", "npm-pick-manifest": "^10.0.0", "npm-registry-fetch": "^18.0.1", "pacote": "^19.0.0", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "ssri": "^12.0.0", "treeverse": "^3.0.0", "walk-up-path": "^3.0.1" }, "bundled": true, "bin": { "arborist": "bin/index.js" } }, "sha512-APDXxtXGSftyXibl0dZ3CuZYmmVnkiN3+gkqwXshY4GKC2rof2+Lg0sGuj6H1p2YfBAKd7PRwuMVhu6Pf/nQ/A=="], - - "npm/@npmcli/config": ["@npmcli/config@9.0.0", "", { "dependencies": { "@npmcli/map-workspaces": "^4.0.1", "@npmcli/package-json": "^6.0.1", "ci-info": "^4.0.0", "ini": "^5.0.0", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, "bundled": true }, "sha512-P5Vi16Y+c8E0prGIzX112ug7XxqfaPFUVW/oXAV+2VsxplKZEnJozqZ0xnK8V8w/SEsBf+TXhUihrEIAU4CA5Q=="], - - "npm/@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" }, "bundled": true }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], - - "npm/@npmcli/git": ["@npmcli/git@6.0.3", "", { "dependencies": { "@npmcli/promise-spawn": "^8.0.0", "ini": "^5.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^10.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^5.0.0" } }, "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ=="], - - "npm/@npmcli/installed-package-contents": ["@npmcli/installed-package-contents@3.0.0", "", { "dependencies": { "npm-bundled": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" }, "bin": { "installed-package-contents": "bin/index.js" } }, "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q=="], - - "npm/@npmcli/map-workspaces": ["@npmcli/map-workspaces@4.0.2", "", { "dependencies": { "@npmcli/name-from-folder": "^3.0.0", "@npmcli/package-json": "^6.0.0", "glob": "^10.2.2", "minimatch": "^9.0.0" }, "bundled": true }, "sha512-mnuMuibEbkaBTYj9HQ3dMe6L0ylYW+s/gfz7tBDMFY/la0w9Kf44P9aLn4/+/t3aTR3YUHKoT6XQL9rlicIe3Q=="], - - "npm/@npmcli/metavuln-calculator": ["@npmcli/metavuln-calculator@8.0.1", "", { "dependencies": { "cacache": "^19.0.0", "json-parse-even-better-errors": "^4.0.0", "pacote": "^20.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5" } }, "sha512-WXlJx9cz3CfHSt9W9Opi1PTFc4WZLFomm5O8wekxQZmkyljrBRwATwDxfC9iOXJwYVmfiW1C1dUe0W2aN0UrSg=="], - - "npm/@npmcli/name-from-folder": ["@npmcli/name-from-folder@3.0.0", "", {}, "sha512-61cDL8LUc9y80fXn+lir+iVt8IS0xHqEKwPu/5jCjxQTVoSCmkXvw4vbMrzAMtmghz3/AkiBjhHkDKUH+kf7kA=="], - - "npm/@npmcli/node-gyp": ["@npmcli/node-gyp@4.0.0", "", {}, "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA=="], - - "npm/@npmcli/package-json": ["@npmcli/package-json@6.1.1", "", { "dependencies": { "@npmcli/git": "^6.0.0", "glob": "^10.2.2", "hosted-git-info": "^8.0.0", "json-parse-even-better-errors": "^4.0.0", "proc-log": "^5.0.0", "semver": "^7.5.3", "validate-npm-package-license": "^3.0.4" }, "bundled": true }, "sha512-d5qimadRAUCO4A/Txw71VM7UrRZzV+NPclxz/dc+M6B2oYwjWTjqh8HA/sGQgs9VZuJ6I/P7XIAlJvgrl27ZOw=="], - - "npm/@npmcli/promise-spawn": ["@npmcli/promise-spawn@8.0.2", "", { "dependencies": { "which": "^5.0.0" }, "bundled": true }, "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ=="], - - "npm/@npmcli/query": ["@npmcli/query@4.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-4OIPFb4weUUwkDXJf4Hh1inAn8neBGq3xsH4ZsAaN6FK3ldrFkH7jSpCc7N9xesi0Sp+EBXJ9eGMDrEww2Ztqw=="], - - "npm/@npmcli/redact": ["@npmcli/redact@3.1.1", "", { "bundled": true }, "sha512-3Hc2KGIkrvJWJqTbvueXzBeZlmvoOxc2jyX00yzr3+sNFquJg0N8hH4SAPLPVrkWIRQICVpVgjrss971awXVnA=="], - - "npm/@npmcli/run-script": ["@npmcli/run-script@9.1.0", "", { "dependencies": { "@npmcli/node-gyp": "^4.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", "node-gyp": "^11.0.0", "proc-log": "^5.0.0", "which": "^5.0.0" }, "bundled": true }, "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg=="], - - "npm/@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], - - "npm/@sigstore/bundle": ["@sigstore/bundle@3.1.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.4.0" } }, "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag=="], - - "npm/@sigstore/core": ["@sigstore/core@2.0.0", "", {}, "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg=="], - - "npm/@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.4.1", "", {}, "sha512-7MJXQhIm7dWF9zo7rRtMYh8d2gSnc3+JddeQOTIg6gUN7FjcuckZ9EwGq+ReeQtbbl3Tbf5YqRrWxA1DMfIn+w=="], - - "npm/@sigstore/sign": ["@sigstore/sign@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.4.0", "make-fetch-happen": "^14.0.2", "proc-log": "^5.0.0", "promise-retry": "^2.0.1" } }, "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw=="], - - "npm/@sigstore/tuf": ["@sigstore/tuf@3.1.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.4.0", "tuf-js": "^3.0.1" }, "bundled": true }, "sha512-suVMQEA+sKdOz5hwP9qNcEjX6B45R+hFFr4LAWzbRc5O+U2IInwvay/bpG5a4s+qR35P/JK/PiKiRGjfuLy1IA=="], - - "npm/@sigstore/verify": ["@sigstore/verify@2.1.0", "", { "dependencies": { "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.4.0" } }, "sha512-kAAM06ca4CzhvjIZdONAL9+MLppW3K48wOFy1TbuaWFW/OMfl8JuTgW0Bm02JB1WJGT/ET2eqav0KTEKmxqkIA=="], - - "npm/@tufjs/canonical-json": ["@tufjs/canonical-json@2.0.0", "", {}, "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA=="], - - "npm/@tufjs/models": ["@tufjs/models@3.0.1", "", { "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^9.0.5" } }, "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA=="], - - "npm/abbrev": ["abbrev@3.0.1", "", { "bundled": true }, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], - - "npm/agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="], - - "npm/aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - - "npm/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "npm/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], - - "npm/aproba": ["aproba@2.0.0", "", {}, "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="], - - "npm/archy": ["archy@1.0.0", "", { "bundled": true }, "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw=="], - - "npm/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "npm/bin-links": ["bin-links@5.0.0", "", { "dependencies": { "cmd-shim": "^7.0.0", "npm-normalize-package-bin": "^4.0.0", "proc-log": "^5.0.0", "read-cmd-shim": "^5.0.0", "write-file-atomic": "^6.0.0" } }, "sha512-sdleLVfCjBtgO5cNjA2HVRvWBJAHs4zwenaCPMNJAJU0yNxpzj80IpjOIimkpkr+mhlA+how5poQtt53PygbHA=="], - - "npm/binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], - - "npm/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], - - "npm/cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" }, "bundled": true }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="], - - "npm/chalk": ["chalk@5.4.1", "", { "bundled": true }, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], - - "npm/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], - - "npm/ci-info": ["ci-info@4.2.0", "", { "bundled": true }, "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg=="], - - "npm/cidr-regex": ["cidr-regex@4.1.3", "", { "dependencies": { "ip-regex": "^5.0.0" } }, "sha512-86M1y3ZeQvpZkZejQCcS+IaSWjlDUC+ORP0peScQ4uEUFCZ8bEQVz7NlJHqysoUb6w3zCjx4Mq/8/2RHhMwHYw=="], - - "npm/clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], - - "npm/cli-columns": ["cli-columns@4.0.0", "", { "dependencies": { "string-width": "^4.2.3", "strip-ansi": "^6.0.1" }, "bundled": true }, "sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ=="], - - "npm/cmd-shim": ["cmd-shim@7.0.0", "", {}, "sha512-rtpaCbr164TPPh+zFdkWpCyZuKkjpAzODfaZCf/SVJZzJN+4bHQb/LP3Jzq5/+84um3XXY8r548XiWKSborwVw=="], - - "npm/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], - - "npm/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - - "npm/common-ancestor-path": ["common-ancestor-path@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="], - - "npm/cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], - - "npm/cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], - - "npm/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], - - "npm/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="], - - "npm/eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], - - "npm/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "npm/encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], - - "npm/env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], - - "npm/err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], - - "npm/exponential-backoff": ["exponential-backoff@3.1.2", "", {}, "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA=="], - - "npm/fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", { "bundled": true }, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="], - - "npm/fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="], - - "npm/foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], - - "npm/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], - - "npm/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bundled": true, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], - - "npm/graceful-fs": ["graceful-fs@4.2.11", "", { "bundled": true }, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "npm/hosted-git-info": ["hosted-git-info@8.1.0", "", { "dependencies": { "lru-cache": "^10.0.1" }, "bundled": true }, "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw=="], - - "npm/http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], - - "npm/http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], - - "npm/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - - "npm/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - - "npm/ignore-walk": ["ignore-walk@7.0.0", "", { "dependencies": { "minimatch": "^9.0.0" } }, "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ=="], - - "npm/imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], - - "npm/indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], - - "npm/ini": ["ini@5.0.0", "", { "bundled": true }, "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw=="], - - "npm/init-package-json": ["init-package-json@7.0.2", "", { "dependencies": { "@npmcli/package-json": "^6.0.0", "npm-package-arg": "^12.0.0", "promzard": "^2.0.0", "read": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^6.0.0" }, "bundled": true }, "sha512-Qg6nAQulaOQZjvaSzVLtYRqZmuqOi7gTknqqgdhZy7LV5oO+ppvHWq15tZYzGyxJLTH5BxRTqTa+cPDx2pSD9Q=="], - - "npm/ip-address": ["ip-address@9.0.5", "", { "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" } }, "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g=="], - - "npm/ip-regex": ["ip-regex@5.0.0", "", {}, "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw=="], - - "npm/is-cidr": ["is-cidr@5.1.1", "", { "dependencies": { "cidr-regex": "^4.1.1" }, "bundled": true }, "sha512-AwzRMjtJNTPOgm7xuYZ71715z99t+4yRnSnSzgK5err5+heYi4zMuvmpUadaJ28+KCXCQo8CjUrKQZRWSPmqTQ=="], - - "npm/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], - - "npm/isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="], - - "npm/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "npm/jsbn": ["jsbn@1.1.0", "", {}, "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="], - - "npm/json-parse-even-better-errors": ["json-parse-even-better-errors@4.0.0", "", { "bundled": true }, "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA=="], - - "npm/json-stringify-nice": ["json-stringify-nice@1.1.4", "", {}, "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw=="], - - "npm/jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], - - "npm/just-diff": ["just-diff@6.0.2", "", {}, "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA=="], - - "npm/just-diff-apply": ["just-diff-apply@5.5.0", "", {}, "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw=="], - - "npm/libnpmaccess": ["libnpmaccess@9.0.0", "", { "dependencies": { "npm-package-arg": "^12.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-mTCFoxyevNgXRrvgdOhghKJnCWByBc9yp7zX4u9RBsmZjwOYdUDEBfL5DdgD1/8gahsYnauqIWFbq0iK6tO6CQ=="], - - "npm/libnpmdiff": ["libnpmdiff@7.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0", "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0", "tar": "^6.2.1" }, "bundled": true }, "sha512-MjvsBJL1AT4ofsSsBRse5clxv7gfPbdgzT0VE+xmVTxE8M92T22laeX9vqFhaQKInSeKiZ2L9w/FVhoCCGPdUg=="], - - "npm/libnpmexec": ["libnpmexec@9.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0", "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0", "proc-log": "^5.0.0", "read": "^4.0.0", "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "walk-up-path": "^3.0.1" }, "bundled": true }, "sha512-5dOwgvt0srgrOkwsjNWokx23BvQXEaUo87HWIY+9lymvAto2VSunNS+Ih7WXVwvkJk7cZ0jhS2H3rNK8G9Anxw=="], - - "npm/libnpmfund": ["libnpmfund@6.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0" }, "bundled": true }, "sha512-+7ZTxPyJ0O/Y0xKoEd1CxPCUQ4ldn6EZ2qUMI/E1gJkfzcwb3AdFlSWk1WEXaGBu2+EqMrPf4Xu5lXFWw2Jd3w=="], - - "npm/libnpmhook": ["libnpmhook@11.0.0", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-Xc18rD9NFbRwZbYCQ+UCF5imPsiHSyuQA8RaCA2KmOUo8q4kmBX4JjGWzmZnxZCT8s6vwzmY1BvHNqBGdg9oBQ=="], - - "npm/libnpmorg": ["libnpmorg@7.0.0", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-DcTodX31gDEiFrlIHurBQiBlBO6Var2KCqMVCk+HqZhfQXqUfhKGmFOp0UHr6HR1lkTVM0MzXOOYtUObk0r6Dg=="], - - "npm/libnpmpack": ["libnpmpack@8.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0", "@npmcli/run-script": "^9.0.1", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0" }, "bundled": true }, "sha512-Z5zqR+j8PNOki97D4XnKlekLQjqJYkqCFZeac07XCJYA3aq6O7wYIpn7RqLcNfFm+u3ZsdblY2VQENMoiHA+FQ=="], - - "npm/libnpmpublish": ["libnpmpublish@10.0.1", "", { "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^7.0.0", "npm-package-arg": "^12.0.0", "npm-registry-fetch": "^18.0.1", "proc-log": "^5.0.0", "semver": "^7.3.7", "sigstore": "^3.0.0", "ssri": "^12.0.0" }, "bundled": true }, "sha512-xNa1DQs9a8dZetNRV0ky686MNzv1MTqB3szgOlRR3Fr24x1gWRu7aB9OpLZsml0YekmtppgHBkyZ+8QZlzmEyw=="], - - "npm/libnpmsearch": ["libnpmsearch@8.0.0", "", { "dependencies": { "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-W8FWB78RS3Nkl1gPSHOlF024qQvcoU/e3m9BGDuBfVZGfL4MJ91GXXb04w3zJCGOW9dRQUyWVEqupFjCrgltDg=="], - - "npm/libnpmteam": ["libnpmteam@7.0.0", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-PKLOoVukN34qyJjgEm5DEOnDwZkeVMUHRx8NhcKDiCNJGPl7G/pF1cfBw8yicMwRlHaHkld1FdujOzKzy4AlwA=="], - - "npm/libnpmversion": ["libnpmversion@7.0.0", "", { "dependencies": { "@npmcli/git": "^6.0.1", "@npmcli/run-script": "^9.0.1", "json-parse-even-better-errors": "^4.0.0", "proc-log": "^5.0.0", "semver": "^7.3.7" }, "bundled": true }, "sha512-0xle91R6F8r/Q/4tHOnyKko+ZSquEXNdxwRdKCPv4kC1cOVBMFXRsKKrVtRKtXcFn362U8ZlJefk4Apu00424g=="], - - "npm/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "npm/make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" }, "bundled": true }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="], - - "npm/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" }, "bundled": true }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - - "npm/minipass": ["minipass@7.1.2", "", { "bundled": true }, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], - - "npm/minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], - - "npm/minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="], - - "npm/minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], - - "npm/minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" }, "bundled": true }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], - - "npm/minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], - - "npm/minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], - - "npm/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], - - "npm/ms": ["ms@2.1.3", "", { "bundled": true }, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - - "npm/mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], - - "npm/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - - "npm/node-gyp": ["node-gyp@11.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bundled": true, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-T0S1zqskVUSxcsSTkAsLc7xCycrRYmtDHadDinzocrThjyQCn5kMlEBSj6H4qDbgsIOSLmmlRIeb0lZXj+UArA=="], - - "npm/nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bundled": true, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="], - - "npm/normalize-package-data": ["normalize-package-data@7.0.0", "", { "dependencies": { "hosted-git-info": "^8.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "bundled": true }, "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA=="], - - "npm/npm-audit-report": ["npm-audit-report@6.0.0", "", { "bundled": true }, "sha512-Ag6Y1irw/+CdSLqEEAn69T8JBgBThj5mw0vuFIKeP7hATYuQuS5jkMjK6xmVB8pr7U4g5Audbun0lHhBDMIBRA=="], - - "npm/npm-bundled": ["npm-bundled@4.0.0", "", { "dependencies": { "npm-normalize-package-bin": "^4.0.0" } }, "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA=="], - - "npm/npm-install-checks": ["npm-install-checks@7.1.1", "", { "dependencies": { "semver": "^7.1.1" }, "bundled": true }, "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg=="], - - "npm/npm-normalize-package-bin": ["npm-normalize-package-bin@4.0.0", "", {}, "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w=="], - - "npm/npm-package-arg": ["npm-package-arg@12.0.2", "", { "dependencies": { "hosted-git-info": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^6.0.0" }, "bundled": true }, "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA=="], - - "npm/npm-packlist": ["npm-packlist@9.0.0", "", { "dependencies": { "ignore-walk": "^7.0.0" } }, "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ=="], - - "npm/npm-pick-manifest": ["npm-pick-manifest@10.0.0", "", { "dependencies": { "npm-install-checks": "^7.1.0", "npm-normalize-package-bin": "^4.0.0", "npm-package-arg": "^12.0.0", "semver": "^7.3.5" }, "bundled": true }, "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ=="], - - "npm/npm-profile": ["npm-profile@11.0.1", "", { "dependencies": { "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0" }, "bundled": true }, "sha512-HP5Cw9WHwFS9vb4fxVlkNAQBUhVL5BmW6rAR+/JWkpwqcFJid7TihKUdYDWqHl0NDfLd0mpucheGySqo8ysyfw=="], - - "npm/npm-registry-fetch": ["npm-registry-fetch@18.0.2", "", { "dependencies": { "@npmcli/redact": "^3.0.0", "jsonparse": "^1.3.1", "make-fetch-happen": "^14.0.0", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^12.0.0", "proc-log": "^5.0.0" }, "bundled": true }, "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ=="], - - "npm/npm-user-validate": ["npm-user-validate@3.0.0", "", { "bundled": true }, "sha512-9xi0RdSmJ4mPYTC393VJPz1Sp8LyCx9cUnm/L9Qcb3cFO8gjT4mN20P9FAsea8qDHdQ7LtcN8VLh2UT47SdKCw=="], - - "npm/p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" }, "bundled": true }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], - - "npm/package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], - - "npm/pacote": ["pacote@19.0.1", "", { "dependencies": { "@npmcli/git": "^6.0.0", "@npmcli/installed-package-contents": "^3.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", "@npmcli/run-script": "^9.0.0", "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^12.0.0", "npm-packlist": "^9.0.0", "npm-pick-manifest": "^10.0.0", "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "sigstore": "^3.0.0", "ssri": "^12.0.0", "tar": "^6.1.11" }, "bundled": true, "bin": { "pacote": "bin/index.js" } }, "sha512-zIpxWAsr/BvhrkSruspG8aqCQUUrWtpwx0GjiRZQhEM/pZXrigA32ElN3vTcCPUDOFmHr6SFxwYrvVUs5NTEUg=="], - - "npm/parse-conflict-json": ["parse-conflict-json@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "bundled": true }, "sha512-37CN2VtcuvKgHUs8+0b1uJeEsbGn61GRHz469C94P5xiOoqpDYJYwjg4RY9Vmz39WyZAVkR5++nbJwLMIgOCnQ=="], - - "npm/path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], - - "npm/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - - "npm/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], - - "npm/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], - - "npm/proc-log": ["proc-log@5.0.0", "", { "bundled": true }, "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ=="], - - "npm/proggy": ["proggy@3.0.0", "", {}, "sha512-QE8RApCM3IaRRxVzxrjbgNMpQEX6Wu0p0KBeoSiSEw5/bsGwZHsshF4LCxH2jp/r6BU+bqA3LrMDEYNfJnpD8Q=="], - - "npm/promise-all-reject-late": ["promise-all-reject-late@1.0.1", "", {}, "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw=="], - - "npm/promise-call-limit": ["promise-call-limit@3.0.2", "", {}, "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw=="], - - "npm/promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], - - "npm/promzard": ["promzard@2.0.0", "", { "dependencies": { "read": "^4.0.0" } }, "sha512-Ncd0vyS2eXGOjchIRg6PVCYKetJYrW1BSbbIo+bKdig61TB6nH2RQNF2uP+qMpsI73L/jURLWojcw8JNIKZ3gg=="], - - "npm/qrcode-terminal": ["qrcode-terminal@0.12.0", "", { "bundled": true, "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ=="], - - "npm/read": ["read@4.1.0", "", { "dependencies": { "mute-stream": "^2.0.0" }, "bundled": true }, "sha512-uRfX6K+f+R8OOrYScaM3ixPY4erg69f8DN6pgTvMcA9iRc8iDhwrA4m3Yu8YYKsXJgVvum+m8PkRboZwwuLzYA=="], - - "npm/read-cmd-shim": ["read-cmd-shim@5.0.0", "", {}, "sha512-SEbJV7tohp3DAAILbEMPXavBjAnMN0tVnh4+9G8ihV4Pq3HYF9h8QNez9zkJ1ILkv9G2BjdzwctznGZXgu/HGw=="], - - "npm/read-package-json-fast": ["read-package-json-fast@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" } }, "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg=="], - - "npm/retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], - - "npm/safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], - - "npm/semver": ["semver@7.7.1", "", { "bundled": true, "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], - - "npm/shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], - - "npm/shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - - "npm/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - - "npm/sigstore": ["sigstore@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.4.0", "@sigstore/sign": "^3.1.0", "@sigstore/tuf": "^3.1.0", "@sigstore/verify": "^2.1.0" } }, "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q=="], - - "npm/smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], - - "npm/socks": ["socks@2.8.4", "", { "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" } }, "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ=="], - - "npm/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], - - "npm/spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], - - "npm/spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], - - "npm/spdx-expression-parse": ["spdx-expression-parse@4.0.0", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" }, "bundled": true }, "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ=="], - - "npm/spdx-license-ids": ["spdx-license-ids@3.0.21", "", {}, "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg=="], - - "npm/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], - - "npm/ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], - - "npm/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "npm/string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "npm/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "npm/strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "npm/supports-color": ["supports-color@9.4.0", "", { "bundled": true }, "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw=="], - - "npm/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "bundled": true }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], - - "npm/text-table": ["text-table@0.2.0", "", { "bundled": true }, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], - - "npm/tiny-relative-date": ["tiny-relative-date@1.3.0", "", { "bundled": true }, "sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A=="], - - "npm/tinyglobby": ["tinyglobby@0.2.12", "", { "dependencies": { "fdir": "^6.4.3", "picomatch": "^4.0.2" } }, "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww=="], - - "npm/treeverse": ["treeverse@3.0.0", "", { "bundled": true }, "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ=="], - - "npm/tuf-js": ["tuf-js@3.0.1", "", { "dependencies": { "@tufjs/models": "3.0.1", "debug": "^4.3.6", "make-fetch-happen": "^14.0.1" } }, "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA=="], - - "npm/unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="], - - "npm/unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="], - - "npm/util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - - "npm/validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], - - "npm/validate-npm-package-name": ["validate-npm-package-name@6.0.0", "", { "bundled": true }, "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg=="], - - "npm/walk-up-path": ["walk-up-path@3.0.1", "", {}, "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA=="], - - "npm/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bundled": true, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], - - "npm/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], - - "npm/wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "npm/write-file-atomic": ["write-file-atomic@6.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" }, "bundled": true }, "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ=="], - - "npm/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - - "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="], - - "pkg-conf/find-up": ["find-up@2.1.0", "", { "dependencies": { "locate-path": "^2.0.0" } }, "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ=="], - - "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], - - "read-pkg/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], - - "semantic-release/@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], - - "semantic-release/aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], - - "semantic-release/execa": ["execa@9.5.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.3", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.0", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.0.0" } }, "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q=="], - - "semantic-release/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], - - "semantic-release/p-reduce": ["p-reduce@3.0.0", "", {}, "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q=="], - - "signale/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], - - "signale/figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA=="], - - "strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "supports-hyperlinks/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], - - "tempy/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], - - "tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], - - "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - - "@commitlint/parse/conventional-commits-parser/meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], - - "@commitlint/parse/conventional-commits-parser/split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], - - "@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - - "@octokit/plugin-throttling/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - - "@semantic-release/github/aggregate-error/clean-stack": ["clean-stack@5.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ=="], - - "@semantic-release/github/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], - - "@semantic-release/npm/aggregate-error/clean-stack": ["clean-stack@5.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ=="], - - "@semantic-release/npm/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], - - "@semantic-release/npm/execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], - - "@semantic-release/npm/execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - - "@semantic-release/npm/execa/human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], - - "@semantic-release/npm/execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], - - "@semantic-release/npm/execa/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], - - "@semantic-release/npm/execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - - "@semantic-release/npm/execa/strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], - - "cli-highlight/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - - "cli-highlight/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], - - "cli-highlight/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], - - "cli-highlight/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], - - "env-ci/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], - - "env-ci/execa/human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], - - "env-ci/execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], - - "env-ci/execa/npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], - - "env-ci/execa/onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], - - "env-ci/execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - - "env-ci/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], - - "normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "npm/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], - - "npm/@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], - - "npm/@npmcli/metavuln-calculator/pacote": ["pacote@20.0.0", "", { "dependencies": { "@npmcli/git": "^6.0.0", "@npmcli/installed-package-contents": "^3.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", "@npmcli/run-script": "^9.0.0", "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^12.0.0", "npm-packlist": "^9.0.0", "npm-pick-manifest": "^10.0.0", "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "sigstore": "^3.0.0", "ssri": "^12.0.0", "tar": "^6.1.11" }, "bin": { "pacote": "bin/index.js" } }, "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A=="], - - "npm/cacache/p-map": ["p-map@7.0.3", "", {}, "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA=="], - - "npm/cacache/tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], - - "npm/cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - - "npm/minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "npm/minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "npm/minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "npm/node-gyp/tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], - - "npm/spdx-correct/spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], - - "npm/tar/fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="], - - "npm/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], - - "npm/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], - - "npm/validate-npm-package-license/spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], - - "npm/wrap-ansi/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], - - "npm/wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], - - "npm/wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - - "pkg-conf/find-up/locate-path": ["locate-path@2.0.0", "", { "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA=="], - - "semantic-release/aggregate-error/clean-stack": ["clean-stack@5.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ=="], - - "semantic-release/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], - - "semantic-release/execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], - - "semantic-release/execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - - "semantic-release/execa/human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], - - "semantic-release/execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], - - "semantic-release/execa/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], - - "semantic-release/execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - - "semantic-release/execa/strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], - - "signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], - - "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], - - "signale/figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], - - "wrap-ansi/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], - - "@semantic-release/npm/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - - "cli-highlight/chalk/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], - - "env-ci/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - - "env-ci/execa/onetime/mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], - - "npm/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "npm/@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], - - "npm/cacache/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - - "npm/cacache/tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], - - "npm/cacache/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], - - "npm/cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - - "npm/node-gyp/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - - "npm/node-gyp/tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], - - "npm/node-gyp/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], - - "npm/tar/fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "npm/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "npm/wrap-ansi/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "npm/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], - - "pkg-conf/find-up/locate-path/p-locate": ["p-locate@2.0.0", "", { "dependencies": { "p-limit": "^1.1.0" } }, "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg=="], - - "pkg-conf/find-up/locate-path/path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], - - "semantic-release/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - - "signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], - - "wrap-ansi/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - - "cli-highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - - "pkg-conf/find-up/locate-path/p-locate/p-limit": ["p-limit@1.3.0", "", { "dependencies": { "p-try": "^1.0.0" } }, "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q=="], - } -} diff --git a/examples/read_game_memory.ts b/examples/read_game_memory.ts index 16651c9..1ba5eed 100644 --- a/examples/read_game_memory.ts +++ b/examples/read_game_memory.ts @@ -1,4 +1,5 @@ -import { openProcess, closeProcess, readMemory } from '../lib'; +// @ts-ignore +import { openProcess, closeProcess, readMemory } from 'memoryprocess'; const PROCESS_NAME = "DarkSoulsRemastered.exe"; diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..b7a0dfb --- /dev/null +++ b/index.ts @@ -0,0 +1,2 @@ +export { default } from './src/memoryprocess'; +export * from './src/types'; \ No newline at end of file diff --git a/lefthook.yml b/lefthook.yml index 604b7b6..2901e45 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -2,16 +2,16 @@ pre-commit: commands: check: glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}" - run: bunx @biomejs/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} + run: npx @biomejs/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} stage_fixed: true commit-msg: commands: lint-commit-msg: - run: bunx commitlint --edit {1} + run: npx commitlint --edit {1} pre-push: commands: check: glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}" - run: bunx @biomejs/biome check --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {push_files} \ No newline at end of file + run: npx @biomejs/biome check --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {push_files} diff --git a/native/dll.h b/native/dll.h index e35f889..26655fc 100644 --- a/native/dll.h +++ b/native/dll.h @@ -8,7 +8,7 @@ #include namespace dll { - inline bool inject(HANDLE handle, std::string dllPath, const char** errorMessage, LPDWORD moduleHandle) { + bool inject(HANDLE handle, std::string dllPath, const char** errorMessage, LPDWORD moduleHandle) { // allocate space in target process memory for DLL path LPVOID targetProcessPath = VirtualAllocEx(handle, NULL, dllPath.length() + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); @@ -52,7 +52,7 @@ namespace dll { return *moduleHandle > 0; } - inline bool unload(HANDLE handle, const char** errorMessage, HMODULE moduleHandle) { + bool unload(HANDLE handle, const char** errorMessage, HMODULE moduleHandle) { HMODULE kernel32 = LoadLibrary("kernel32"); if (kernel32 == 0) { diff --git a/native/functions.h b/native/functions.h index 31a7d06..286d27d 100644 --- a/native/functions.h +++ b/native/functions.h @@ -62,9 +62,9 @@ namespace functions { LPVOID address = functions::reserveString(pHandle, value.c_str(), value.length()); // Little endian representation - for (int i = 0; i < sizeof(void*); i++) { - unsigned char shifted = ((uintptr_t)address >> (i * 8)) & 0xFF; - argShellcode.push_back(shifted); + for (int i = 0; i < sizeof(LPVOID); i++) { + unsigned char byte = ((reinterpret_cast(address) >> (i * 8)) & 0xFF); + argShellcode.push_back(byte); } continue; @@ -113,9 +113,9 @@ namespace functions { callShellcode.push_back(0xA3); } - for (int i = 0; i < sizeof(void*); i++) { - unsigned char shifted = ((uintptr_t)returnValuePointer >> (i * 8)) & 0xFF; - callShellcode.push_back(shifted); + for (int i = 0; i < sizeof(LPVOID); i++) { + unsigned char byte = ((reinterpret_cast(returnValuePointer) >> (i * 8)) & 0xFF); + callShellcode.push_back(byte); } } diff --git a/native/memoryprocess.cc b/native/memoryprocess.cc index a264fba..b70c6c8 100644 --- a/native/memoryprocess.cc +++ b/native/memoryprocess.cc @@ -1,137 +1,1605 @@ -#include "process.h" +#include +#include +#include +#include #include "module.h" +#include "process.h" +#include "memoryprocess.h" #include "memory.h" -#include - -process proc; -memory memory; - -extern "C" { - __declspec(dllexport) const char* openProcess(const char* processName) { - const char* errorMessage = nullptr; - auto result = proc.openProcess(processName, &errorMessage); - - static char buffer[1024]; - snprintf(buffer, sizeof(buffer), - "{\"dwSize\":%lu,\"th32ProcessID\":%lu,\"cntThreads\":%lu,\"th32ParentProcessID\":%lu," - "\"pcPriClassBase\":%ld,\"szExeFile\":\"%s\",\"handle\":%llu,\"modBaseAddr\":%llu}", - result.process.dwSize, - result.process.th32ProcessID, - result.process.cntThreads, - result.process.th32ParentProcessID, - result.process.pcPriClassBase, - result.process.szExeFile, - (unsigned long long)result.handle, - (unsigned long long)module::getBaseAddress(result.process.szExeFile, result.process.th32ProcessID) - ); - - return buffer; +#include "pattern.h" +#include "functions.h" +#include "dll.h" +#include "debugger.h" + +#pragma comment(lib, "psapi.lib") +#pragma comment(lib, "onecore.lib") + + +process Process; +// module Module; +memory Memory; +pattern Pattern; +// functions Functions; + +struct Vector3 { + float x, y, z; +}; + +struct Vector4 { + float w, x, y, z; +}; + +Napi::Value openProcess(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 1 && args.Length() != 2) { + Napi::Error::New(env, "requires 1 argument, or 2 arguments if a callback is being used").ThrowAsJavaScriptException(); + return env.Null(); } - // Vector3 and Vector4 structures for memory reading - struct Vector3 { - float x, y, z; - }; + if (!args[0].IsString() && !args[0].IsNumber()) { + Napi::Error::New(env, "first argument must be a string or a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 2 && !args[1].IsFunction()) { + Napi::Error::New(env, "second argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + // Define error message that may be set by the function that opens the process + const char* errorMessage = ""; + + process::Pair pair; + + if (args[0].IsString()) { + std::string processName(args[0].As().Utf8Value()); + pair = Process.openProcess(processName.c_str(), &errorMessage); + + // In case it failed to open, let's keep retrying + // while(!strcmp(process.szExeFile, "")) { + // process = Process.openProcess((char*) *(processName), &errorMessage); + // }; + } + + if (args[0].IsNumber()) { + pair = Process.openProcess(args[0].As().Uint32Value(), &errorMessage); + + // In case it failed to open, let's keep retrying + // while(!strcmp(process.szExeFile, "")) { + // process = Process.openProcess(info[0].As().Uint32Value(), &errorMessage); + // }; + } + + // If an error message was returned from the function that opens the process, throw the error. + // Only throw an error if there is no callback (if there's a callback, the error is passed there). + if (strcmp(errorMessage, "") && args.Length() != 2) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + // Create a v8 Object (JSON) to store the process information + Napi::Object processInfo = Napi::Object::New(env); + + processInfo.Set(Napi::String::New(env, "dwSize"), Napi::Value::From(env, (int)pair.process.dwSize)); + processInfo.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)pair.process.th32ProcessID)); + processInfo.Set(Napi::String::New(env, "cntThreads"), Napi::Value::From(env, (int)pair.process.cntThreads)); + processInfo.Set(Napi::String::New(env, "th32ParentProcessID"), Napi::Value::From(env, (int)pair.process.th32ParentProcessID)); + processInfo.Set(Napi::String::New(env, "pcPriClassBase"), Napi::Value::From(env, (int)pair.process.pcPriClassBase)); + processInfo.Set(Napi::String::New(env, "szExeFile"), Napi::String::New(env, pair.process.szExeFile)); + processInfo.Set(Napi::String::New(env, "handle"), Napi::Value::From(env, (uintptr_t)pair.handle)); + + DWORD64 base = module::getBaseAddress(pair.process.szExeFile, pair.process.th32ProcessID); + processInfo.Set(Napi::String::New(env, "modBaseAddr"), Napi::Value::From(env, (uintptr_t)base)); + + // openProcess can either take one argument or can take + // two arguments for asychronous use (second argument is the callback) + if (args.Length() == 2) { + // Callback to let the user handle with the information + Napi::Function callback = args[1].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), processInfo }); + return env.Null(); + } else { + // return JSON + return processInfo; + } +} + +Napi::Value closeHandle(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + BOOL success = CloseHandle((HANDLE)args[0].As().Int64Value()); + return Napi::Boolean::New(env, success); +} + +Napi::Value getProcesses(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() > 1) { + Napi::Error::New(env, "requires either 0 arguments or 1 argument if a callback is being used").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 1 && !args[0].IsFunction()) { + Napi::Error::New(env, "first argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + // Define error message that may be set by the function that gets the processes + const char* errorMessage = ""; + + std::vector processEntries = Process.getProcesses(&errorMessage); + + // If an error message was returned from the function that gets the processes, throw the error. + // Only throw an error if there is no callback (if there's a callback, the error is passed there). + if (strcmp(errorMessage, "") && args.Length() != 1) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + // Creates v8 array with the size being that of the processEntries vector processes is an array of JavaScript objects + Napi::Array processes = Napi::Array::New(env, processEntries.size()); + + // Loop over all processes found + for (std::vector::size_type i = 0; i != processEntries.size(); i++) { + // Create a v8 object to store the current process' information + Napi::Object process = Napi::Object::New(env); + + process.Set(Napi::String::New(env, "cntThreads"), Napi::Value::From(env, (int)processEntries[i].cntThreads)); + process.Set(Napi::String::New(env, "szExeFile"), Napi::String::New(env, processEntries[i].szExeFile)); + process.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)processEntries[i].th32ProcessID)); + process.Set(Napi::String::New(env, "th32ParentProcessID"), Napi::Value::From(env, (int)processEntries[i].th32ParentProcessID)); + process.Set(Napi::String::New(env, "pcPriClassBase"), Napi::Value::From(env, (int)processEntries[i].pcPriClassBase)); + + // Push the object to the array + processes.Set(i, process); + } + + /* getProcesses can either take no arguments or one argument + one argument is for asychronous use (the callback) */ + if (args.Length() == 1) { + // Callback to let the user handle with the information + Napi::Function callback = args[0].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), processes }); + return env.Null(); + } else { + // return JSON + return processes; + } +} + +Napi::Value getModules(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 1 && args.Length() != 2) { + Napi::Error::New(env, "requires 1 argument, or 2 arguments if a callback is being used").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber()) { + Napi::Error::New(env, "first argument must be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 2 && !args[1].IsFunction()) { + Napi::Error::New(env, "first argument must be a number, second argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + // Define error message that may be set by the function that gets the modules + const char* errorMessage = ""; + + std::vector moduleEntries = module::getModules(args[0].As().Int32Value(), &errorMessage); + + // If an error message was returned from the function getting the modules, throw the error. + // Only throw an error if there is no callback (if there's a callback, the error is passed there). + if (strcmp(errorMessage, "") && args.Length() != 2) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + // Creates v8 array with the size being that of the moduleEntries vector + // modules is an array of JavaScript objects + Napi::Array modules = Napi::Array::New(env, moduleEntries.size()); + + // Loop over all modules found + for (std::vector::size_type i = 0; i != moduleEntries.size(); i++) { + // Create a v8 object to store the current module's information + Napi::Object module = Napi::Object::New(env); + + module.Set(Napi::String::New(env, "modBaseAddr"), Napi::Value::From(env, (uintptr_t)moduleEntries[i].modBaseAddr)); + module.Set(Napi::String::New(env, "modBaseSize"), Napi::Value::From(env, (int)moduleEntries[i].modBaseSize)); + module.Set(Napi::String::New(env, "szExePath"), Napi::String::New(env, moduleEntries[i].szExePath)); + module.Set(Napi::String::New(env, "szModule"), Napi::String::New(env, moduleEntries[i].szModule)); + module.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)moduleEntries[i].th32ProcessID)); + module.Set(Napi::String::New(env, "GlblcntUsage"), Napi::Value::From(env, (int)moduleEntries[i].GlblcntUsage)); + + // Push the object to the array + modules.Set(i, module); + } + + // getModules can either take one argument or two arguments + // one/two arguments is for asychronous use (the callback) + if (args.Length() == 2) { + // Callback to let the user handle with the information + Napi::Function callback = args[1].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), modules }); + return env.Null(); + } else { + // return JSON + return modules; + } +} + +Napi::Value findModule(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 1 && args.Length() != 2 && args.Length() != 3) { + Napi::Error::New(env, "requires 1 argument, 2 arguments, or 3 arguments if a callback is being used").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsString() && !args[1].IsNumber()) { + Napi::Error::New(env, "first argument must be a string, second argument must be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 3 && !args[2].IsFunction()) { + Napi::Error::New(env, "third argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } - struct Vector4 { - float w, x, y, z; + std::string moduleName(args[0].As().Utf8Value()); + + // Define error message that may be set by the function that gets the modules + const char* errorMessage = ""; + + MODULEENTRY32 module = module::findModule(moduleName.c_str(), args[1].As().Int32Value(), &errorMessage); + + // If an error message was returned from the function getting the module, throw the error. + // Only throw an error if there is no callback (if there's a callback, the error is passed there). + if (strcmp(errorMessage, "") && args.Length() != 3) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + // In case it failed to open, let's keep retrying + while (!strcmp(module.szExePath, "")) { + module = module::findModule(moduleName.c_str(), args[1].As().Int32Value(), &errorMessage); }; - __declspec(dllexport) int readMemory(unsigned long long handle, unsigned long long address, const char* dataType) { - // For simple numeric types, we'll return the value directly - // For complex types, we'll need to handle them differently in the JS side - - // Cast handle to HANDLE (void*) safely using intptr_t as an intermediate type - HANDLE hProcess = (HANDLE)(intptr_t)handle; - DWORD64 memAddress = (DWORD64)address; - - if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { - return (int)memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { - return (int)memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { - return (int)memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { - return (int)memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { - return memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { - return (int)memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "int64") || !strcmp(dataType, "long long")) { - return memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "uint64") || !strcmp(dataType, "ulong long")) { - return (int)memory.readMemory(hProcess, memAddress); - - } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { - return memory.readMemory(hProcess, memAddress) ? 1 : 0; - - } else if (!strcmp(dataType, "float")) { - // For float, we'll reinterpret the bits as an int - float result = memory.readMemory(hProcess, memAddress); - return *(int*)&result; - + // Create a v8 Object (JSON) to store the process information + Napi::Object moduleInfo = Napi::Object::New(env); + + moduleInfo.Set(Napi::String::New(env, "modBaseAddr"), Napi::Value::From(env, (uintptr_t)module.modBaseAddr)); + moduleInfo.Set(Napi::String::New(env, "modBaseSize"), Napi::Value::From(env, (int)module.modBaseSize)); + moduleInfo.Set(Napi::String::New(env, "szExePath"), Napi::String::New(env, module.szExePath)); + moduleInfo.Set(Napi::String::New(env, "szModule"), Napi::String::New(env, module.szModule)); + moduleInfo.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)module.th32ProcessID)); + moduleInfo.Set(Napi::String::New(env, "GlblcntUsage"), Napi::Value::From(env, (int)module.GlblcntUsage)); + + // findModule can either take one or two arguments, + // three arguments for asychronous use (third argument is the callback) + if (args.Length() == 3) { + // Callback to let the user handle with the information + Napi::Function callback = args[2].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), moduleInfo }); + return env.Null(); + } else { + // return JSON + return moduleInfo; + } +} + +Napi::Value readMemory(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 3 && args.Length() != 4) { + Napi::Error::New(env, "requires 3 arguments, or 4 arguments if a callback is being used").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() && !args[1].IsNumber() && !args[2].IsString()) { + Napi::Error::New(env, "first and second argument must be a number, third argument must be a string").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 4 && !args[3].IsFunction()) { + Napi::Error::New(env, "fourth argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string dataTypeArg(args[2].As().Utf8Value()); + const char* dataType = dataTypeArg.c_str(); + + // Define the error message that will be set if no data type is recognised + const char* errorMessage = ""; + Napi::Value retVal = env.Null(); + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + + DWORD64 address; + if (args[1].As().IsBigInt()) { + bool lossless; + address = args[1].As().Uint64Value(&lossless); + } else { + address = args[1].As().Int64Value(); + } + + if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { + + int8_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { + + uint8_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { + + int16_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { + + uint16_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { + + int32_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { + + uint32_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "int64")) { + + int64_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, Napi::BigInt::New(env, result)); + + } else if (!strcmp(dataType, "uint64")) { + + uint64_t result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, Napi::BigInt::New(env, result)); + + } else if (!strcmp(dataType, "float")) { + + float result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "double")) { + + double result = Memory.readMemory(handle, address); + retVal = Napi::Value::From(env, result); + + } else if (!strcmp(dataType, "ptr") || !strcmp(dataType, "pointer")) { + + intptr_t result = Memory.readMemory(handle, address); + + if (sizeof(intptr_t) == 8) { + retVal = Napi::Value::From(env, Napi::BigInt::New(env, (int64_t) result)); + } else { + retVal = Napi::Value::From(env, result); + } + + } else if (!strcmp(dataType, "uptr") || !strcmp(dataType, "upointer")) { + + uintptr_t result = Memory.readMemory(handle, address); + + if (sizeof(uintptr_t) == 8) { + retVal = Napi::Value::From(env, Napi::BigInt::New(env, (uint64_t) result)); } else { - // For unsupported types in this simple implementation, return 0 - // More complex types would need special handling on the JS side - return 0; + retVal = Napi::Value::From(env, result); } + + } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { + + bool result = Memory.readMemory(handle, address); + retVal = Napi::Boolean::New(env, result); + + } else if (!strcmp(dataType, "string") || !strcmp(dataType, "str")) { + + std::string str; + if (!Memory.readString(handle, address, &str)) { + errorMessage = "unable to read string"; + } else { + retVal = Napi::String::New(env, str); + } + + } else if (!strcmp(dataType, "vector3") || !strcmp(dataType, "vec3")) { + + Vector3 result = Memory.readMemory(handle, address); + Napi::Object moduleInfo = Napi::Object::New(env); + moduleInfo.Set(Napi::String::New(env, "x"), Napi::Value::From(env, result.x)); + moduleInfo.Set(Napi::String::New(env, "y"), Napi::Value::From(env, result.y)); + moduleInfo.Set(Napi::String::New(env, "z"), Napi::Value::From(env, result.z)); + retVal = moduleInfo; + + } else if (!strcmp(dataType, "vector4") || !strcmp(dataType, "vec4")) { + + Vector4 result = Memory.readMemory(handle, address); + Napi::Object moduleInfo = Napi::Object::New(env); + moduleInfo.Set(Napi::String::New(env, "w"), Napi::Value::From(env, result.w)); + moduleInfo.Set(Napi::String::New(env, "x"), Napi::Value::From(env, result.x)); + moduleInfo.Set(Napi::String::New(env, "y"), Napi::Value::From(env, result.y)); + moduleInfo.Set(Napi::String::New(env, "z"), Napi::Value::From(env, result.z)); + retVal = moduleInfo; + + } else { + errorMessage = "unexpected data type"; + } + + if (strcmp(errorMessage, "") && args.Length() != 4) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 4) { + Napi::Function callback = args[3].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), retVal }); + return env.Null(); + } else { + return retVal; + } +} + +Napi::Value readBuffer(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 3 && args.Length() != 4) { + Napi::Error::New(env, "requires 3 arguments, or 4 arguments if a callback is being used").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() && !args[1].IsNumber() && !args[2].IsNumber()) { + Napi::Error::New(env, "first, second and third arguments must be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 4 && !args[3].IsFunction()) { + Napi::Error::New(env, "fourth argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + + DWORD64 address; + if (args[1].As().IsBigInt()) { + bool lossless; + address = args[1].As().Uint64Value(&lossless); + } else { + address = args[1].As().Int64Value(); + } + + SIZE_T size = args[2].As().Int64Value(); + + // To fix the memory leak problem that was happening here, we need to release the + // temporary buffer we create after we're done creating a Napi::Buffer from it. + // Napi::Buffer::New doesn't free the memory, so it has be done manually + // but it can segfault when the memory is freed before being accessed. + // The solution is to use Napi::Buffer::Copy, and then we can manually free it. + // + // see: https://github.com/nodejs/node/issues/40936 + // see: https://sagivo.com/2015/09/30/Go-Native-Calling-C-From-NodeJS.html + char* data = (char*) malloc(sizeof(char) * size); + Memory.readBuffer(handle, address, size, data); + + Napi::Buffer buffer = Napi::Buffer::Copy(env, data, size); + free(data); + + if (args.Length() == 4) { + Napi::Function callback = args[3].As(); + callback.Call(env.Global(), { Napi::String::New(env, ""), buffer }); + return env.Null(); + } else { + return buffer; + } +} + +Napi::Value writeMemory(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 4) { + Napi::Error::New(env, "requires 4 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() && !args[1].IsNumber() && !args[3].IsString()) { + Napi::Error::New(env, "first and second argument must be a number, third argument must be a string").ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string dataTypeArg(args[3].As().Utf8Value()); + const char* dataType = dataTypeArg.c_str(); + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + + DWORD64 address; + if (args[1].As().IsBigInt()) { + bool lossless; + address = args[1].As().Uint64Value(&lossless); + } else { + address = args[1].As().Int64Value(); } - __declspec(dllexport) void writeMemory(HANDLE handle, DWORD64 address, const char* dataType, const void* valuePtr) { - // This function assumes valuePtr points to data of the type specified by dataType. - // The caller is responsible for ensuring type correctness and memory validity. - - if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "int64")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "uint64")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "float")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "double")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "ptr") || !strcmp(dataType, "pointer")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "uptr") || !strcmp(dataType, "upointer")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "string") || !strcmp(dataType, "str")) { - // Assumes valuePtr points to a null-terminated C-style string. - // Writes the string content including the null terminator. - const char* strValue = static_cast(valuePtr); - memory.writeMemory(handle, address, strValue, strlen(strValue) + 1); - } else if (!strcmp(dataType, "vector3") || !strcmp(dataType, "vec3")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); - } else if (!strcmp(dataType, "vector4") || !strcmp(dataType, "vec4")) { - memory.writeMemory(handle, address, *(static_cast(valuePtr))); + if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { + + Memory.writeMemory(handle, address, args[2].As().Int32Value()); + + } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { + + Memory.writeMemory(handle, address, args[2].As().Uint32Value()); + + } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { + + Memory.writeMemory(handle, address, args[2].As().Int32Value()); + + } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { + + Memory.writeMemory(handle, address, args[2].As().Uint32Value()); + + } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { + + Memory.writeMemory(handle, address, args[2].As().Int32Value()); + + } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { + + Memory.writeMemory(handle, address, args[2].As().Uint32Value()); + + } else if (!strcmp(dataType, "int64")) { + + if (args[2].As().IsBigInt()) { + bool lossless; + Memory.writeMemory(handle, address, args[2].As().Int64Value(&lossless)); + } else { + Memory.writeMemory(handle, address, args[2].As().Int64Value()); + } + + } else if (!strcmp(dataType, "uint64")) { + + if (args[2].As().IsBigInt()) { + bool lossless; + Memory.writeMemory(handle, address, args[2].As().Uint64Value(&lossless)); + } else { + Memory.writeMemory(handle, address, args[2].As().Int64Value()); + } + + } else if (!strcmp(dataType, "float")) { + + Memory.writeMemory(handle, address, args[2].As().FloatValue()); + + } else if (!strcmp(dataType, "double")) { + + Memory.writeMemory(handle, address, args[2].As().DoubleValue()); + + } else if (!strcmp(dataType, "ptr") || !strcmp(dataType, "pointer")) { + + Napi::BigInt valueBigInt = args[2].As(); + + if (sizeof(intptr_t) == 8 && !valueBigInt.IsBigInt()) { + std::string error = "Writing 'ptr' or 'pointer' on 64 bit target build requires you to supply a BigInt."; + Napi::Error::New(env, error).ThrowAsJavaScriptException(); + return env.Null(); + } + + if (valueBigInt.IsBigInt()) { + bool lossless; + Memory.writeMemory(handle, address, valueBigInt.Int64Value(&lossless)); + } else { + Memory.writeMemory(handle, address, args[2].As().Int32Value()); + } + + } else if (!strcmp(dataType, "uptr") || !strcmp(dataType, "upointer")) { + + Napi::BigInt valueBigInt = args[2].As(); + + if (sizeof(uintptr_t) == 8 && !valueBigInt.IsBigInt()) { + std::string error = "Writing 'ptr' or 'pointer' on 64 bit target build requires you to supply a BigInt."; + Napi::Error::New(env, error).ThrowAsJavaScriptException(); + return env.Null(); + } + + if (valueBigInt.IsBigInt()) { + bool lossless; + Memory.writeMemory(handle, address, valueBigInt.Uint64Value(&lossless)); } else { - // Optional: Add error handling for unexpected data type if needed, - // e.g., throw std::runtime_error or return a bool status. - // For now, it does nothing for unknown types. + Memory.writeMemory(handle, address, args[2].As().Uint32Value()); + } + + } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { + + Memory.writeMemory(handle, address, args[2].As().Value()); + + } else if (!strcmp(dataType, "string") || !strcmp(dataType, "str")) { + + std::string valueParam(args[2].As().Utf8Value()); + valueParam.append("", 1); + + // Write String, Method 1 + //Memory.writeMemory(handle, address, std::string(*valueParam)); + + // Write String, Method 2 + Memory.writeMemory(handle, address, (char*) valueParam.data(), valueParam.size()); + + } else if (!strcmp(dataType, "vector3") || !strcmp(dataType, "vec3")) { + + Napi::Object value = args[2].As(); + Vector3 vector = { + value.Get(Napi::String::New(env, "x")).As().FloatValue(), + value.Get(Napi::String::New(env, "y")).As().FloatValue(), + value.Get(Napi::String::New(env, "z")).As().FloatValue() + }; + Memory.writeMemory(handle, address, vector); + + } else if (!strcmp(dataType, "vector4") || !strcmp(dataType, "vec4")) { + + Napi::Object value = args[2].As(); + Vector4 vector = { + value.Get(Napi::String::New(env, "w")).As().FloatValue(), + value.Get(Napi::String::New(env, "x")).As().FloatValue(), + value.Get(Napi::String::New(env, "y")).As().FloatValue(), + value.Get(Napi::String::New(env, "z")).As().FloatValue() + }; + Memory.writeMemory(handle, address, vector); + + } else { + Napi::Error::New(env, "unexpected data type").ThrowAsJavaScriptException(); + } + + return env.Null(); +} + +Napi::Value writeBuffer(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 3) { + Napi::Error::New(env, "required 3 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() && !args[1].IsNumber()) { + Napi::Error::New(env, "first and second argument must be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + + DWORD64 address; + if (args[1].As().IsBigInt()) { + bool lossless; + address = args[1].As().Uint64Value(&lossless); + } else { + address = args[1].As().Int64Value(); + } + + SIZE_T length = args[2].As>().Length(); + char* data = args[2].As>().Data(); + Memory.writeMemory(handle, address, data, length); + + return env.Null(); +} + +// Napi::Value findPattern(const Napi::CallbackInfo& args) { +// Napi::Env env = args.Env(); + +// HANDLE handle = (HANDLE)args[0].As().Int64Value(); +// DWORD64 baseAddress = args[1].As().Int64Value(); +// DWORD64 baseSize = args[2].As().Int64Value(); +// std::string signature(args[3].As().Utf8Value()); +// short flags = args[4].As().Uint32Value(); +// uint32_t patternOffset = args[5].As().Uint32Value(); + +// // matching address +// uintptr_t address = 0; +// const char* errorMessage = ""; + +// // read memory region occupied by the module to pattern match inside +// std::vector moduleBytes = std::vector(baseSize); +// ReadProcessMemory(handle, (LPVOID)baseAddress, &moduleBytes[0], baseSize, nullptr); +// unsigned char* byteBase = const_cast(&moduleBytes.at(0)); + +// Pattern.findPattern(handle, baseAddress, byteBase, baseSize, signature.c_str(), flags, patternOffset, &address); + +// if (address == 0) { +// errorMessage = "unable to match pattern inside any modules or regions"; +// } + +// if (args.Length() == 5) { +// Napi::Function callback = args[4].As(); +// callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); +// return env.Null(); +// } else { +// return Napi::Value::From(env, address); +// } +// } + +Napi::Value findPattern(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 4 && args.Length() != 5) { + Napi::Error::New(env, "requires 4 arguments, 5 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsString() || !args[2].IsNumber() || !args[3].IsNumber()) { + Napi::Error::New(env, "expected: number, string, string, number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 5 && !args[4].IsFunction()) { + Napi::Error::New(env, "callback argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + std::string pattern(args[1].As().Utf8Value()); + short flags = args[2].As().Uint32Value(); + uint32_t patternOffset = args[3].As().Uint32Value(); + + // matching address + uintptr_t address = 0; + const char* errorMessage = ""; + + std::vector modules = module::getModules(GetProcessId(handle), &errorMessage); + Pattern.search(handle, modules, 0, pattern.c_str(), flags, patternOffset, &address); + + // if no match found inside any modules, search memory regions + if (address == 0) { + std::vector regions = Memory.getRegions(handle); + Pattern.search(handle, regions, 0, pattern.c_str(), flags, patternOffset, &address); + } + + if (address == 0) { + errorMessage = "unable to match pattern inside any modules or regions"; + } + + if (args.Length() == 5) { + Napi::Function callback = args[4].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); + return env.Null(); + } else { + return Napi::Value::From(env, address); + } +} + +Napi::Value findPatternByModule(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 5 && args.Length() != 6) { + Napi::Error::New(env, "requires 5 arguments, 6 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsString() || !args[2].IsString() || !args[3].IsNumber() || !args[4].IsNumber()) { + Napi::Error::New(env, "expected: number, string, string, number, number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 6 && !args[5].IsFunction()) { + Napi::Error::New(env, "callback argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + std::string moduleName(args[1].As().Utf8Value()); + std::string pattern(args[2].As().Utf8Value()); + short flags = args[3].As().Uint32Value(); + uint32_t patternOffset = args[4].As().Uint32Value(); + + // matching address + uintptr_t address = 0; + const char* errorMessage = ""; + + MODULEENTRY32 module = module::findModule(moduleName.c_str(), GetProcessId(handle), &errorMessage); + + uintptr_t baseAddress = (uintptr_t) module.modBaseAddr; + DWORD baseSize = module.modBaseSize; + + // read memory region occupied by the module to pattern match inside + std::vector moduleBytes = std::vector(baseSize); + ReadProcessMemory(handle, (LPVOID)baseAddress, &moduleBytes[0], baseSize, nullptr); + unsigned char* byteBase = const_cast(&moduleBytes.at(0)); + + Pattern.findPattern(handle, baseAddress, byteBase, baseSize, pattern.c_str(), flags, patternOffset, &address); + + if (address == 0) { + errorMessage = "unable to match pattern inside any modules or regions"; + } + + if (args.Length() == 6) { + Napi::Function callback = args[5].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); + return env.Null(); + } else { + return Napi::Value::From(env, address); + } +} + +Napi::Value findPatternByAddress(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 5 && args.Length() != 6) { + Napi::Error::New(env, "requires 5 arguments, 6 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsNumber() || !args[2].IsString() || !args[3].IsNumber() || !args[4].IsNumber()) { + Napi::Error::New(env, "expected: number, number, string, number, number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 6 && !args[5].IsFunction()) { + Napi::Error::New(env, "callback argument must be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + + DWORD64 baseAddress; + if (args[1].As().IsBigInt()) { + bool lossless; + baseAddress = args[1].As().Uint64Value(&lossless); + } else { + baseAddress = args[1].As().Int64Value(); + } + + std::string pattern(args[2].As().Utf8Value()); + short flags = args[3].As().Uint32Value(); + uint32_t patternOffset = args[4].As().Uint32Value(); + + // matching address + uintptr_t address = 0; + const char* errorMessage = ""; + + std::vector modules = module::getModules(GetProcessId(handle), &errorMessage); + Pattern.search(handle, modules, baseAddress, pattern.c_str(), flags, patternOffset, &address); + + if (address == 0) { + std::vector regions = Memory.getRegions(handle); + Pattern.search(handle, regions, baseAddress, pattern.c_str(), flags, patternOffset, &address); + } + + if (address == 0) { + errorMessage = "unable to match pattern inside any modules or regions"; + } + + if (args.Length() == 6) { + Napi::Function callback = args[5].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); + return env.Null(); + } else { + return Napi::Value::From(env, address); + } +} + +Napi::Value callFunction(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 4 && args.Length() != 5) { + Napi::Error::New(env, "requires 4 arguments, 5 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() && !args[1].IsObject() && !args[2].IsNumber() && !args[3].IsNumber()) { + Napi::Error::New(env, "invalid arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + // TODO: temp (?) solution to forcing variables onto the heap + // to ensure consistent addresses. copy everything to a vector, and use the + // vector's instances of the variables as the addresses being passed to `functions.call()`. + // Another solution: do `int x = new int(4)` and then use `&x` for the address + std::vector heap; + + std::vector parsedArgs; + Napi::Array arguments = args[1].As(); + for (unsigned int i = 0; i < arguments.Length(); i++) { + Napi::Object argument = arguments.Get(i).As(); + + functions::Type type = (functions::Type) argument.Get(Napi::String::New(env, "type")).As().Uint32Value(); + + if (type == functions::Type::T_STRING) { + std::string stringValue = argument.Get(Napi::String::New(env, "value")).As().Utf8Value(); + parsedArgs.push_back({ type, &stringValue }); + } + + if (type == functions::Type::T_INT) { + int data = argument.Get(Napi::String::New(env, "value")).As().Int32Value(); + + // As we only pass the addresses of the variable to the `call` function and not a copy + // of the variable itself, we need to ensure that the variable stays alive and in a unique + // memory location until the `call` function has been executed. So manually allocate memory, + // track it, and then free it once the function has been called. + // TODO: find a better solution? + int* memory = (int*) malloc(sizeof(int)); + *memory = data; + heap.push_back(memory); + + parsedArgs.push_back({ type, memory }); + } + + if (type == functions::Type::T_FLOAT) { + float data = argument.Get(Napi::String::New(env, "value")).As().FloatValue(); + + float* memory = (float*) malloc(sizeof(float)); + *memory = data; + heap.push_back(memory); + + parsedArgs.push_back({ type, memory }); + } + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + functions::Type returnType = (functions::Type) args[2].As().Uint32Value(); + + DWORD64 address; + if (args[3].As().IsBigInt()) { + bool lossless; + address = args[3].As().Uint64Value(&lossless); + } else { + address = args[3].As().Int64Value(); + } + + const char* errorMessage = ""; + Call data = functions::call(handle, parsedArgs, returnType, address, &errorMessage); + + // Free all the memory we allocated + for (auto &memory : heap) { + free(memory); + } + + heap.clear(); + + if (strcmp(errorMessage, "") && args.Length() != 5) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + Napi::Object info = Napi::Object::New(env); + + Napi::String keyString = Napi::String::New(env, "returnValue"); + + if (returnType == functions::Type::T_STRING) { + info.Set(keyString, Napi::String::New(env, data.returnString.c_str())); + } + + if (returnType == functions::Type::T_CHAR) { + info.Set(keyString, Napi::Value::From(env, (char) data.returnValue)); + } + + if (returnType == functions::Type::T_BOOL) { + info.Set(keyString, Napi::Value::From(env, (bool) data.returnValue)); + } + + if (returnType == functions::Type::T_INT) { + info.Set(keyString, Napi::Value::From(env, (int) data.returnValue)); + } + + if (returnType == functions::Type::T_FLOAT) { + float value = *(float *)&data.returnValue; + info.Set(keyString, Napi::Value::From(env, value)); + } + + if (returnType == functions::Type::T_DOUBLE) { + double value = *(double *)&data.returnValue; + info.Set(keyString, Napi::Value::From(env, value)); + } + + info.Set(Napi::String::New(env, "exitCode"), Napi::Value::From(env, data.exitCode)); + + if (args.Length() == 5) { + // Callback to let the user handle with the information + Napi::Function callback = args[2].As(); + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), info }); + return env.Null(); + } else { + // return JSON + return info; + } + +} + +Napi::Value virtualProtectEx(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 4 && args.Length() != 5) { + Napi::Error::New(env, "requires 4 arguments, 5 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() && !args[1].IsNumber() && !args[2].IsNumber()) { + Napi::Error::New(env, "All arguments should be numbers.").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 5 && !args[4].IsFunction()) { + Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + DWORD result; + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + DWORD64 address = args[1].As().Int64Value(); + SIZE_T size = args[2].As().Int64Value(); + DWORD protection = args[3].As().Uint32Value(); + + bool success = VirtualProtectEx(handle, (LPVOID) address, size, protection, &result); + + const char* errorMessage = ""; + + if (success == 0) { + errorMessage = "an error occurred calling VirtualProtectEx"; + // errorMessage = GetLastErrorToString().c_str(); + } + + // If there is an error and there is no callback, throw the error + if (strcmp(errorMessage, "") && args.Length() != 5) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 5) { + // Callback to let the user handle with the information + Napi::Function callback = args[5].As(); + callback.Call(env.Global(), { + Napi::String::New(env, errorMessage), + Napi::Value::From(env, result) + }); + return env.Null(); + } else { + return Napi::Value::From(env, result); + } +} + +Napi::Value getRegions(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 1 && args.Length() != 2) { + Napi::Error::New(env, "requires 1 argument, 2 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber()) { + Napi::Error::New(env, "invalid arguments: first argument must be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 2 && !args[1].IsFunction()) { + Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + std::vector regions = Memory.getRegions(handle); + + Napi::Array regionsArray = Napi::Array::New(env, regions.size()); + + for (std::vector::size_type i = 0; i != regions.size(); i++) { + Napi::Object region = Napi::Object::New(env); + + region.Set(Napi::String::New(env, "BaseAddress"), Napi::Value::From(env, (DWORD64) regions[i].BaseAddress)); + region.Set(Napi::String::New(env, "AllocationBase"), Napi::Value::From(env, (DWORD64) regions[i].AllocationBase)); + region.Set(Napi::String::New(env, "AllocationProtect"), Napi::Value::From(env, (DWORD) regions[i].AllocationProtect)); + region.Set(Napi::String::New(env, "RegionSize"), Napi::Value::From(env, (SIZE_T) regions[i].RegionSize)); + region.Set(Napi::String::New(env, "State"), Napi::Value::From(env, (DWORD) regions[i].State)); + region.Set(Napi::String::New(env, "Protect"), Napi::Value::From(env, (DWORD) regions[i].Protect)); + region.Set(Napi::String::New(env, "Type"), Napi::Value::From(env, (DWORD) regions[i].Type)); + + char moduleName[MAX_PATH]; + DWORD size = GetModuleFileNameExA(handle, (HINSTANCE)regions[i].AllocationBase, moduleName, MAX_PATH); + + if (size != 0) { + region.Set(Napi::String::New(env, "szExeFile"), Napi::String::New(env, moduleName)); + } + + regionsArray.Set(i, region); + } + + if (args.Length() == 2) { + // Callback to let the user handle with the information + Napi::Function callback = args[1].As(); + callback.Call(env.Global(), { Napi::String::New(env, ""), regionsArray }); + return env.Null(); + } else { + // return JSON + return regionsArray; + } +} + +Napi::Value virtualQueryEx(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2 && args.Length() != 3) { + Napi::Error::New(env, "requires 2 arguments, 3 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsNumber()) { + Napi::Error::New(env, "first and second argument need to be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 3 && !args[2].IsFunction()) { + Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + DWORD64 address = args[1].As().Int64Value(); + + MEMORY_BASIC_INFORMATION information; + SIZE_T result = VirtualQueryEx(handle, (LPVOID)address, &information, sizeof(information)); + + const char* errorMessage = ""; + + if (result == 0 || result != sizeof(information)) { + errorMessage = "an error occurred calling VirtualQueryEx"; + // errorMessage = GetLastErrorToString().c_str(); + } + + // If there is an error and there is no callback, throw the error + if (strcmp(errorMessage, "") && args.Length() != 3) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + Napi::Object region = Napi::Object::New(env); + + region.Set(Napi::String::New(env, "BaseAddress"), Napi::Value::From(env, (DWORD64) information.BaseAddress)); + region.Set(Napi::String::New(env, "AllocationBase"), Napi::Value::From(env, (DWORD64) information.AllocationBase)); + region.Set(Napi::String::New(env, "AllocationProtect"), Napi::Value::From(env, (DWORD) information.AllocationProtect)); + region.Set(Napi::String::New(env, "RegionSize"), Napi::Value::From(env, (SIZE_T) information.RegionSize)); + region.Set(Napi::String::New(env, "State"), Napi::Value::From(env, (DWORD) information.State)); + region.Set(Napi::String::New(env, "Protect"), Napi::Value::From(env, (DWORD) information.Protect)); + region.Set(Napi::String::New(env, "Type"), Napi::Value::From(env, (DWORD) information.Type)); + + if (args.Length() == 3) { + // Callback to let the user handle with the information + Napi::Function callback = args[1].As(); + callback.Call(env.Global(), { Napi::String::New(env, ""), region }); + return env.Null(); + } else { + // return JSON + return region; + } +} + +Napi::Value virtualAllocEx(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 5 && args.Length() != 6) { + Napi::Error::New(env, "requires 5 arguments, 6 with callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[2].IsNumber() || !args[3].IsNumber() || !args[4].IsNumber()) { + Napi::Error::New(env, "invalid arguments: arguments 0, 2, 3 and 4 need to be numbers").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 6 && !args[5].IsFunction()) { + Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + SIZE_T size = args[2].As().Int64Value(); + DWORD allocationType = args[3].As().Uint32Value(); + DWORD protection = args[4].As().Uint32Value(); + LPVOID address; + + // Means in the JavaScript space `null` was passed through. + if (args[1] == env.Null()) { + address = NULL; + } else { + address = (LPVOID) args[1].As().Int64Value(); + } + + LPVOID allocatedAddress = VirtualAllocEx(handle, address, size, allocationType, protection); + + const char* errorMessage = ""; + + // If null, it means an error occurred + if (allocatedAddress == NULL) { + errorMessage = "an error occurred calling VirtualAllocEx"; + // errorMessage = GetLastErrorToString().c_str(); + } + + // If there is an error and there is no callback, throw the error + if (strcmp(errorMessage, "") && args.Length() != 6) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 6) { + // Callback to let the user handle with the information + Napi::Function callback = args[5].As(); + callback.Call(env.Global(), { + Napi::String::New(env, errorMessage), + Napi::Value::From(env, (intptr_t)allocatedAddress) + }); + return env.Null(); + } else { + return Napi::Value::From(env, (intptr_t)allocatedAddress); + } +} + +Napi::Value attachDebugger(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2) { + Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsBoolean()) { + Napi::Error::New(env, "first argument needs to be a number, second a boolean").ThrowAsJavaScriptException(); + return env.Null(); + } + + DWORD processId = args[0].As().Uint32Value(); + bool killOnExit = args[1].As().Value(); + + bool success = debugger::attach(processId, killOnExit); + return Napi::Boolean::New(env, success); +} + +Napi::Value detachDebugger(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + DWORD processId = args[0].As().Uint32Value(); + + if (args.Length() != 1) { + Napi::Error::New(env, "requires only 1 argument").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber()) { + Napi::Error::New(env, "only argument needs to be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + bool success = debugger::detatch(processId); + return Napi::Boolean::New(env, success); +} + +Napi::Value awaitDebugEvent(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2) { + Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsNumber()) { + Napi::Error::New(env, "both arguments need to be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + int millisTimeout = args[1].As().Uint32Value(); + + DebugEvent debugEvent; + bool success = debugger::awaitDebugEvent(millisTimeout, &debugEvent); + + Register hardwareRegister = static_cast(args[0].As().Uint32Value()); + + if (success && debugEvent.hardwareRegister == hardwareRegister) { + Napi::Object info = Napi::Object::New(env); + + info.Set(Napi::String::New(env, "processId"), Napi::Value::From(env, (DWORD) debugEvent.processId)); + info.Set(Napi::String::New(env, "threadId"), Napi::Value::From(env, (DWORD) debugEvent.threadId)); + info.Set(Napi::String::New(env, "exceptionCode"), Napi::Value::From(env, (DWORD) debugEvent.exceptionCode)); + info.Set(Napi::String::New(env, "exceptionFlags"), Napi::Value::From(env, (DWORD) debugEvent.exceptionFlags)); + info.Set(Napi::String::New(env, "exceptionAddress"), Napi::Value::From(env, (DWORD64) debugEvent.exceptionAddress)); + info.Set(Napi::String::New(env, "hardwareRegister"), Napi::Value::From(env, static_cast(debugEvent.hardwareRegister))); + + return info; + } + + // If we aren't interested in passing this event back to the JS space, + // just silently handle it + if (success && debugEvent.hardwareRegister != hardwareRegister) { + debugger::handleDebugEvent(debugEvent.processId, debugEvent.threadId); + } + + return env.Null(); +} + +Napi::Value handleDebugEvent(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2) { + Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsNumber()) { + Napi::Error::New(env, "both arguments need to be numbers").ThrowAsJavaScriptException(); + return env.Null(); + } + + DWORD processId = args[0].As().Uint32Value(); + DWORD threadId = args[1].As().Uint32Value(); + + bool success = debugger::handleDebugEvent(processId, threadId); + return Napi::Boolean::New(env, success); +} + +Napi::Value setHardwareBreakpoint(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 5) { + Napi::Error::New(env, "requires 5 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + for (unsigned int i = 0; i < args.Length(); i++) { + if (!args[i].IsNumber()) { + Napi::Error::New(env, "all arguments need to be numbers").ThrowAsJavaScriptException(); + return env.Null(); + } + } + + DWORD processId = args[0].As().Uint32Value(); + DWORD64 address = args[1].As().Int64Value(); + Register hardwareRegister = static_cast(args[2].As().Uint32Value()); + + // Execute = 0x0 + // Access = 0x3 + // Writer = 0x1 + int trigger = args[3].As().Uint32Value(); + + int length = args[4].As().Uint32Value(); + + bool success = debugger::setHardwareBreakpoint(processId, address, hardwareRegister, trigger, length); + return Napi::Boolean::New(env, success); +} + +Napi::Value removeHardwareBreakpoint(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2) { + Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsNumber()) { + Napi::Error::New(env, "both arguments need to be numbers").ThrowAsJavaScriptException(); + return env.Null(); + } + + DWORD processId = args[0].As().Uint32Value(); + Register hardwareRegister = static_cast(args[1].As().Uint32Value()); + + bool success = debugger::setHardwareBreakpoint(processId, 0, hardwareRegister, 0, 0); + return Napi::Boolean::New(env, success); +} + +Napi::Value injectDll(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2 && args.Length() != 3) { + Napi::Error::New(env, "requires 2 arguments, or 3 with a callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber() || !args[1].IsString()) { + Napi::Error::New(env, "first argument needs to be a number, second argument needs to be a string").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 3 && !args[2].IsFunction()) { + Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + std::string dllPath(args[1].As().Utf8Value()); + Napi::Function callback = args[2].As(); + + const char* errorMessage = ""; + DWORD moduleHandle = -1; + bool success = dll::inject(handle, dllPath, &errorMessage, &moduleHandle); + + if (strcmp(errorMessage, "") && args.Length() != 3) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return env.Null(); + } + + // `moduleHandle` above is the return value of the `LoadLibrary` procedure, + // which we retrieve through `GetExitCode`. This value can become truncated + // in large address spaces such as 64 bit since `GetExitCode` just returns BOOL, + // so it's unreliable to use as the handle. Since the handle of a module is just a pointer + // to the address of the DLL mapped in the process' virtual address space, we can fetch + // this separately, so we won't return it to prevent it being passed to `unloadDll` + // and in some cases unexpectedly failing when it is truncated. + + if (args.Length() == 3) { + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Boolean::New(env, success) }); + return env.Null(); + } else { + return Napi::Boolean::New(env, success); + } +} + +Napi::Value unloadDll(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + if (args.Length() != 2 && args.Length() != 3) { + Napi::Error::New(env, "requires 2 arguments, or 3 with a callback").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[0].IsNumber()) { + Napi::Error::New(env, "first argument needs to be a number").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (!args[1].IsNumber() && !args[1].IsString()) { + Napi::Error::New(env, "second argument needs to be a number or a string").ThrowAsJavaScriptException(); + return env.Null(); + } + + if (args.Length() == 3 && !args[2].IsFunction()) { + Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); + return env.Null(); + } + + HANDLE handle = (HANDLE)args[0].As().Int64Value(); + Napi::Function callback = args[2].As(); + + HMODULE moduleHandle; + + // get module handle (module base address) directly + if (args[1].IsNumber()) { + moduleHandle = (HMODULE)args[1].As().Int64Value(); + } + + // find module handle from name of DLL + if (args[1].IsString()) { + std::string moduleName(args[1].As().Utf8Value()); + const char* errorMessage = ""; + + MODULEENTRY32 module = module::findModule(moduleName.c_str(), GetProcessId(handle), &errorMessage); + + if (strcmp(errorMessage, "")) { + if (args.Length() != 3) { + Napi::Error::New(env, "unable to find specified module").ThrowAsJavaScriptException(); + return env.Null(); + } else { + callback.Call(env.Global(), { Napi::String::New(env, errorMessage) }); + return Napi::Boolean::New(env, false); + } } + + moduleHandle = (HMODULE) module.modBaseAddr; + } + + const char* errorMessage = ""; + bool success = dll::unload(handle, &errorMessage, moduleHandle); + + if (strcmp(errorMessage, "") && args.Length() != 3) { + Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); + return Napi::Boolean::New(env, false); + } + + if (args.Length() == 3) { + callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Boolean::New(env, success) }); + return env.Null(); + } else { + return Napi::Boolean::New(env, success); } +} + +Napi::Value openFileMapping(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + std::string fileName(args[0].As().Utf8Value()); + + HANDLE fileHandle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, fileName.c_str()); + + if (fileHandle == NULL) { + Napi::Error::New(env, Napi::String::New(env, "Error opening handle to file!")).ThrowAsJavaScriptException(); + return env.Null(); + } + + return Napi::Value::From(env, (uintptr_t) fileHandle); +} + +Napi::Value mapViewOfFile(const Napi::CallbackInfo& args) { + Napi::Env env = args.Env(); + + HANDLE processHandle = (HANDLE)args[0].As().Int64Value(); + HANDLE fileHandle = (HANDLE)args[1].As().Int64Value(); - __declspec(dllexport) void closeProcess(HANDLE hProcess) { - process proc; - proc.closeProcess(hProcess); + uint64_t offset; + if (args[2].As().IsBigInt()) { + bool lossless; + offset = args[2].As().Uint64Value(&lossless); + } else { + offset = args[2].As().Int64Value(); } -} \ No newline at end of file + + size_t viewSize; + if (args[3].As().IsBigInt()) { + bool lossless; + viewSize = args[3].As().Uint64Value(&lossless); + } else { + viewSize = args[3].As().Int64Value(); + } + + ULONG pageProtection = args[4].As().Int64Value(); + + LPVOID baseAddress = MapViewOfFile2(fileHandle, processHandle, offset, NULL, viewSize, 0, pageProtection); + + if (baseAddress == NULL) { + Napi::Error::New(env, Napi::String::New(env, "Error mapping file to process!")).ThrowAsJavaScriptException(); + return env.Null(); + } + + return Napi::Value::From(env, (uintptr_t) baseAddress); +} + +// https://stackoverflow.com/a/17387176 +std::string GetLastErrorToString() { + DWORD errorMessageID = ::GetLastError(); + + // No error message, return empty string + if(errorMessageID == 0) { + return std::string(); + } + + LPSTR messageBuffer = nullptr; + + size_t size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errorMessageID, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&messageBuffer, + 0, + NULL + ); + + std::string message(messageBuffer, size); + + // Free the buffer + LocalFree(messageBuffer); + return message; +} + +Napi::Object init(Napi::Env env, Napi::Object exports) { + exports.Set(Napi::String::New(env, "openProcess"), Napi::Function::New(env, openProcess)); + exports.Set(Napi::String::New(env, "closeHandle"), Napi::Function::New(env, closeHandle)); + exports.Set(Napi::String::New(env, "getProcesses"), Napi::Function::New(env, getProcesses)); + exports.Set(Napi::String::New(env, "getModules"), Napi::Function::New(env, getModules)); + exports.Set(Napi::String::New(env, "findModule"), Napi::Function::New(env, findModule)); + exports.Set(Napi::String::New(env, "readMemory"), Napi::Function::New(env, readMemory)); + exports.Set(Napi::String::New(env, "readBuffer"), Napi::Function::New(env, readBuffer)); + exports.Set(Napi::String::New(env, "writeMemory"), Napi::Function::New(env, writeMemory)); + exports.Set(Napi::String::New(env, "writeBuffer"), Napi::Function::New(env, writeBuffer)); + exports.Set(Napi::String::New(env, "findPattern"), Napi::Function::New(env, findPattern)); + exports.Set(Napi::String::New(env, "findPatternByModule"), Napi::Function::New(env, findPatternByModule)); + exports.Set(Napi::String::New(env, "findPatternByAddress"), Napi::Function::New(env, findPatternByAddress)); + exports.Set(Napi::String::New(env, "virtualProtectEx"), Napi::Function::New(env, virtualProtectEx)); + exports.Set(Napi::String::New(env, "callFunction"), Napi::Function::New(env, callFunction)); + exports.Set(Napi::String::New(env, "virtualAllocEx"), Napi::Function::New(env, virtualAllocEx)); + exports.Set(Napi::String::New(env, "getRegions"), Napi::Function::New(env, getRegions)); + exports.Set(Napi::String::New(env, "virtualQueryEx"), Napi::Function::New(env, virtualQueryEx)); + exports.Set(Napi::String::New(env, "attachDebugger"), Napi::Function::New(env, attachDebugger)); + exports.Set(Napi::String::New(env, "detachDebugger"), Napi::Function::New(env, detachDebugger)); + exports.Set(Napi::String::New(env, "awaitDebugEvent"), Napi::Function::New(env, awaitDebugEvent)); + exports.Set(Napi::String::New(env, "handleDebugEvent"), Napi::Function::New(env, handleDebugEvent)); + exports.Set(Napi::String::New(env, "setHardwareBreakpoint"), Napi::Function::New(env, setHardwareBreakpoint)); + exports.Set(Napi::String::New(env, "removeHardwareBreakpoint"), Napi::Function::New(env, removeHardwareBreakpoint)); + exports.Set(Napi::String::New(env, "injectDll"), Napi::Function::New(env, injectDll)); + exports.Set(Napi::String::New(env, "unloadDll"), Napi::Function::New(env, unloadDll)); + exports.Set(Napi::String::New(env, "openFileMapping"), Napi::Function::New(env, openFileMapping)); + exports.Set(Napi::String::New(env, "mapViewOfFile"), Napi::Function::New(env, mapViewOfFile)); + return exports; +} + +NODE_API_MODULE(memoryprocess, init) diff --git a/native/memoryprocess.h b/native/memoryprocess.h index 81066e4..d30e879 100644 --- a/native/memoryprocess.h +++ b/native/memoryprocess.h @@ -8,7 +8,7 @@ class memoryprocess { public: -memoryprocess(); + memoryprocess(); ~memoryprocess(); }; #endif diff --git a/native/module.cc b/native/module.cc index 4dd8c93..b21a0c0 100644 --- a/native/module.cc +++ b/native/module.cc @@ -2,6 +2,8 @@ #include #include #include "module.h" +#include "process.h" +#include "memoryprocess.h" DWORD64 module::getBaseAddress(const char* processName, DWORD processId) { const char* errorMessage = ""; diff --git a/native/pattern.cc b/native/pattern.cc index b1783b2..3a3505d 100644 --- a/native/pattern.cc +++ b/native/pattern.cc @@ -2,6 +2,9 @@ #include #include #include "pattern.h" +#include "memoryprocess.h" +#include "process.h" +#include "memory.h" #define INRANGE(x,a,b) (x >= a && x <= b) #define getBits( x ) (INRANGE(x,'0','9') ? (x - '0') : ((x&(~0x20)) - 'A' + 0xa)) diff --git a/native/process.cc b/native/process.cc index 787500a..0822d63 100644 --- a/native/process.cc +++ b/native/process.cc @@ -2,10 +2,15 @@ #include #include #include "process.h" +#include "memoryprocess.h" process::process() {} process::~process() {} +using v8::Exception; +using v8::Isolate; +using v8::String; + process::Pair process::openProcess(const char* processName, const char** errorMessage){ PROCESSENTRY32 process; HANDLE handle = NULL; @@ -58,10 +63,6 @@ process::Pair process::openProcess(DWORD processId, const char** errorMessage) { }; } -void process::closeProcess(HANDLE hProcess){ - CloseHandle(hProcess); -} - std::vector process::getProcesses(const char** errorMessage) { // Take a snapshot of all processes. HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..efc59ed --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1598 @@ +{ + "name": "memoryprocess", + "version": "3.5.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "memoryprocess", + "version": "3.5.1", + "license": "MIT", + "dependencies": { + "node-addon-api": "3.2.1" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "@commitlint/cli": "19.8.0", + "@commitlint/config-conventional": "19.8.0", + "@microsoft/api-extractor": "7.52.4", + "@total-typescript/tsconfig": "1.0.4", + "@types/bun": "1.2.10", + "@types/node": "22.14.1", + "lefthook": "1.11.10", + "typescript": "5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@commitlint/cli": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/format": "^19.8.0", + "@commitlint/lint": "^19.8.0", + "@commitlint/load": "^19.8.0", + "@commitlint/read": "^19.8.0", + "@commitlint/types": "^19.8.0", + "tinyexec": "^0.3.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.0", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.0", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator/node_modules/ajv": { + "version": "8.13.0", + "dev": true, + "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/@commitlint/ensure": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.0", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.0", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored/node_modules/semver": { + "version": "7.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@commitlint/lint": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^19.8.0", + "@commitlint/parse": "^19.8.0", + "@commitlint/rules": "^19.8.0", + "@commitlint/types": "^19.8.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.8.0", + "@commitlint/execute-rule": "^19.8.0", + "@commitlint/resolve-extends": "^19.8.0", + "@commitlint/types": "^19.8.0", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/message": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/parse": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.0", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^19.8.0", + "@commitlint/types": "^19.8.0", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8", + "tinyexec": "^0.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.8.0", + "@commitlint/types": "^19.8.0", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^19.8.0", + "@commitlint/message": "^19.8.0", + "@commitlint/to-lines": "^19.8.0", + "@commitlint/types": "^19.8.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^7.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types": { + "version": "19.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@microsoft/api-extractor": { + "version": "7.52.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/api-extractor-model": "7.30.5", + "@microsoft/tsdoc": "~0.15.1", + "@microsoft/tsdoc-config": "~0.17.1", + "@rushstack/node-core-library": "5.13.0", + "@rushstack/rig-package": "0.5.3", + "@rushstack/terminal": "0.15.2", + "@rushstack/ts-command-line": "4.23.7", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.8.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.30.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "~0.15.1", + "@microsoft/tsdoc-config": "~0.17.1", + "@rushstack/node-core-library": "5.13.0" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.8.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "0.15.1", + "ajv": "~8.12.0", + "jju": "~1.4.0", + "resolve": "~1.22.2" + } + }, + "node_modules/@rushstack/node-core-library": { + "version": "5.13.0", + "dev": true, + "license": "MIT", + "dependencies": { + "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.22.1", + "semver": "~7.5.4" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/node-core-library/node_modules/ajv": { + "version": "8.13.0", + "dev": true, + "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/rig-package": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/terminal": { + "version": "0.15.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/node-core-library": "5.13.0", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.23.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/terminal": "0.15.2", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" + } + }, + "node_modules/@total-typescript/tsconfig": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/argparse": { + "version": "1.0.38", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bun": { + "version": "1.2.10", + "dev": true, + "license": "MIT", + "dependencies": { + "bun-types": "1.2.10" + } + }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.13.0", + "dev": true, + "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/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/bun-types": { + "version": "1.2.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/compare-func": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^2.4.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" + } + }, + "node_modules/dargs": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fs-extra": { + "version": "11.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ini": { + "version": "4.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-text-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/lefthook": { + "version": "1.11.10", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "lefthook": "bin/index.js" + }, + "optionalDependencies": { + "lefthook-darwin-arm64": "1.11.10", + "lefthook-darwin-x64": "1.11.10", + "lefthook-freebsd-arm64": "1.11.10", + "lefthook-freebsd-x64": "1.11.10", + "lefthook-linux-arm64": "1.11.10", + "lefthook-linux-x64": "1.11.10", + "lefthook-openbsd-arm64": "1.11.10", + "lefthook-openbsd-x64": "1.11.10", + "lefthook-windows-arm64": "1.11.10", + "lefthook-windows-x64": "1.11.10" + } + }, + "node_modules/lefthook-windows-x64": { + "version": "1.11.10", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow": { + "version": "12.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.0.8", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "license": "MIT" + }, + "node_modules/p-limit": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "dev": true, + "license": "MIT", + "dependencies": { + "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/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/string-argv": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-extensions": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 8cad87f..0d4edd9 100644 --- a/package.json +++ b/package.json @@ -1,63 +1,47 @@ { "name": "memoryprocess", - "version": "1.0.0-beta.1", - "description": "Maintained fork of memoryjs (Bun-only) with critical fixes. Requires Bun runtime.", - "author": "JoShMiQueL", + "version": "1.0.0-beta", + "description": "Maintained fork of memoryjs with critical fixes.", + "main": "lib/index.js", + "types": "lib/index.d.ts", "type": "module", - "types": "./lib/index.d.ts", - "engineStrict": true, - "engines": { - "bun": ">=1.2.9" - }, - "exports": { - ".": { - "bun": "./lib/index.js", - "node": "./lib/node-error.js", - "types": "./lib/index.d.ts", - "default": "./lib/index.js" - } - }, "scripts": { + "build": "bun run scripts/build.ts", "check": "biome check --write" }, + "repository": { + "type": "git", + "url": "git+https://github.com/joshmiquel/memoryprocess.git" + }, + "keywords": [ + "memory", + "reading", + "writing", + "management", + "addon" + ], + "author": "JoShMiQueL", + "license": "MIT", + "bugs": { + "url": "https://github.com/joshmiquel/memoryprocess/issues" + }, + "homepage": "https://github.com/joshmiquel/memoryprocess#readme", + "dependencies": { + "node-addon-api": "3.2.1" + }, "devDependencies": { "@biomejs/biome": "1.9.4", "@commitlint/cli": "19.8.0", "@commitlint/config-conventional": "19.8.0", - "@microsoft/api-extractor": "7.52.3", - "@semantic-release/commit-analyzer": "13.0.1", - "@semantic-release/git": "10.0.1", - "@semantic-release/github": "11.0.1", - "@semantic-release/npm": "12.0.1", - "@semantic-release/release-notes-generator": "14.0.3", - "@types/bun": "latest", + "@microsoft/api-extractor": "7.52.4", + "@total-typescript/tsconfig": "1.0.4", + "@types/bun": "1.2.10", + "@types/node": "22.14.1", "lefthook": "1.11.10", - "semantic-release": "24.2.3" - }, - "peerDependencies": { - "typescript": "^5" + "typescript": "5" }, "trustedDependencies": [ "@biomejs/biome", "lefthook" - ], - "license": "MIT", - "homepage": "https://github.com/JoShMiQueL/memoryprocess#readme", - "repository": { - "type": "git", - "url": "git+https://github.com/JoShMiQueL/memoryprocess.git" - }, - "bugs": { - "url": "https://github.com/JoShMiQueL/memoryprocess/issues" - }, - "keywords": [ - "memory", - "reading", - "writing", - "management", - "addon", - "maintained-fork", - "windows-memory", - "process-memory" ] } diff --git a/scripts/build.ts b/scripts/build.ts new file mode 100644 index 0000000..203b709 --- /dev/null +++ b/scripts/build.ts @@ -0,0 +1,206 @@ +// 1. Build native code using node-gyp +// 2. Copy .node file from build/Release to src/ +// 3. Build with bun.build +// 4. Build types with tsc +// 5. Bundle types with api-extractor +// 6. Remove all .d.ts files from lib/ folder except index.d.ts +// 7. Remove .node file from src/ +// 8. Remove build/ folder +// 9. Remove all remaining empty folders from lib/ folder + +import path from "path"; +import { Extractor, ExtractorConfig, ExtractorResult } from '@microsoft/api-extractor'; + +function log(message: any, type: 'info' | 'success' | 'error' | 'warning' = 'info') { + const colors = { + info: '\x1b[36m', // cyan + success: '\x1b[32m', // green + error: '\x1b[31m', // red + warning: '\x1b[33m' // yellow + }; + + let prefix = ''; + if (process.stdout.isTTY) { + if (type === 'success') { + prefix = '✓ '; + } else if (type === 'info') { + prefix = 'ℹ '; + } else if (type === 'error') { + prefix = '✗ '; + } else if (type === 'warning') { + prefix = '⚠ '; + } + } + + const coloredMessage = `${colors[type]}${prefix}${message}\x1b[0m`; + + if (type === 'error') { + console.error(coloredMessage); + } else if (type === 'warning') { + console.warn(coloredMessage); + } else if (type === 'info') { + console.info(coloredMessage); + } else { + console.log(coloredMessage); + } +} + +function logWithTime(message: string, startTime: number, type: 'info' | 'success' | 'error' | 'warning' = 'success') { + const elapsedMs = performance.now() - startTime; + let timeString: string; + + if (elapsedMs < 1000) { + timeString = `${Math.round(elapsedMs)}ms`; + } else { + const seconds = elapsedMs / 1000; + timeString = seconds < 60 + ? `${seconds.toFixed(2)}s` + : `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`; + } + + log(`${message} \x1b[90m[${timeString}]\x1b[0m`, type); +} + +const srcGlob = new Bun.Glob("src/**/*.ts"); + +try { + // 1. Build native code using node-gyp + const startTime = performance.now(); + log("Starting native build...", "info"); + + const result = Bun.spawnSync(["node-gyp", "clean", "configure", "build", "--arch", "x64"]); + if (result.exitCode !== 0) { + log(`Native build failed with exit code ${result.exitCode}`, "error"); + throw new Error(`node-gyp build failed: ${result.stderr.toString()}`); + } + + logWithTime("Native build completed", startTime, "success"); + + // 2. Copy .node file from build/Release to src/ + const copyStartTime = performance.now(); + log("Copying native module to src directory...", "info"); + + const copyResult = Bun.spawnSync(["cp", "build/Release/native.node", "src/"]); + if (copyResult.exitCode !== 0) { + log(`Failed to copy native module: ${copyResult.stderr.toString()}`, "error"); + throw new Error("Failed to copy native module"); + } + logWithTime("Native module copied successfully", copyStartTime, "success"); + + // 3. Build with bun.build + const bundleStartTime = performance.now(); + log("Starting TypeScript build...", "info"); + const entryFiles = [ + "index.ts", + ...await Array.fromAsync(srcGlob.scan()), + "src/native.node" + ]; + log(`Found ${entryFiles.length} entry files for bundling`, "info"); + + const buildResult = await Bun.build({ + entrypoints: entryFiles, + outdir: "lib", + minify: true, + target: "node", + }); + + if (!buildResult.success) { + log(`Build failed with ${buildResult.logs.length} errors`, "error"); + for (const logItem of buildResult.logs) { + log(logItem.message, "error"); + } + throw new Error("TypeScript build failed"); + } + + logWithTime(`Build completed successfully (${buildResult.outputs.length} files)`, bundleStartTime, "success"); + + // 4. Build types with tsc + const typesStartTime = performance.now(); + log("Starting types build...", "info"); + + const tscResult = Bun.spawnSync(["tsc", "--project", "tsconfig.json"]); + if (tscResult.exitCode !== 0) { + log(`Types build failed: ${tscResult.stderr.toString()}`, "error"); + throw new Error("Types build failed"); + } + logWithTime("Types build completed", typesStartTime, "success"); + + // 5. Bundle types with api-extractor + const bundleTypesStartTime = performance.now(); + log("Starting types bundle...", "info"); + + const apiExtractorJsonPath: string = path.join(__dirname, '..', 'config', 'api-extractor.json'); + + const extractorConfig: ExtractorConfig = ExtractorConfig.loadFileAndPrepare(apiExtractorJsonPath); + + const extractorResult: ExtractorResult = Extractor.invoke(extractorConfig, { + localBuild: true, + }); + + if (extractorResult.succeeded) { + if (extractorResult.warningCount && extractorResult.warningCount > 0) { + logWithTime(`Types bundle completed with ${extractorResult.warningCount} warnings`, bundleTypesStartTime, "warning"); + } else { + logWithTime("Types bundle completed", bundleTypesStartTime, "success"); + } + } else { + logWithTime(`Types bundle failed with ${extractorResult.errorCount} errors`, bundleTypesStartTime, "error"); + throw new Error("Types bundle failed"); + } + + // 6. Remove all .d.ts files from lib/ folder except index.d.ts + const removeTypesStartTime = performance.now(); + log("Starting types cleanup...", "info"); + + const removeTypesResult = Bun.spawnSync(["find", "lib", "-name", "*.d.ts", "-not", "-name", "index.d.ts", "-delete"]); + if (removeTypesResult.exitCode !== 0) { + log(`Failed to remove types: ${removeTypesResult.stderr.toString()}`, "warning"); + } else { + logWithTime("Types cleanup completed", removeTypesStartTime, "success"); + } + + // 7. Remove .node file from src/ + const cleanupStartTime = performance.now(); + log("Cleaning up temporary native module...", "info"); + + const cleanupResult = Bun.spawnSync(["rm", "src/native.node"]); + if (cleanupResult.exitCode !== 0) { + log(`Failed to remove temporary native module: ${cleanupResult.stderr.toString()}`, "warning"); + } else { + logWithTime("Native module cleanup completed", cleanupStartTime, "success"); + } + + // 8. Remove build/ folder + const finalCleanupStartTime = performance.now(); + log("Removing build/ directory...", "info"); + + const finalCleanupResult = Bun.spawnSync(["rm", "-rf", "build"]); + if (finalCleanupResult.exitCode !== 0) { + log(`Failed to remove build/ directory: ${finalCleanupResult.stderr.toString()}`, "warning"); + } else { + logWithTime("Successfully removed build/ directory", finalCleanupStartTime, "success"); + } + + // 9. Remove all remaining empty folders from lib/ folder + const removeEmptyFoldersStartTime = performance.now(); + log("Starting empty folders cleanup...", "info"); + + const removeEmptyFoldersResult = Bun.spawnSync(["find", "lib", "-type", "d", "-empty", "-delete"]); + if (removeEmptyFoldersResult.exitCode !== 0) { + log(`Failed to remove empty folders: ${removeEmptyFoldersResult.stderr.toString()}`, "warning"); + } else { + logWithTime("Empty folders cleanup completed", removeEmptyFoldersStartTime, "success"); + } + + logWithTime("Total build process completed", startTime, "success"); +} catch (e) { + const error = e as AggregateError; + log("Build Failed", "error"); + + // Example: Using the built-in formatter + log(error, "error"); + + // Example: Serializing the failure as a JSON string. + log(JSON.stringify(error, null, 2), "error"); + process.exit(1); +} diff --git a/src/debugger.ts b/src/debugger.ts new file mode 100644 index 0000000..16883fa --- /dev/null +++ b/src/debugger.ts @@ -0,0 +1,152 @@ +// @ts-nocheck +// TODO: In the future, we plan to add proper typing +import EventEmitter from 'events'; + +const lengths = { + byte: 1, + int: 4, + int32: 4, + uint32: 4, + int64: 8, + uint64: 8, + dword: 4, + short: 2, + long: 8, + float: 4, + double: 8, + bool: 1, + boolean: 1, + ptr: 4, + pointer: 4, + // str: 0, + // string: 0, + // vec3: 0, + // vector3: 0, + // vec4: 0, + // vector4: 0, +}; + +// Tracks used and unused registers +class Registers { + constructor() { + this.registers = Object.freeze({ + DR0: 0x0, + DR1: 0x1, + DR2: 0x2, + DR3: 0x3, + }); + + this.used = []; + } + + getRegister() { + const unused = Object + .values(this.registers) + .filter(r => !this.used.includes(r)); + + return unused[0]; + } + + busy(register) { + this.used.push(register); + } + + unbusy(register) { + this.used.splice(this.used.indexOf(register), 1); + } +} + +class Debugger extends EventEmitter { + constructor(memoryprocess) { + super(); + this.memoryprocess = memoryprocess; + this.registers = new Registers(); + this.attached = false; + this.intervals = []; + } + + attach(processId, killOnDetach = false) { + const success = this.memoryprocess.attachDebugger(processId, killOnDetach); + + if (success) { + this.attached = true; + } + + return success; + } + + detach(processId) { + this.intervals.map(({ id }) => clearInterval(id)); + return this.memoryprocess.detachDebugger(processId); + } + + removeHardwareBreakpoint(processId, register) { + const success = this.memoryprocess.removeHardwareBreakpoint(processId, register); + + if (success) { + this.registers.unbusy(register); + } + + // Find the register's corresponding interval and delete it + this.intervals.forEach(({ register: r, id }) => { + if (r === register) { + clearInterval(id); + } + }); + + return success; + } + + setHardwareBreakpoint(processId, address, trigger, dataType) { + let size = lengths[dataType]; + + // If we are breakpointing a string, we need to determine the length of it + if (dataType === 'str' || dataType === 'string') { + const { handle } = this.memoryprocess.openProcess(processId); + const value = this.memoryprocess.readMemory(handle, address, this.memoryprocess.STRING); + + size = value.length; + + this.memoryprocess.closeProcess(handle); + } + + // Obtain an available register + const register = this.registers.getRegister(); + const success = this.memoryprocess + .setHardwareBreakpoint(processId, address, register, trigger, size); + + // If the breakpoint was set, mark this register as busy + if (success) { + this.registers.busy(register); + this.monitor(register); + } + + return register; + } + + monitor(register, timeout = 100) { + const id = setInterval(() => { + const debugEvent = this.memoryprocess.awaitDebugEvent(register, timeout); + + if (debugEvent) { + this.memoryprocess.handleDebugEvent(debugEvent.processId, debugEvent.threadId); + + // Global event for all registers + this.emit('debugEvent', { + register, + event: debugEvent, + }); + + // Event per register + this.emit(register, debugEvent); + } + }, 100); + + this.intervals.push({ + register, + id, + }); + } +} + +export default Debugger; diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index 136a2d2..0000000 --- a/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { readMemory, writeMemory } from './memory'; -import { openProcess, closeProcess, type ProcessObject } from './process'; - -export { - readMemory, - writeMemory, - openProcess, - closeProcess, - type ProcessObject -}; - -const memoryprocess = { - readMemory, - writeMemory, - openProcess, - closeProcess -}; - -export default memoryprocess; diff --git a/src/memory.ts b/src/memory.ts deleted file mode 100644 index 4e79958..0000000 --- a/src/memory.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { dlopen } from "bun:ffi"; - -// Dynamically resolve the path to the DLL relative to the built file -const libPath = import.meta.resolve("./memoryprocess.dll"); - -const { symbols } = dlopen(libPath, { - readMemory: { - args: ["uint64_t", "uint64_t", "cstring"], - returns: "int", - }, - writeMemory: { - args: ["uint64_t", "uint64_t", "cstring", "ptr"], - returns: "void", - }, -}) - -/** Represents the valid data types for memory operations. */ -export type MemoryDataType = - | "byte" | "int8" | "char" // 8-bit signed - | "ubyte" | "uint8" | "uchar" // 8-bit unsigned - | "short" | "int16" // 16-bit signed - | "ushort" | "uint16" | "word" // 16-bit unsigned - | "int" | "int32" | "long" // 32-bit signed - | "uint" | "uint32" | "ulong" | "dword" // 32-bit unsigned - | "float" // 32-bit float - | "double" // 64-bit float - | "longlong" | "int64" // 64-bit signed (Note: JS Number limitations apply) - | "ulonglong" | "uint64" // 64-bit unsigned (Note: JS Number limitations apply) - | "bool" - | "string" | "str"; // Null-terminated string - -/** Represents the possible value types corresponding to MemoryDataType. */ -export type MemoryValueType = number | string | boolean; - -/** - * Reads memory from a process. - * @param handle - The handle to the process. - * @param address - The address to read from. - * @param dataType - The data type to read. - * @returns The value read from memory. - */ -export function readMemory(handle: number, address: number, dataType: MemoryDataType): number { - const dataTypeBuffer = Buffer.from(dataType + "\0") - const result = symbols.readMemory(handle, address, dataTypeBuffer) - return result -} - -/** - * Writes memory to a process. - * @param handle - The handle to the process. - * @param address - The address to write to. - * @param dataType - The data type to write. - * @param value - The value to write. Should be `number` for numeric types, `boolean` for bool, and `string` for string. - */ -export function writeMemory( - handle: number, - address: number, - dataType: MemoryDataType, - value: MemoryValueType, -): void { - const dataTypeBuffer = Buffer.from(dataType + "\0") - - let valueBuffer: Buffer; - - // Create buffer with correct binary representation based on dataType - // This needs to handle all types supported by the C++ function - if (dataType === "int" || dataType === "int32" || dataType === "long") { - valueBuffer = Buffer.alloc(4); - valueBuffer.writeInt32LE(value as number, 0); - } else if (dataType === "uint" || dataType === "uint32" || dataType === "ulong" || dataType === "dword") { - valueBuffer = Buffer.alloc(4); - valueBuffer.writeUInt32LE(value as number, 0); - } else if (dataType === "short" || dataType === "int16") { - valueBuffer = Buffer.alloc(2); - valueBuffer.writeInt16LE(value as number, 0); - } else if (dataType === "ushort" || dataType === "uint16" || dataType === "word") { - valueBuffer = Buffer.alloc(2); - valueBuffer.writeUInt16LE(value as number, 0); - } else if (dataType === "byte" || dataType === "int8" || dataType === "char") { - valueBuffer = Buffer.alloc(1); - valueBuffer.writeInt8(value as number, 0); - } else if (dataType === "ubyte" || dataType === "uint8" || dataType === "uchar") { - valueBuffer = Buffer.alloc(1); - valueBuffer.writeUInt8(value as number, 0); - } else if (dataType === "float") { - valueBuffer = Buffer.alloc(4); - valueBuffer.writeFloatLE(value as number, 0); - } else if (dataType === "double") { - valueBuffer = Buffer.alloc(8); - valueBuffer.writeDoubleLE(value as number, 0); - } else if (dataType === "longlong" || dataType === "int64") { - valueBuffer = Buffer.alloc(8); - valueBuffer.writeBigInt64LE(BigInt(value), 0); - } else if (dataType === "ulonglong" || dataType === "uint64") { - valueBuffer = Buffer.alloc(8); - valueBuffer.writeBigUInt64LE(BigInt(value), 0); - } else if (dataType === "bool") { - valueBuffer = Buffer.alloc(1); - valueBuffer.writeUInt8(value ? 1 : 0, 0); - } else if (dataType === "string" || dataType === "str") { - // Ensure null termination for C++ side - valueBuffer = Buffer.from((value as string) + "\0", "utf8"); - } else if (dataType === "ptr" || dataType === "pointer") { - valueBuffer = Buffer.alloc(8); // Assuming 64-bit pointers - valueBuffer.writeBigUInt64LE(BigInt(value), 0); - } else if (dataType === "uptr" || dataType === "upointer") { - valueBuffer = Buffer.alloc(8); // Assuming 64-bit pointers - valueBuffer.writeBigUInt64LE(BigInt(value), 0); - } - // TODO: Add Vector3/Vector4 handling if needed - else { - throw new Error(`Unsupported data type for writeMemory: ${dataType}`); - } - - symbols.writeMemory(handle, address, dataTypeBuffer, valueBuffer) -} \ No newline at end of file diff --git a/src/memoryprocess.d.ts b/src/memoryprocess.d.ts deleted file mode 100644 index 8a8e71b..0000000 --- a/src/memoryprocess.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module "*.dll" { - const value: string; - export default value; -} \ No newline at end of file diff --git a/src/memoryprocess.ts b/src/memoryprocess.ts new file mode 100644 index 0000000..db4b8b9 --- /dev/null +++ b/src/memoryprocess.ts @@ -0,0 +1,547 @@ +// @ts-ignore +import memoryprocess from './native.node'; +import { existsSync, type PathLike } from 'fs'; +import { MemoryAllocationFlags, type Protection, MemoryAccessFlags, MemoryPageFlags, type Process, type Module, type DataType, type MemoryData } from "./types" +import Debugger from './debugger'; +import { STRUCTRON_TYPE_STRING } from './utils'; + +/* TODO: + * - remove callbacks from all functions and implement promise support using Napi + * - validate argument types in JS space instead of C++ + * - refactor read/write memory functions to use buffers instead? + */ + +/** + * Opens a process by name or id. + * + * @param processIdentifier - The name or id of the process to open. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The handle of the opened process or undefined if the process was not found. + */ +function openProcess(processIdentifier: string | number, callback?: ((handle: number, errorMessage: string) => void) | undefined): Process { + if (!callback) { + return memoryprocess.openProcess(processIdentifier); + } + + return memoryprocess.openProcess(processIdentifier, callback); +} + +/** + * Closes a handle to a process. + * + * @param handle - The handle of the process to close. + * @returns Whether the operation was successful. + */ +function closeHandle(handle: number) { + return memoryprocess.closeHandle(handle); +} + +/** + * Retrieves a list of all processes currently running on the system. + * + * @param callback - Optional callback function to handle the result asynchronously. + * @returns An array of process objects or undefined if the operation failed. + */ +function getProcesses(callback?: ((processes: Process[], errorMessage: string) => void) | undefined) { + if (!callback) { + return memoryprocess.getProcesses(); + } + + return memoryprocess.getProcesses(callback); +} + +/** + * Finds a module by name within a process. + * + * @param moduleName - The name of the module to find. + * @param processId - The ID of the process to search within. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The module object or undefined if the module was not found. + */ +function findModule(moduleName: string, processId: number, callback?: ((module: Module, errorMessage: string) => void) | undefined) { + if (!callback) { + return memoryprocess.findModule(moduleName, processId); + } + + return memoryprocess.findModule(moduleName, processId, callback); +} + +/** + * Retrieves a list of all modules loaded by a process. + * + * @param processId - The ID of the process to search within. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns An array of module objects or undefined if the operation failed. + */ +function getModules(processId: number, callback?: ((modules: Module[], errorMessage: string) => void) | undefined) { + if (!callback) { + return memoryprocess.getModules(processId); + } + + return memoryprocess.getModules(processId, callback); +} + +/** + * Reads a value from a process's memory. + * + * @param handle - The handle of the process to read from. + * @param address - The address to read from. + * @param dataType - The data type to read. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The read value or undefined if the operation failed. + */ +function readMemory(handle: number, address: number, dataType: T, callback?: (value: MemoryData, errorMessage: string) => void): MemoryData | undefined { + if (dataType.endsWith('_be')) { + return readMemoryBE(handle, address, dataType, callback); + } + + if (!callback) { + return memoryprocess.readMemory(handle, address, dataType); + } + + return memoryprocess.readMemory(handle, address, dataType, callback); +} + +/** + * Reads a value from a process's memory in big-endian format. + * + * @param handle - The handle of the process to read from. + * @param address - The address to read from. + * @param dataType - The data type to read. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The read value or undefined if the operation failed. + */ +function readMemoryBE(handle: number, address: number, dataType: T, callback?: (value: MemoryData, errorMessage: string) => void): MemoryData | undefined { + let value: number | bigint | null = null; + + switch (dataType) { + case 'int64_be': + value = readBuffer(handle, address, 8).readBigInt64BE(); + break; + + case 'uint64_be': + value = readBuffer(handle, address, 8).readBigUInt64BE(); + break; + + case 'int32_be': + case 'int_be': + case 'long_be': + value = readBuffer(handle, address, 4).readInt32BE(); + break; + + case 'uint32_be': + case 'uint_be': + case 'ulong_be': + value = readBuffer(handle, address, 4).readUInt32BE(); + break; + + case 'int16_be': + case 'short_be': + value = readBuffer(handle, address, 2).readInt16BE(); + break; + + case 'uint16_be': + case 'ushort_be': + value = readBuffer(handle, address, 2).readUInt16BE(); + break; + + case 'float_be': + value = readBuffer(handle, address, 4).readFloatBE(); + break; + + case 'double_be': + value = readBuffer(handle, address, 8).readDoubleBE(); + break; + } + + if (typeof callback !== 'function') { + if (value === null) { + throw new Error('Invalid data type argument!'); + } + + return value as MemoryData; + } + + callback(value as MemoryData, value === null ? 'Invalid data type argument!' : ''); +} + +/** + * Reads a buffer of specified size from a process's memory. + * + * @param handle - The handle of the process to read from. + * @param address - The memory address to read from. + * @param size - The number of bytes to read. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns A buffer containing the read data or undefined if the operation failed. + */ +function readBuffer(handle: number, address: number, size: number, callback?: (buffer: Buffer, errorMessage: string) => void): Buffer { + if (arguments.length === 3) { + return memoryprocess.readBuffer(handle, address, size); + } + + return memoryprocess.readBuffer(handle, address, size, callback); +} + +/** + * Writes a value to a process's memory. + * + * @param handle - The handle of the process to write to. + * @param address - The address to write to. + * @param value - The value to write. + * @param dataType - The data type to write. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns Whether the operation was successful. + */ +function writeMemory(handle: number, address: number, value: string, dataType: 'str'|'string'): boolean; +function writeMemory>(handle: number, address: number, value: MemoryData, dataType: T): boolean; +function writeMemory(handle: number, address: number, value: any, dataType: DataType): boolean { + let dataValue: MemoryData = value; + if (dataType === 'str' || dataType === 'string') { + // ensure TS knows this branch yields a string for T = 'str'|'string' + dataValue = ((value as string) + '\0') as MemoryData; + } + + const bigintTypes: DataType[] = ['int64', 'uint64', 'int64_be', 'uint64_be']; + if (bigintTypes.includes(dataType) && typeof value !== 'bigint') { + throw new Error(`${dataType.toUpperCase()} expects type BigInt`); + } + + if (dataType.endsWith('_be')) { + // dataValue narrowed to numeric types in BE branch + writeMemoryBE(handle, address, dataValue as number | bigint, dataType); + return true; + } + + return memoryprocess.writeMemory(handle, address, dataValue, dataType); +} + +/** + * Writes a value to a process's memory in big-endian format. + * + * @param handle - The handle of the process to write to. + * @param address - The address to write to. + * @param value - The value to write. + * @param dataType - The data type to write. + * @returns Whether the operation was successful. + */ +function writeMemoryBE(handle: number, address: number, value: number | bigint, dataType: DataType): boolean { + let buffer: Buffer | null = null; + + switch (dataType) { + case 'int64_be': + if (typeof value !== 'bigint') { + throw new Error('INT64_BE expects type BigInt'); + } + buffer = Buffer.alloc(8); + buffer.writeBigInt64BE(value); + break; + + case 'uint64_be': + if (typeof value !== 'bigint') { + throw new Error('UINT64_BE expects type BigInt'); + } + buffer = Buffer.alloc(8); + buffer.writeBigUInt64BE(value); + break; + + case 'int32_be': + case 'int_be': + case 'long_be': + buffer = Buffer.alloc(4); + buffer.writeInt32BE(value as number); + break; + + case 'uint32_be': + case 'uint_be': + case 'ulong_be': + buffer = Buffer.alloc(4); + buffer.writeUInt32BE(value as number); + break; + + case 'int16_be': + case 'short_be': + buffer = Buffer.alloc(2); + buffer.writeInt16BE(value as number); + break; + + case 'uint16_be': + case 'ushort_be': + buffer = Buffer.alloc(2); + buffer.writeUInt16BE(value as number); + break; + + case 'float_be': + buffer = Buffer.alloc(4); + buffer.writeFloatBE(value as number); + break; + + case 'double_be': + buffer = Buffer.alloc(8); + buffer.writeDoubleBE(value as number); + break; + } + + if (buffer == null) { + throw new Error('Invalid data type argument!'); + } + + writeBuffer(handle, address, buffer as Buffer); + return true; +} + +/** + * Writes a buffer of specified size to a process's memory. + * + * @param handle - The handle of the process to write to. + * @param address - The memory address to write to. + * @param buffer - The buffer containing the data to write. + * @returns Whether the operation was successful. + */ +function writeBuffer(handle: number, address: number, buffer: Buffer) { + return memoryprocess.writeBuffer(handle, address, buffer); +} + +// TODO: Implement pattern scanning functionality with various overloads to match the C++ implementation +function findPattern(...args: any[]): any { + const pattern = ['number', 'string', 'number', 'number'].toString(); + const patternByModule = ['number', 'string', 'string', 'number', 'number'].toString(); + const patternByAddress = ['number', 'number', 'string', 'number', 'number'].toString(); + + const types = args.map(arg => typeof arg); + + if (types.slice(0, 4).toString() === pattern) { + if (types.length === 4 || (types.length === 5 && types[4] === 'function')) { + // @ts-ignore + return memoryprocess.findPattern(...args); + } + } + + if (types.slice(0, 5).toString() === patternByModule) { + if (types.length === 5 || (types.length === 6 && types[5] === 'function')) { + // @ts-ignore + return memoryprocess.findPatternByModule(...args); + } + } + + if (types.slice(0, 5).toString() === patternByAddress) { + if (types.length === 5 || (types.length === 6 && types[5] === 'function')) { + // @ts-ignore + return memoryprocess.findPatternByAddress(...args); + } + } + + throw new Error('invalid arguments!'); +} + +/** + * Calls a function in a process's memory. + * + * @param handle - The handle of the process to call the function in. + * @param args - The arguments to pass to the function. + * @param returnType - The return type of the function. + * @param address - The address of the function to call. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The return value of the function or undefined if the operation failed. + */ +function callFunction(handle: number, args: any[], returnType: number, address: number, callback: ((errorMessage: string, info: { returnValue: any; exitCode: number; }) => void) | undefined) { + if (arguments.length === 4) { + return memoryprocess.callFunction(handle, args, returnType, address); + } + + return memoryprocess.callFunction(handle, args, returnType, address, callback); +} + +/** + * Allocates memory in a process's virtual address space. + * + * @param handle - The handle of the process to allocate memory in. + * @param address - The address to allocate memory at. If null, the memory will be allocated at the next available address. + * @param size - The size of the memory block to allocate. + * @param allocationType - The type of memory allocation to use. + * @param protection - The memory protection to apply. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The base address of the allocated memory or undefined if the operation failed. + */ +function virtualAllocEx( + handle: number, + address: number | null, + size: number, + allocationType: keyof typeof MemoryAllocationFlags, + protection: keyof typeof MemoryAccessFlags, + callback?: (errorMessage: string, baseAddress: number) => void +) { + const allocCode = MemoryAllocationFlags[allocationType]; + const protCode = MemoryAccessFlags[protection]; + if (arguments.length === 5) { + return memoryprocess.virtualAllocEx(handle, address, size, allocCode, protCode); + } + return memoryprocess.virtualAllocEx(handle, address, size, allocCode, protCode, callback!); +} + +/** + * Changes the protection of a region of memory in a process's virtual address space. + * + * @param handle - The handle of the process to change the memory protection in. + * @param address - The starting address of the memory region. + * @param size - The size of the memory region. + * @param protection - The new memory protection to apply. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The old memory protection or undefined if the operation failed. + */ +function virtualProtectEx( + handle: number, + address: number, + size: number, + protection: keyof typeof MemoryAccessFlags, + callback?: (errorMessage: string, oldProtection: Protection) => void +) { + const protCode = MemoryAccessFlags[protection]; + + if (arguments.length === 4) { + return memoryprocess.virtualProtectEx(handle, address, size, protCode); + } + return memoryprocess.virtualProtectEx(handle, address, size, protCode, callback!); +} + +/** + * Maps a view of a file into the virtual address space of a process. + * + * @param handle - The handle of the process to map the file into. + * @param fileHandle - The handle of the file to map. + * @param offset - The offset within the file to map. + * @param viewSize - The size of the view to map. + * @param pageProtection - The memory protection to apply. + * @returns The base address of the mapped view or undefined if the operation failed. + */ +function mapViewOfFile( + handle: number, + fileHandle: number, + offset: number, + viewSize: number, + pageProtection: keyof typeof MemoryPageFlags +) { + const pageCode = MemoryPageFlags[pageProtection]; + if (arguments.length === 2) { + return memoryprocess.mapViewOfFile(handle, fileHandle, 0, 0, pageCode); + } + return memoryprocess.mapViewOfFile(handle, fileHandle, offset, viewSize, pageCode); +} + +/** + * Retrieves a list of memory regions in a process's virtual address space. + * + * @param handle - The handle of the process to retrieve memory regions from. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns An array of memory regions or undefined if the operation failed. + */ +function getRegions(handle: number, callback: ((regions: any[], errorMessage: string) => void) | undefined) { + if (arguments.length === 1) { + return memoryprocess.getRegions(handle); + } + + return memoryprocess.getRegions(handle, callback); +} + +/** + * Retrieves information about a specific memory region in a process's virtual address space. + + * @param handle - The handle of the process to retrieve memory region information from. + * @param address - The starting address of the memory region. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns The memory region information or undefined if the operation failed. + */ +function virtualQueryEx(handle: number, address: number, callback: ((region: any, errorMessage: string) => void) | undefined) { + if (arguments.length === 2) { + return memoryprocess.virtualQueryEx(handle, address); + } + + return memoryprocess.virtualQueryEx(handle, address, callback); +} + +/** + * Injects a DLL into a process. + + * @param handle - The handle of the process to inject the DLL into. + * @param dllPath - The path to the DLL to inject. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns Whether the operation was successful. + */ +function injectDll(handle: number, dllPath: PathLike, callback: ((errorMessage: string, success: boolean) => void) | undefined) { + if (!dllPath.toString().endsWith('.dll')) { + throw new Error("Given path is invalid: file is not of type 'dll'."); + } + + if (existsSync(dllPath)) { + throw new Error('Given path is invaild: file does not exist.'); + } + + if (arguments.length === 2) { + return memoryprocess.injectDll(handle, dllPath.toString()); + } + + return memoryprocess.injectDll(handle, dllPath.toString(), callback); +} + +/** + * Unloads a DLL from a process. + * + * @param handle - The handle of the process to unload the DLL from. + * @param module - The module to unload. + * @param callback - Optional callback function to handle the result asynchronously. + * @returns Whether the operation was successful. + */ +function unloadDll(handle: number, module: string | number, callback: ((errorMessage: string, success: boolean) => void) | undefined) { + if (arguments.length === 2) { + return memoryprocess.unloadDll(handle, module); + } + + return memoryprocess.unloadDll(handle, module, callback); +} + +/** + * Opens a file mapping object. + * + * @param fileName - The name of the file to open. + * @returns The handle of the opened file mapping object or undefined if the operation failed. + */ +function openFileMapping(fileName: string) { + if (arguments.length !== 1 || typeof fileName !== 'string') { + throw new Error('invalid arguments!'); + } + + return memoryprocess.openFileMapping(fileName); +} + +const library = { + openProcess, + closeHandle, + getProcesses, + findModule, + getModules, + readMemory, + readBuffer, + writeMemory, + writeBuffer, + findPattern, + callFunction, + virtualAllocEx, + virtualProtectEx, + getRegions, + virtualQueryEx, + injectDll, + unloadDll, + openFileMapping, + mapViewOfFile, + attachDebugger: memoryprocess.attachDebugger, + detachDebugger: memoryprocess.detachDebugger, + awaitDebugEvent: memoryprocess.awaitDebugEvent, + handleDebugEvent: memoryprocess.handleDebugEvent, + setHardwareBreakpoint: memoryprocess.setHardwareBreakpoint, + removeHardwareBreakpoint: memoryprocess.removeHardwareBreakpoint, + Debugger: new Debugger(memoryprocess), +}; + +export default { + ...library, + STRUCTRON_TYPE_STRING: STRUCTRON_TYPE_STRING(library), +}; diff --git a/src/process.ts b/src/process.ts deleted file mode 100644 index 331f88d..0000000 --- a/src/process.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { dlopen } from "bun:ffi"; - -// Dynamically resolve the path to the DLL relative to the built file -const libPath = import.meta.resolve("./memoryprocess.dll"); - -export interface ProcessObject { - dwSize: number; - th32ProcessID: number; - cntThreads: number; - th32ParentProcessID: number; - pcPriClassBase: number; - szExeFile: string; - handle: number; - modBaseAddr: number; -} - -const { symbols } = dlopen(libPath, { - openProcess: { - args: ["cstring"], - returns: "cstring", - }, - closeProcess: { - args: ["int"], - returns: "void", - }, -}) - -/** - * Opens a process by name. - * @param processName - The name of the process to open. - * @returns The opened process object. - */ -export function openProcess(processName: string): ProcessObject { - const processNameBuffer = Buffer.from(processName + "\0") - const processCString = symbols.openProcess(processNameBuffer) - const process = JSON.parse(processCString.toString()) as ProcessObject - return process -} - -/** - * Closes a process handle. - * @param handle - The handle to the process to close. - */ -export function closeProcess(handle: number): void { - try { - if (symbols.closeProcess) { - symbols.closeProcess(handle); - } else { - console.error("closeProcess FFI symbol not found."); - } - } catch (e) { - console.error(`Error closing handle ${handle}:`, e); - } -} \ No newline at end of file diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..ae83c9c --- /dev/null +++ b/src/types.ts @@ -0,0 +1,175 @@ +/** Function types */ +export const FunctionTypes = { + T_VOID: 0x0, + T_STRING: 0x1, + T_CHAR: 0x2, + T_BOOL: 0x3, + T_INT: 0x4, + T_DOUBLE: 0x5, + T_FLOAT: 0x6, +} as const; + +/** Signature scanning flags */ +export const SignatureTypes = { + NORMAL: 0x0, + READ: 0x1, + SUBTRACT: 0x2, +} as const; + +// Memory access flags +export const MemoryAccessFlags = { + PAGE_NOACCESS: 0x01, + PAGE_READONLY: 0x02, + PAGE_READWRITE: 0x04, + PAGE_WRITECOPY: 0x08, + PAGE_EXECUTE: 0x10, + PAGE_EXECUTE_READ: 0x20, + PAGE_EXECUTE_READWRITE: 0x40, + PAGE_EXECUTE_WRITECOPY: 0x80, + PAGE_GUARD: 0x100, + PAGE_NOCACHE: 0x200, + PAGE_WRITECOMBINE: 0x400, + PAGE_ENCLAVE_UNVALIDATED: 0x20000000, + PAGE_TARGETS_NO_UPDATE: 0x40000000, + PAGE_TARGETS_INVALID: 0x40000000, + PAGE_ENCLAVE_THREAD_CONTROL: 0x80000000, +} as const; + +// Memory allocation flags +export const MemoryAllocationFlags = { + MEM_COMMIT: 0x00001000, + MEM_RESERVE: 0x00002000, + MEM_RESET: 0x00080000, + MEM_TOP_DOWN: 0x00100000, + MEM_RESET_UNDO: 0x1000000, + MEM_LARGE_PAGES: 0x20000000, + MEM_PHYSICAL: 0x00400000, +} as const; + +// Memory page flags +export const MemoryPageFlags = { + MEM_PRIVATE: 0x20000, + MEM_MAPPED: 0x40000, + MEM_IMAGE: 0x1000000, +} as const; + +// Hardware debug registers +export const HardwareDebugRegisters = { + DR0: 0x0, + DR1: 0x1, + DR2: 0x2, + DR3: 0x3, +} as const; + +// Breakpoint trigger types +export const BreakpointTriggerTypes = { + TRIGGER_EXECUTE: 0x0, + TRIGGER_ACCESS: 0x3, + TRIGGER_WRITE: 0x1, +} as const; + + +export type Protection = typeof MemoryAccessFlags[keyof typeof MemoryAccessFlags]; +export type PageProtection = typeof MemoryPageFlags[keyof typeof MemoryPageFlags]; +export type AllocationType = typeof MemoryAllocationFlags[keyof typeof MemoryAllocationFlags]; +export type BreakpointTriggerType = typeof BreakpointTriggerTypes[keyof typeof BreakpointTriggerTypes]; + +/** + * Represents a process with its associated information and handle + */ +export interface Process { + /** + * Size of the structure, in bytes + */ + dwSize: number; + /** + * Process identifier (PID) + */ + th32ProcessID: number; + /** + * Number of execution threads started by the process + */ + cntThreads: number; + /** + * PID of the parent process + */ + th32ParentProcessID: number; + /** + * Base priority of threads created by this process + */ + pcPriClassBase: number; + /** + * Path to the executable file + */ + szExeFile: string; + /** + * Process handle (for read/write operations) + */ + handle: number; + /** + * Base address of the process's primary module + */ + modBaseAddr: number; +} + +/** + * Represents a module with its associated information + */ +export interface Module { + /** + * Base address of the module in the process's virtual address space + */ + modBaseAddr: number; + /** + * Size of the module, in bytes + */ + modBaseSize: number; + /** + * Full path to the module file + */ + szExePath: string; + /** + * Module name (filename) + */ + szModule: string; + /** + * Process identifier (PID) of the process owning this module + */ + th32ProcessID: number; + /** + * Global usage count of the module + */ + GlblcntUsage: number; +} + +/** + * Supported data types from constants.standard + */ +export type DataType = + 'byte' | 'ubyte' | 'char' | 'uchar' | + 'int8' | 'uint8' | + 'int16' | 'int16_be' | 'uint16' | 'uint16_be' | + 'short' | 'short_be' | 'ushort' | 'ushort_be' | + 'long' | 'long_be' | 'ulong' | 'ulong_be' | + 'int' | 'int_be' | 'uint' | 'uint_be' | + 'int32' | 'int32_be' | 'uint32' | 'uint32_be' | + 'int64' | 'int64_be' | 'uint64' | 'uint64_be' | + 'word' | 'dword' | + 'float' | 'float_be' | + 'double' | 'double_be'| + 'bool' | 'boolean' | + 'ptr' | 'pointer' | 'uptr' | 'upointer' | + 'str' | 'string' | + 'vec3' | 'vector3' | + 'vec4' | 'vector4'; + +/** + * Maps a DataType to its corresponding JS return type + */ +export type MemoryData = +/** 64-bit integers (LE/BE) as BigInt */ +T extends 'int64' | 'uint64' | 'int64_be' | 'uint64_be' ? bigint : +T extends 'string' | 'str' ? string : +T extends 'vector3' | 'vec3' ? { x: number; y: number; z: number } : +T extends 'vector4' | 'vec4' ? { x: number; y: number; z: number; w: number } : +number; \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..983076b --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,75 @@ +// @ts-nocheck +// TODO: In the future, we plan to add proper typing +const SIZEOF_STDSTRING_32BIT = 24; +const SIZEOF_STDSTRING_64BIT = 32; +const STDSTRING_LENGTH_OFFSET = 0x10; + +/** + * Custom string consumer/producer for Structron (due to complexity of `std::string`) + * `std::string` is a container for a string which makes reading/writing to it tricky, + * it will either store the string itself, or a pointer to the string, based on the + * length of the string. When we want to read from or write to a buffer, we need + * to determine if the string is in the buffer itself, or if the buffer + * just contains a pointer to the string. Based on one of these options, + * we can read from or write to the string. + * + * @param handle the handle to the process + * @param structAddress the base address of the structure in memory + * @param platform the architecture of the process, either "32" or "64" + * @param encoding the encoding type of the string + */ +export const STRUCTRON_TYPE_STRING = memoryprocess => (handle, structAddress, platform, encoding = 'utf8') => ({ + read(buffer, offset) { + // get string length from `std::string` container + const length = buffer.readUInt32LE(offset + STDSTRING_LENGTH_OFFSET); + + // if length > 15, `std::string` has a pointer to the string + if (length > 15) { + const pointer = platform === '64' ? buffer.readBigInt64LE(offset) : buffer.readUInt32LE(offset); + return memoryprocess.readMemory(handle, Number(pointer), 'string'); + } + + // if length <= 15, `std::string` directly contains the string + return buffer.toString(encoding, offset, offset + length); + }, + write(value, context, offset) { + // address containing the length of the string + const lengthAddress = structAddress + offset + STDSTRING_LENGTH_OFFSET; + + // get existing `std::string` buffer + const bufferSize = platform === '64' ? SIZEOF_STDSTRING_64BIT : SIZEOF_STDSTRING_32BIT; + const existingBuffer = memoryprocess.readBuffer(handle, structAddress + offset, bufferSize); + + // fetch length of string in memory (to determine if it's pointer based) + const length = memoryprocess.readMemory(handle, lengthAddress, 'int'); + + if ((length > 15 && value.length <= 15) || (length <= 15 && value.length > 15)) { + // there are two ways strings are stored: directly or with a pointer, + // we can't go from one to the other (without introducing more complexity), + // so just skip the bytes to prevent crashing. if a pointer is used, we could + // technically write any length, but the next time we try writing, we will read + // the length and assume it's not stored via pointer and will lead to crashes + + // write existing buffer without changes + existingBuffer.copy(context.buffer, offset); + return; + } + + // write new length + memoryprocess.writeMemory(handle, lengthAddress, value.length, 'uint32'); + existingBuffer.writeUInt32LE(value.length, STDSTRING_LENGTH_OFFSET); + + if (length > 15 && value.length > 15) { + // write new string in memory + const pointer = memoryprocess.readMemory(handle, structAddress + offset, 'pointer'); + memoryprocess.writeMemory(handle, pointer, value, 'string'); + } else if (length <= 15 && value.length <= 15) { + // write new string directly into buffer + existingBuffer.write(value, encoding); + } + + // write our new `std::string` buffer into the buffer we are creating + existingBuffer.copy(context.buffer, offset); + }, + SIZE: platform === '64' ? SIZEOF_STDSTRING_64BIT : SIZEOF_STDSTRING_32BIT, +}); diff --git a/tsconfig.json b/tsconfig.json index 2767c59..6a55b42 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,34 +1,30 @@ { "compilerOptions": { - "declaration": true, - "sourceMap": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "outDir": "lib", - - // Environment setup & latest features - "lib": ["ESNext"], - "target": "ESNext", - "module": "ESNext", + /* Base Options: */ + "esModuleInterop": true, + "skipLibCheck": true, + "allowJs": true, + "resolveJsonModule": true, "moduleDetection": "force", - "jsx": "react-jsx", - - // Bundler mode - "moduleResolution": "bundler", - // "allowImportingTsExtensions": true, - // "verbatimModuleSyntax": true, - // "noEmit": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, - // Best practices + /* Strictness */ "strict": true, - "skipLibCheck": true, - "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + "module": "Preserve", + "target": "ES2022", + "lib": ["ES2022"], - // Some stricter flags (disabled by default) - "noUnusedLocals": false, - "noUnusedParameters": false, - "noPropertyAccessFromIndexSignature": false, + "moduleResolution": "bundler", + "declaration": true, + "emitDeclarationOnly": true, + "noEmit": false, + "outDir": "lib", + "rootDir": "." }, - "include": ["src/**/*.ts"] + "include": ["index.ts", "src/**/*.ts", "scripts/**/*.ts"], + "exclude": ["node_modules"] }