From 510b06322350322f924e14b363a97500f266197d Mon Sep 17 00:00:00 2001 From: Lautaro Jayat Date: Tue, 26 Dec 2023 13:52:43 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20first=20commit=20=F0=9F=94=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yaml | 18 + .github/workflows/test.yaml | 18 + .gitignore | 131 + LICENSE | 21 + README.md | 142 + assets/header.png | Bin 0 -> 21171 bytes jest.config.js | 5 + package.json | 33 + src/SQLGenerator/composeSQLQuery.ts | 38 + src/SQLGenerator/generateSQLSelectStmt.ts | 26 + src/SQLGenerator/generateSQLWhereStmt.ts | 114 + src/SQLGenerator/getCommand.ts | 8 + src/SQLGenerator/index.ts | 3 + src/SQLGenerator/types.ts | 224 ++ src/cli/index.ts | 48 + src/constants.ts | 22 + src/e2e/e2e.test.ts | 191 ++ src/parseMongoArgs/parseMongoArgs.ts | 141 + .../test/_getIndexesOfArgs.test.ts | 113 + src/parseMongoArgs/test/_swapQuotes.test.ts | 20 + .../test/getWehereAndSelect.test.ts | 127 + src/parseMongoCollectionName/index.ts | 1 + .../parseCollectionName.ts | 48 + .../test/parseCollectionName.test.ts | 51 + src/utils/utils.ts | 39 + tsconfig.build.json | 6 + tsconfig.json | 111 + yarn.lock | 2299 +++++++++++++++++ 28 files changed, 3998 insertions(+) create mode 100644 .github/workflows/build.yaml create mode 100644 .github/workflows/test.yaml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 assets/header.png create mode 100644 jest.config.js create mode 100644 package.json create mode 100644 src/SQLGenerator/composeSQLQuery.ts create mode 100644 src/SQLGenerator/generateSQLSelectStmt.ts create mode 100644 src/SQLGenerator/generateSQLWhereStmt.ts create mode 100644 src/SQLGenerator/getCommand.ts create mode 100644 src/SQLGenerator/index.ts create mode 100644 src/SQLGenerator/types.ts create mode 100644 src/cli/index.ts create mode 100644 src/constants.ts create mode 100644 src/e2e/e2e.test.ts create mode 100644 src/parseMongoArgs/parseMongoArgs.ts create mode 100644 src/parseMongoArgs/test/_getIndexesOfArgs.test.ts create mode 100644 src/parseMongoArgs/test/_swapQuotes.test.ts create mode 100644 src/parseMongoArgs/test/getWehereAndSelect.test.ts create mode 100644 src/parseMongoCollectionName/index.ts create mode 100644 src/parseMongoCollectionName/parseCollectionName.ts create mode 100644 src/parseMongoCollectionName/test/parseCollectionName.test.ts create mode 100644 src/utils/utils.ts create mode 100644 tsconfig.build.json create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..abe3963 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,18 @@ +name: Build + +on: + push: + branches: [ main ] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js 20.x (LTS) + uses: actions/setup-node@v2 + with: + node-version: 20.x + - name: Install and build + run: | + yarn + yarn build diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..c16d1c1 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,18 @@ +name: Test + +on: + push: + branches: [ main ] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js 20.x (LTS) + uses: actions/setup-node@v2 + with: + node-version: 20.x + - name: Install and test + run: | + yarn + yarn test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2883829 --- /dev/null +++ b/.gitignore @@ -0,0 +1,131 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* +bin \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7ea599b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Lautaro Jayat + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..06cb481 --- /dev/null +++ b/README.md @@ -0,0 +1,142 @@ +# Mongo To SQL! + +![Testing](https://github.com/lautarojayat/mongo-to-sql/actions/workflows/test.yaml/badge.svg) +![Build](https://github.com/lautarojayat/mongo-to-sql/actions/workflows/build.yaml/badge.svg) + + + +A simple mongo to sql translator powered by Nodejs + +![header](assets/header.png) + + + +* [How to start](#how-to-start) + * [1. Clone this repo](#1-clone-this-repo) + * [2. Install yarn](#2-install-yarn) + * [3. Install all dependencies](#3-install-all-dependencies) + * [4. Transpile the project](#4-transpile-the-project) + * [5. Install the package as a cmd utility](#5-install-the-package-as-a-cmd-utility) + * [6. Try to translate a query](#6-try-to-translate-a-query) +* [Usage](#usage) +* [Observations](#observations) + * [String Values](#string-values) + * [Command Line tips](#command-line-tips) + * [Bash escaping](#bash-escaping) +* [Uninstall](#uninstall) + +## How to start + +### 1. Clone this repo +Clone the project and then go to the root folder +```bash +git clone https://github.com/LautaroJayat/mongo-to-sql.git + +cd mongo-to-sql +``` + +### 2. Install yarn +if you have NPM installed: +```bash +npm install --global yarn +``` + +if not, you can follow these alternative steps: +https://classic.yarnpkg.com/lang/en/docs/install + +### 3. Install all dependencies +```bash +yarn +``` + +### 4. Transpile the project + +```bash +yarn build +``` + +### 5. Install package as a command line utility +```bash +yarn install:bin + +# under the hood it does +# chmod +x bin/cli/index.js && npm i -g . +``` + +### 6. Translate a query + +```bash +mongoToSql "db.myCollection.find({some: 'args'}, { fieldToProject: 1 })" +``` +## Usage + +### `mongoToSql [options] [ command | arguments ] ` + +Options: +* `--cool`: prints a pretty title before the output + ```bash + mongoToSql --cool "db.myCollection.find({})" + ``` + +Commands: +* `help` : prints a help dialog with all the options + ```bash + mongoToSql help + ``` + +Arguments: +* A mongo query that will be used as input + ```bash + mongoToSql "db.myCollection.find({my: 'field'})" + ``` + + + + +## Observations + +### String Values +When using string values, remember to use single quotes. If you try to quote using double quotes or backticks you will have an error +```js +// this is ok +db.users.find({name: 'smith'}) +// but this no +db.users.find({name: "smith"}) +``` + +### Command Line tips +You can use this CLI in three ways: + +1. You can introduce a a string containing a command as the first argument: + +```1.ash +mongoToSql "db.myCollection.find({some: 'args'}, { fieldToProject: 1 })" +``` + +2. You can interpolate the value of the first argument by using a subshell: + +```bash +mongoToSql $(cat query.js) +``` + +3. You can pipe a string directly to the command +```bash +cat query.js | mongoToSql +``` + +### Bash escaping +Mongodb uses `$` as a prefix for their operators, but the same character is an actual operator in bash. +To avoid unexpected errors, if you are providing a string directly into the shell, remember to escape any special character: +```bash +# this will work +mongoToSql "db.users.find({age: { \$gte: 25 }, name: 'smith' })" + +# this will interpret 'gre' as an env and will try to interpolate its value +mongoToSql "db.users.find({age: { $gte: 25 }, name: 'smith' })" +``` + +## Uninstall +Just run: +```bash +yarn remove:bin +``` \ No newline at end of file diff --git a/assets/header.png b/assets/header.png new file mode 100644 index 0000000000000000000000000000000000000000..0ede189ccd79f3fd9598b40a2d4e06930b8e48c9 GIT binary patch literal 21171 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%0Dl|})a}MZS?VJDF{h`DMkVcG zOYnpx3#~IXjH|9de)|x*D^y81Zp&Uo5o3*#0D40Jo}u?+Z^2XfG<{c&_&{0 zG*56p^^nO^2GFI-Mb7H^eF=h18@lv}BekLp?MF{$REtm!4RRq~21vy7{!bYKfi2pq$!#-|`>xlEjM=3aYbsj4R zDmb_8QHgFE>0Neh=AbsRYk?efk{#Q};5gfn)#65+uSSq<*%oUNUS7!2LKk{Lz@pcu zbg>9v-!vd*alF9lbJa`Rj;1BVEB zxaleWNiasOF~fG!Vum-Uj=50|NuhpRTRxFrH-+SXX5+5>$31@#o1F3|v+B>~a(3C3 z$@cz@sl6i^x5%EsEBY|OTqZ3%kQ@8%VJh&?SZD(2m$$O}+CXMFe8C_6_7W}?H^xLv zEh<7z90hNx%4!X2%rG@C!w%Afa`2m(Sgx4DaL4~LvvLJA87U-3`r;n)EQ^g4gX^Sm znEto`dxs4SGEOJ_PI&G!y>jhKL%^>~+1h#;!`EzLKz0=VyO!W`>;b8=M5NO!>|^a2 zH*+v!f3>5ksX%7zW9~bxa@@- zVys>%r1+~kExw-1x@-)jU0~DH-BejNlqG+RM@$RHZ-)aX{|wYo?WNSkE7e7DVdi8u zHax_PJqrlzx&(Kvj><%=NB+$IAK!g(nlk0wNv5d0S!X+pJq2T30gwpaw~O<0Z0W6w z$j{_{v}X_3r!8mV-1c1i&I?_0nQ4WbL72x4LWX?C@}r}vph+d-_5~b2TgyJT=PgP^ z?3l;5HI^`a>!VSjA`0V5bolyvhS#lxG1(+P4#aEqEY=--7MrS#jgnIdxD|q`nHNXS zq=F2Wcb+2VlP36imn1&59Arm}IjD{7T9MAJ#r8~#najj6-|^F23l!NY#0GkC>fy6R zq&B+H2Nhdkx8M`RQwum2RERB*l8FdSLT*(B3#&?o*P9qHVBl|w@Q!KYf5_6tfC2p@ z)*Zz*@Ba}0&HH@otQR-lfPqq=px%V->|Rx$>*GhT=ur3@9zS2Uh;M(x&Z`6Q{CF^q z-X%Z(5iD9@w|_U&>KtZl`&IZBlH~ZG%D-9mazm_6*Y$f@Gw3O+dyMDsqrzsXNTp7* z*z{+A0!H-XhjRsA{%yd30RwM7x@KxHVBlYbG0lgJplS949!F;&S~aBelnJy+y1@L) zZ)!G61OIL`gl(O}!X~>|y?GDcOLi { + const lastParen = input.lastIndexOf(")") + + const trimmedInput = input.substring(0, lastParen + 1) + + const command = getCommand(trimmedInput) + + switch (command) { + case 'find': + return translateFindCommand(trimmedInput) + default: + throw new Error(`only ${JSON.stringify(SUPPORTED_COMMANDS)} are supported. Got ${command}`) + } + +}; diff --git a/src/SQLGenerator/generateSQLSelectStmt.ts b/src/SQLGenerator/generateSQLSelectStmt.ts new file mode 100644 index 0000000..24f159b --- /dev/null +++ b/src/SQLGenerator/generateSQLSelectStmt.ts @@ -0,0 +1,26 @@ +export function checkValuesOrThrow(values: Array) { + if (values.length === 0) { + return + } + for (const v of values) { + if (v !== true && v !== 1) { + throw new Error("Projection only supports 'true' and '1' as values.") + } + } + const s = new Set(values) + if (s.size !== 1) { + throw new Error("All projected key/value needs to use the same value (1 | true)") + } +} + +import { COMMA, SELECT, SPACE, STAR } from "../constants"; +export const generateSQLSelectStmt = (select: Record | undefined): string => { + + if (!select) return `${SELECT}${SPACE}${STAR}`; + + checkValuesOrThrow(Object.values(select)) + + if (Object.keys(select).length === 0) return `${SELECT}${SPACE}${STAR}` + + return `${SELECT}${SPACE}` + Object.keys(select).sort().map(k => k.trim()).join(`${COMMA}${SPACE}`); +}; \ No newline at end of file diff --git a/src/SQLGenerator/generateSQLWhereStmt.ts b/src/SQLGenerator/generateSQLWhereStmt.ts new file mode 100644 index 0000000..a44d694 --- /dev/null +++ b/src/SQLGenerator/generateSQLWhereStmt.ts @@ -0,0 +1,114 @@ +import { AND, EQ, SPACE, WHERE } from "../constants"; +import { Operator, Value, RightPart, LeftPart, BinaryExpression, RawValue, SQlBuilder, ArrayExpression, } from "./types"; + + +type Expression = Value | RightPart | BinaryExpression | ArrayExpression + +class ExpressionFactory { + defaultOperator: string; + + constructor(defaultOperator: string) { + this.defaultOperator = defaultOperator; + } + + createExpression(rawValue: RawValue): Expression { + switch (rawValue.type) { + case 'primitive': + return this.createValue(rawValue); + + case 'object': + if (rawValue.leftNotOperator()) { + // raw value is {identity: expression|value} + // like {identity: {$operator: expression|value } } or {identity: value} + return this.createBinExpression(rawValue.getLeft(), rawValue.getRight()); + } + + // raw value is { $operator: expression|value} + const operator = new Operator(rawValue.getLeft().toPrimitive()) + return this.createRightPartOfExpression(operator, rawValue.getRight()); + + default: + throw new Error(`expected string | number | object as raw value, got: ${rawValue}`); + } + } + + private createValue(rawValue: RawValue): Value { + return new Value(rawValue); + } + + private createDefaultRightPart(rawValue: RawValue): RightPart { + return new RightPart(new Operator(this.defaultOperator), new Value(rawValue)); + } + + private createRightPartOfExpression(operator: Operator, rawRight: RawValue): RightPart | ArrayExpression { + if (!rawRight.isArray()) { + return new RightPart(operator, this.createExpression(rawRight)); + } + if (operator.isIn()) { + // because we need to prepend "IN" -> "IN (exp, exp, exp)" + // createArrayExpression wont prepend anything. + return new RightPart(operator, this.createArrayExpression(operator, rawRight)); + } + // at this point this is just $and | $or + // is just "(exp + operator + exp + operator)" + return this.createArrayExpression(operator, rawRight) + } + + private createBinExpression(rawLeft: RawValue, rawRight: RawValue): BinaryExpression { + if (`${rawLeft.toPrimitive()}` === "") { + throw new Error("bad identifier or operator. Please check your syntax") + } + + const identifier = new LeftPart(`${rawLeft.toPrimitive()}`) + + if (rawRight.isObject()) { + // this means we received {something: {$operator: expression | value} } + if (rawRight.leftIsAndOr()) { + throw new Error("$and | $or cant be used as value expressions, they must be used at top level") + } + return new BinaryExpression(identifier, this.createExpression(rawRight)); + } + // this means we received {something: value} + return new BinaryExpression(identifier, this.createDefaultRightPart(rawRight)); + } + + /** Knows how to parse each element as expression. */ + private createArrayExpression(operator: Operator, rawValue: RawValue) { + const expressions: SQlBuilder[] = [] + if (!rawValue.isArray()) { + throw new Error("expected array, but got something else") + } + for (const e of rawValue.toPrimitive()) { + const v = new RawValue(e) + expressions.push(this.createExpression(v)) + } + return new ArrayExpression(operator, expressions) + } +} + +export function generateSQLWhereStmt(where: Record | undefined): string { + if (!where) { + return ""; + } + + const expressionsFactory = new ExpressionFactory(EQ); + const expressions: SQlBuilder[] = []; + const sortedKeys = Object.keys(where).sort(); + + for (const k of sortedKeys) { + expressions.push(expressionsFactory.createExpression(new RawValue({ [k]: where[k] }))); + } + if (sortedKeys.length === 0) { + return ""; + } + let SQL = `${SPACE}${WHERE}`; + + for (let i = 0; i < expressions.length; i++) { + SQL = SQL.concat(` ${expressions[i].toSQL()}`); + if (i + 1 < expressions.length) { + SQL = SQL.concat(`${SPACE}${AND}`); + } + } + + return SQL; +} diff --git a/src/SQLGenerator/getCommand.ts b/src/SQLGenerator/getCommand.ts new file mode 100644 index 0000000..2b08690 --- /dev/null +++ b/src/SQLGenerator/getCommand.ts @@ -0,0 +1,8 @@ +import { DOT, OPEN_PARENTHESES } from "../constants"; + +export function getCommand(input: string) { + const firstCharAfterFirstDot = input.indexOf(DOT) + 1 + const firstCharAfterSecondDot = input.substring(firstCharAfterFirstDot).indexOf(DOT) + firstCharAfterFirstDot + 1 + const command = input.substring(firstCharAfterSecondDot, input.indexOf(OPEN_PARENTHESES)) + return command +} \ No newline at end of file diff --git a/src/SQLGenerator/index.ts b/src/SQLGenerator/index.ts new file mode 100644 index 0000000..1e094a9 --- /dev/null +++ b/src/SQLGenerator/index.ts @@ -0,0 +1,3 @@ +import { composeSQLQuery } from "./composeSQLQuery"; + +export { composeSQLQuery }; \ No newline at end of file diff --git a/src/SQLGenerator/types.ts b/src/SQLGenerator/types.ts new file mode 100644 index 0000000..c189c2b --- /dev/null +++ b/src/SQLGenerator/types.ts @@ -0,0 +1,224 @@ +import { $AND, $IN, $OR, CLOSING_PARENTHESES, COMMA, OPEN_PARENTHESES, SPACE } from "../constants"; +import { arrayOperator, isOperator, translateOperator } from "../utils/utils"; + +export interface SQlBuilder { + toSQL: () => string +} + +export class RawValue { + rawValue: any; + type: string; + jsType: string; + + constructor(rawValue: any) { + this.rawValue = rawValue; + const t = typeof rawValue; + + if (t === 'number' || t === 'string') { + this.type = 'primitive'; + this.jsType = t; + return; + } + + if (t === 'boolean') { + this.type = 'primitive'; + this.jsType = 'boolean'; + return + } + + if (this.rawValue === null) { + throw new Error("querying for a null value is not yet supported") + } + + if (Array.isArray(rawValue)) { + this.type = 'array' + this.jsType = 'array' + return + } + + this.type = 'object'; + this.jsType = 'object'; + } + + toPrimitive(): any { + return this.rawValue; + } + + getRight(): RawValue { + if (this.isObject()) { + const v = Object.values(this.rawValue)[0]; + return new RawValue(v); + } + return this; + } + + getLeft(): RawValue { + if (!this.isObject()) { + throw new Error("only raw objects can have left"); + } + return new RawValue(Object.keys(this.rawValue)[0]); + } + + leftNotOperator(): boolean { + if (this.isString()) { + return !isOperator(this.rawValue); + } + return !isOperator(Object.keys(this.rawValue)[0]); + } + + leftIsAndOr(): boolean { + if (this.isString()) { + return [$AND, $OR].includes(this.rawValue); + } + return [$AND, $OR].includes(Object.keys(this.rawValue)[0]) + } + + isOperator(): boolean { + if (this.isString()) { + return isOperator(this.rawValue); + } + return isOperator(Object.keys(this.rawValue)[0]) + } + + + isString(): boolean { + return this.jsType === 'string'; + } + + isNumber(): boolean { + return this.jsType === 'number'; + } + + isBoolean(): boolean { + return this.jsType === 'boolean'; + } + + isArray(): boolean { + return this.type === 'array'; + } + + isObject(): boolean { + return this.jsType === 'object'; + } +} + +export class Value implements SQlBuilder { + value: RawValue; + + constructor(value: RawValue) { + this.value = value; + } + + toSQL(): string { + if (this.value.isString()) { + return `'${this.value.toPrimitive()}'`; + } + if (this.value.isBoolean()) { + return `${this.value.toPrimitive()}`.toUpperCase(); + } + return `${this.value.toPrimitive()}`; + } +} + +/** Knows how to concatenate expressions based on the operation.*/ +export class ArrayExpression implements SQlBuilder { + content: SQlBuilder[]; + separator: string; + operator: Operator + constructor(operator: Operator, content: SQlBuilder[]) { + this.content = content; + + if (![$AND, $OR, $IN].includes(operator.raw)) { + new Error("Operation not supported for array expressions: " + operator.raw) + } + + if (operator.isIn()) { + this.separator = `${COMMA}${SPACE}` + } else { + this.separator = `${SPACE}${operator.toSQL()}${SPACE}` + } + this.operator = operator + } + + toSQL(): string { + let SQL = [] + for (let i = 0; i < this.content.length; i++) { + if (this.content[i] instanceof RightPart) { + throw new Error("only binary expressions or values are allowed inside an array expression") + } + SQL.push(this.content[i].toSQL()) + } + return `${OPEN_PARENTHESES}${SPACE}` + SQL.join(this.separator) + `${SPACE}${CLOSING_PARENTHESES}` + } +} + +export class Operator implements SQlBuilder { + raw: string; + + constructor(raw: string) { + this.raw = raw; + } + + isAnd() { + return this.raw === $AND; + } + + isOr() { + return this.raw === $OR; + } + isIn() { + return this.raw === $IN; + + } + + toSQL(): string { + if (isOperator(this.raw)) { + return translateOperator(this.raw); + } + return this.raw; + } +} + +export class LeftPart implements SQlBuilder { + key: string; + + constructor(key: string) { + this.key = key; + } + + toSQL(): string { + return this.key; + } + + getRaw(): string { + return this.key + } +} + +export class RightPart implements SQlBuilder { + operator: Operator; + right: SQlBuilder; + + constructor(operator: Operator, right: SQlBuilder) { + this.operator = operator; + this.right = right; + } + + toSQL(): string { + return `${SPACE}${this.operator.toSQL()}${SPACE}${this.right.toSQL()}`; + } +} + +export class BinaryExpression implements SQlBuilder { + left: LeftPart; + right: SQlBuilder; + + constructor(left: LeftPart, right: SQlBuilder) { + this.left = left; + this.right = right; + } + + toSQL(): string { + return `${this.left.toSQL()}${this.right.toSQL()}`; + } +} diff --git a/src/cli/index.ts b/src/cli/index.ts new file mode 100644 index 0000000..fc63734 --- /dev/null +++ b/src/cli/index.ts @@ -0,0 +1,48 @@ +#!/usr/bin/env node +import yargs from 'yargs/yargs'; +import figlet from 'figlet' +import fs from 'node:fs' +import { composeSQLQuery } from '../SQLGenerator'; + +const help = `Usage: $0 [mongo command] + + +Examples + - $0 db.users.find({}) + - $0 --cool db.users.fund({ name: 'john' }) + - $0 --cool db.users.find({},{name: 1, id: 1}) +` + +const argv = yargs(process.argv.slice(2)).options('cool', { type: 'boolean', description: 'make a cool output' }) + .usage(help) + .parseSync(); + +let input = argv._.join(""); + +if (argv.cool) { + console.log("") + console.log(figlet.textSync("Mongo To SQL!", "ANSI Shadow")) + console.log("") +} + +if (!input && !process.stdin.isTTY) { + input = fs.readFileSync(0, 'utf8').toString().replace(/\n/g, "").replace(/\s+/gi, "") + fs.close(0) +} + +try { + if (input) { + console.log("IN: ", input.substring(0, input.lastIndexOf(")") + 1)) + const parsedQuery = composeSQLQuery(`${input}`); + console.log("OUT: ", parsedQuery); + process.exit(0); + } else { + console.log(`Usage: ${argv.$0} [mongo command]`) + console.log(`\nrun ${argv.$0} --help for more information`) + process.exit(1); + } +} catch (error) { + console.error("There is an error in the provided command"); + console.error(error); + process.exit(1); +} diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..cb35e66 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,22 @@ +export const DOT = "."; +export const COMMA = ","; +export const SEMICOLON = ";" +export const SPACE = " "; +export const OPEN_PARENTHESES = "("; +export const CLOSING_PARENTHESES = ")"; +export const OPEN_BRACE = "{"; +export const CLOSING_BRACE = "}"; +export const $OR = "$or"; +export const $AND = "$and"; +export const $LT = "$lt"; +export const $LTE = "$lte"; +export const $GT = "$gt"; +export const $GTE = "$gte"; +export const $NE = "$ne"; +export const $IN = "$in"; +export const EQ = "=" +export const SELECT = "SELECT" +export const STAR = "*" +export const WHERE = "WHERE"; +export const FROM = "FROM"; +export const AND = "AND"; diff --git a/src/e2e/e2e.test.ts b/src/e2e/e2e.test.ts new file mode 100644 index 0000000..f413711 --- /dev/null +++ b/src/e2e/e2e.test.ts @@ -0,0 +1,191 @@ +import { composeSQLQuery } from "../SQLGenerator" + + +describe("composeSQLQuery", () => { + const tests: { input: string, error: boolean, expectedOutput: string }[] = [ + { + input: "db.users.find({})", + expectedOutput: "SELECT * FROM users;", + error: false + }, + { + input: "db.users.find({},{})", + expectedOutput: "SELECT * FROM users;", + error: false + }, + { + input: "db.users.find({},{age: 1})", + expectedOutput: "SELECT age FROM users;", + error: false + }, + { + input: "db.users.find({},{age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users;", + error: false + }, + { + input: "db.users.find({}, {name: 1, age: 1, lastName: 1})", + expectedOutput: "SELECT age, lastName, name FROM users;", + error: false + }, + { + input: "db.users.find({}, {age: 1})", + expectedOutput: "SELECT age FROM users;", + error: false + }, + { + input: "db.users.find({name: 'john'}, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: 25}, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age = 25 AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: {$ne: 25}}, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age != 25 AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: {$lte: 25}}, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age =< 25 AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $lt: 25 } }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age < 25 AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $gte: 25 } }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age >= 25 AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $gt: 25 } }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age > 25 AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $gt: 25 }, salary: {$lt: 150000} }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age > 25 AND name = 'john' AND salary < 150000;", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $gt: 25 }, married: true }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age > 25 AND married = TRUE AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $gt: 25 }, married: false }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age > 25 AND married = FALSE AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', age: { $in: [25] }, married: true }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age IN ( 25 ) AND married = TRUE AND name = 'john';", + error: false + }, + { + input: "db.users.find({name: 'john', surname: { $in: ['clark', 'smith'] }, married: true }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE married = TRUE AND name = 'john' AND surname IN ( 'clark', 'smith' );", + error: false + }, + + { + input: "db.users.find({name: 'john', age: { $in: [25] }, married: true }, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE age IN ( 25 ) AND married = TRUE AND name = 'john';", + error: false + }, + { + input: "db.users.find({ $or: [{name: 'john'}, {age: { $in: [25, 15] } }, {married: true} ]}, {age: 1, name: 1})", + expectedOutput: "SELECT age, name FROM users WHERE ( name = 'john' OR age IN ( 25, 15 ) OR married = TRUE );", + error: false + }, + { + input: "db.users.find({$or: [{ $and: [{ name: 'john' }, { age: { $in: [25, 15] } }] }, { married: true }]})", + expectedOutput: "SELECT * FROM users WHERE ( ( name = 'john' AND age IN ( 25, 15 ) ) OR married = TRUE );", + error: false + }, + { + input: "db.users.find({$or: [{ $and: [{ name: 'john' }, { age: { $in: [25, 15] } }] }, { married: true }]})", + expectedOutput: "SELECT * FROM users WHERE ( ( name = 'john' AND age IN ( 25, 15 ) ) OR married = TRUE );", + error: false + }, + { + input: "db.users.find({}, { married: true, id:1 })", + expectedOutput: "", + error: true + }, + { + input: "db.users.find({}, { married: 0, id: 0 })", + expectedOutput: "", + error: true + }, + { + input: "db.users.find({}, { married: 'true', id: 'true' })", + expectedOutput: "", + error: true + }, + { + input: "db.users.find()", + expectedOutput: "", + error: true + }, + { + input: "db.users.find(x{}, {})", + expectedOutput: "", + error: true + }, + { + input: "users.find({}]})", + expectedOutput: "", + error: true + }, + { + input: "db.users.find(,{})", + expectedOutput: "", + error: true + }, + { + input: "db.users.find({id: {$or: [{$gte: 15}]}},{})", + expectedOutput: "", + error: true + }, + { + input: "db.users.findOne({})", + expectedOutput: "", + error: true + }, + { + input: "db.users.findTwo({})", + expectedOutput: "", + error: true + }, + { + input: "db.users.insert({name: 'smith'})", + expectedOutput: "", + error: true + }, + ] + test.each(tests)("in: $input\n out: $expectedOutput\n err: $error", ( + { input, expectedOutput, error }) => { + let result; + let err; + try { + result = composeSQLQuery(input) + } catch (error) { + //console.error(error) + err = error + } + if (error) { + expect(err).toBeDefined() + } else { + expect(result).toBe(expectedOutput) + expect(err).toBeUndefined() + } + }) +}) + diff --git a/src/parseMongoArgs/parseMongoArgs.ts b/src/parseMongoArgs/parseMongoArgs.ts new file mode 100644 index 0000000..bcdeb9d --- /dev/null +++ b/src/parseMongoArgs/parseMongoArgs.ts @@ -0,0 +1,141 @@ +import { OPEN_BRACE, SPACE, COMMA, CLOSING_BRACE, CLOSING_PARENTHESES, OPEN_PARENTHESES } from "../constants"; +import { matchObjectKeys } from "../utils/utils"; + +export const errorInvalidArgsCall = "arguments can only be valid objects objects"; +export const errorBadArguments = "found unbalanced braces within the objects provided as arguments"; +export const errorInvalidSyntax = "the syntax for the function call is invalid"; + +export interface Indexes { + firstArgFirstBrace?: number; + commaSeparatingArgs?: number; + error?: string; +} + +/** + * This function is supposed to get the indexes needed to then split the string into segments. + * Those segments should represent the arguments of the function call. + * It expects an input starting from the first parentheses + */ +export function _getIndexesOfArgs(input: string): Indexes { + let firstArgFirstBrace: number | undefined; + let commaSeparatingArgs: number | undefined; + let counter = 0; + + for (let i = 1; i < input.length; i++) { + const currentChar = input.charAt(i); + + if (!firstArgFirstBrace) { + if (currentChar === OPEN_BRACE) { + firstArgFirstBrace = i; + counter++; + continue; + } else if (currentChar === SPACE) { + continue; + } else { + return { error: errorInvalidArgsCall }; + } + } + + if (currentChar === OPEN_BRACE) { + counter++; + continue; + } + + if (currentChar === CLOSING_BRACE) { + counter--; + } + + if (counter === 0) { + if (!commaSeparatingArgs && currentChar === COMMA) { + commaSeparatingArgs = i; + break; + } + + if (currentChar === CLOSING_PARENTHESES) { + break; + } + } + } + + if (counter !== 0) { + return { error: errorBadArguments }; + } + + return { + firstArgFirstBrace, + commaSeparatingArgs, + }; +} + +/** + * As the main idea behind all of this package is to try to sanitize the input + * and turn it into valid JS objects, this will attempt to add single quotes to each key. + */ +export function _tryMakeJsonString(input: string): string { + return input.trim().replace(/\"|\'/gi, (char) => { + if (char === "'") return '"'; + if (char === '"') return "'"; + return char; + }).replace(matchObjectKeys, '\"$1\":'); +} + +/** + * This function will get the whole query and extract the segments + * where our candidates as JSON strings + */ +function _getArgsAsPossibleJsonString(input: string): { whereStmt?: string; selectStmt?: string; error?: string } { + const firstParenthesis = input.indexOf(OPEN_PARENTHESES); + const lastParenthesis = input.lastIndexOf(CLOSING_PARENTHESES); + + if (firstParenthesis < 0) { + return { error: errorInvalidSyntax }; + } + + if (lastParenthesis < 0 || lastParenthesis < firstParenthesis) { + return { error: errorInvalidSyntax }; + } + + const { firstArgFirstBrace, commaSeparatingArgs, error } = _getIndexesOfArgs(input.substring(firstParenthesis)); + + if (error) { + return { error }; + } + + if (!firstArgFirstBrace) { + return {}; + } + + const firstSegment = input.substring(firstParenthesis, lastParenthesis).substring(firstArgFirstBrace, commaSeparatingArgs); + const whereStmt = _tryMakeJsonString(firstSegment); + + if (!commaSeparatingArgs) { + return { whereStmt }; + } + + const secondFragment = input.substring(firstParenthesis, lastParenthesis).substring(commaSeparatingArgs + 1); + const selectStmt = _tryMakeJsonString(secondFragment); + + return { whereStmt, selectStmt }; +} + +/** + * Note: this function is supposed to throw if some error occurred while parsing the query + */ +export function getWhereAndSelect(input: string): { where?: Record; select?: Record } { + const result: { where?: Record; select?: Record } = {}; + const { whereStmt, selectStmt, error } = _getArgsAsPossibleJsonString(input); + + if (error) { + throw new Error(error); + } + + if (whereStmt) { + result.where = JSON.parse(whereStmt); + } + + if (selectStmt) { + result.select = JSON.parse(selectStmt); + } + + return result; +} diff --git a/src/parseMongoArgs/test/_getIndexesOfArgs.test.ts b/src/parseMongoArgs/test/_getIndexesOfArgs.test.ts new file mode 100644 index 0000000..9f3ec0a --- /dev/null +++ b/src/parseMongoArgs/test/_getIndexesOfArgs.test.ts @@ -0,0 +1,113 @@ +import { _getIndexesOfArgs, Indexes } from '../parseMongoArgs'; + +describe('_getIndexesOfArgs OK Calls', () => { + + it.each([{ + name: "works with simple arguments for where and select", + input: "({arg1: 'value1', arg2: 'value2'}, {field:1, field2:1})", + assertFn: (result: Indexes) => { + expect(result).toEqual({ + firstArgFirstBrace: 1, + commaSeparatingArgs: 33, + }); + expect(result.error).toBeUndefined() + } + + + }, + { + name: "works with simple arguments for where and no select", + input: "({arg1: 'value1', arg2: 'value2'})", + assertFn: (result: Indexes) => { + expect(result).toEqual({ + firstArgFirstBrace: 1, + }); + expect(result.error).toBeUndefined() + expect(result.commaSeparatingArgs).toBeUndefined() + } + }, + { + name: "works with simple arguments for where and empty select", + input: "({arg1: 'value1', arg2: 'value2'}, {})", + assertFn: (result: Indexes) => { + expect(result).toEqual({ + firstArgFirstBrace: 1, + commaSeparatingArgs: 33, + }); + expect(result.error).toBeUndefined() + } + + + }, + { + name: "works with simple arguments for empty where and non empty select", + input: "({}, {field:1, field2:1})", + assertFn: (result: Indexes) => { + expect(result).toEqual({ + firstArgFirstBrace: 1, + commaSeparatingArgs: 3, + }); + expect(result.error).toBeUndefined() + } + + + }, + { + name: "works with simple arguments for both empty where and select", + input: "({}, {})", + assertFn: (result: Indexes) => { + expect(result).toEqual({ + firstArgFirstBrace: 1, + commaSeparatingArgs: 3, + }); + expect(result.error).toBeUndefined() + } + } + , + { + name: "works with simple arguments for both empty where no select", + input: "({})", + assertFn: (result: Indexes) => { + expect(result).toEqual({ + firstArgFirstBrace: 1, + }); + expect(result.error).toBeUndefined() + expect(result.commaSeparatingArgs).toBeUndefined() + } + }] + )('$name', ({ input, assertFn }: { input: string, assertFn: (result: Indexes) => void }) => { + const result = _getIndexesOfArgs(input); + assertFn(result) + + }); + + + + +}); +describe('_getIndexesOfArgs BAD Calls', () => { + it.each([ + { + query: "(arg1: value1, arg2: value2)" + }, + { + query: "(arg1: ''value1, arg2: 'value2')" + }, + { + query: "(x{arg1: 'value1', arg2: 'value2')" + }, + { + query: "({{arg1: value1, arg2: value2})" + }, + { + query: "(}arg1: value1, arg2: value2})" + }, + { + query: "(!{arg1: value1, arg2: value2})" + }, + ])("must provide error for bad queries", ({ query }: { query: string }) => { + const result = _getIndexesOfArgs(query); + expect(result.error).toBeDefined(); + }); + +}) \ No newline at end of file diff --git a/src/parseMongoArgs/test/_swapQuotes.test.ts b/src/parseMongoArgs/test/_swapQuotes.test.ts new file mode 100644 index 0000000..43a532c --- /dev/null +++ b/src/parseMongoArgs/test/_swapQuotes.test.ts @@ -0,0 +1,20 @@ +import { _tryMakeJsonString, } from '../parseMongoArgs'; + + +describe('_tryMakeJsonString', () => { + it.each([ + { + input: "({arg1: 'value1', arg2: 'value2'})", + expected: `({\"arg1\": \"value1\", \"arg2\": \"value2\"})` + }, + { + input: `({arg1: 'va "lu" e1', arg2: 'va "lu" e2'})`, + expected: `({\"arg1\": \"va 'lu' e1\", \"arg2\": \"va 'lu' e2\"})` + }, + ])("must swap the quotes and double quotes", ({ input, expected }) => { + const result = _tryMakeJsonString(input); + expect(result).toBe(expected) + + }); + +}) \ No newline at end of file diff --git a/src/parseMongoArgs/test/getWehereAndSelect.test.ts b/src/parseMongoArgs/test/getWehereAndSelect.test.ts new file mode 100644 index 0000000..2266314 --- /dev/null +++ b/src/parseMongoArgs/test/getWehereAndSelect.test.ts @@ -0,0 +1,127 @@ +import * as parseMongoArgs from '../parseMongoArgs'; + +describe('getWhereAndSelect', () => { + it.each([ + { + input: "({arg1: 'value1', arg2: 'value2'}, {field:1, field2:1})", + expectedWhere: { arg1: "value1", arg2: "value2" }, + expectedSelect: { field: 1, field2: 1 }, + expectedError: false + }, + { + input: "({}, {field:1, field2:1})", + expectedWhere: {}, + expectedSelect: { field: 1, field2: 1 }, + expectedError: false + }, + { + input: "({arg1: 'value1', arg2: 'value2'}, {})", + expectedWhere: { arg1: "value1", arg2: "value2" }, + expectedSelect: {}, + expectedError: false + }, + { + input: "({arg1: 'value1', arg2: 'value2'})", + expectedWhere: { arg1: "value1", arg2: "value2" }, + expectedSelect: undefined, + expectedError: false + }, + { + input: "({}, {})", + expectedWhere: {}, + expectedSelect: {}, + expectedError: false + }, + { + input: "({})", + expectedWhere: {}, + expectedSelect: undefined, + expectedError: false + }, + { + input: "({arg1: 'value1', arg2: { $gte: 'value2'}}, {arg1: 1})", + expectedWhere: { arg1: "value1", arg2: { $gte: 'value2' } }, + expectedSelect: { arg1: 1 }, + expectedError: false + }, + { + input: "(x{arg1: 'value1', arg2: { $gte: 'value2'}}, {arg1: 1})", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + }, + { + input: "(arg1: 'value1', arg2: { $gte: 'value2'}}, {arg1: 1})", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + }, + { + input: "({)arg1: 'value1', arg2: { $gte: 'value2'}}, {arg1: 1})", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + }, + { + input: "({}arg1: 'value1', arg2: { $gte: 'value2'}}, {arg1: 1})", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + }, + { + input: "(,, {arg1: 1})", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + }, + { + input: "(,, }{arg1: 1})", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + }, + { + input: "()", + expectedWhere: undefined, + expectedSelect: undefined, + expectedError: true + } + + + ] + )('$input', ({ + input, + expectedWhere, + expectedSelect, + expectedError }) => { + let where; + let select; + let error; + try { + const result = parseMongoArgs.getWhereAndSelect(input) + where = result.where + select = result.select + } catch (e) { + error = e + } + + if (!expectedWhere) { + expect(where).toBeUndefined() + } else { + expect(where).toMatchObject(expectedWhere) + } + + if (!expectedSelect) { + expect(select).toBeUndefined() + } else { + expect(select).toMatchObject(expectedSelect) + } + + if (expectedError) { + expect(error).toBeDefined() + } else { + expect(error).toBeUndefined() + } + }) + +}) diff --git a/src/parseMongoCollectionName/index.ts b/src/parseMongoCollectionName/index.ts new file mode 100644 index 0000000..8d9911a --- /dev/null +++ b/src/parseMongoCollectionName/index.ts @@ -0,0 +1 @@ +export { parseCollectionName } from "./parseCollectionName"; diff --git a/src/parseMongoCollectionName/parseCollectionName.ts b/src/parseMongoCollectionName/parseCollectionName.ts new file mode 100644 index 0000000..5b63742 --- /dev/null +++ b/src/parseMongoCollectionName/parseCollectionName.ts @@ -0,0 +1,48 @@ +import { DOT } from "../constants"; +import { checkForNumber, checkForNonAlphaNumeric } from "../utils/utils"; + +export const errorBadMethodChaining = "couldn't find collection between dots"; +export const errorNoDbFound = "first dot is at position 0 so no db was specified"; +export const errorCollectionBadCharForCollection = "only alphanumeric and low dashes are allowed for collection"; +export const errorCollectionMustStartWithALetter = "collection names should start with a letter"; + +interface ParseResult { + collection?: string; + error?: string; +} + +/** + * + * @param input: a full string like 'db.users.find({})' + * @returns + */ +export function parseCollectionName(input: string): ParseResult { + const firstDot = input.indexOf(DOT); + + if (firstDot === -1) { + return { error: errorBadMethodChaining }; + } + + if (firstDot === 0) { + return { error: errorNoDbFound }; + } + + const nextCharFromFirstDot = firstDot + 1; + const secondDot = input.substring(nextCharFromFirstDot).indexOf(DOT); + + if (secondDot === -1) { + return { error: errorBadMethodChaining }; + } + + const collection = input.substring(nextCharFromFirstDot, nextCharFromFirstDot + secondDot); + + if (checkForNumber.test(collection.charAt(0))) { + return { error: errorCollectionMustStartWithALetter }; + } + + if (checkForNonAlphaNumeric.test(collection)) { + return { error: errorCollectionBadCharForCollection }; + } + + return { collection }; +} diff --git a/src/parseMongoCollectionName/test/parseCollectionName.test.ts b/src/parseMongoCollectionName/test/parseCollectionName.test.ts new file mode 100644 index 0000000..6f68331 --- /dev/null +++ b/src/parseMongoCollectionName/test/parseCollectionName.test.ts @@ -0,0 +1,51 @@ +import { + parseCollectionName, + errorBadMethodChaining, + errorNoDbFound, + errorCollectionBadCharForCollection, + errorCollectionMustStartWithALetter +} from '../parseCollectionName'; + +describe('parseCollectionName', () => { + it('should correctly parse collection name', () => { + const input = 'db.users.find({})'; + const result = parseCollectionName(input); + + expect(result).toEqual({ collection: 'users' }); + }); + + it('should handle missing first dot', () => { + const input = 'dbusers.find({})'; + const result = parseCollectionName(input); + + expect(result).toEqual({ error: errorBadMethodChaining }); + }); + + it('should handle first dot at position 0', () => { + const input = '.users.find({})'; + const result = parseCollectionName(input); + + expect(result).toEqual({ error: errorNoDbFound }); + }); + + it('should handle missing second dot', () => { + const input = 'db.usersfind({})'; + const result = parseCollectionName(input); + + expect(result).toEqual({ error: errorBadMethodChaining }); + }); + + it('should handle collection starting with a number', () => { + const input = 'db.123users.find({})'; + const result = parseCollectionName(input); + + expect(result).toEqual({ error: errorCollectionMustStartWithALetter }); + }); + + it('should handle collection with invalid characters', () => { + const input = 'db.us&ers.find({})'; + const result = parseCollectionName(input); + + expect(result).toEqual({ error: errorCollectionBadCharForCollection }); + }); +}); \ No newline at end of file diff --git a/src/utils/utils.ts b/src/utils/utils.ts new file mode 100644 index 0000000..230d291 --- /dev/null +++ b/src/utils/utils.ts @@ -0,0 +1,39 @@ +import { $OR, $AND, $LT, $LTE, $GT, $GTE, $NE, $IN } from "../constants"; + +export const checkForNonAlphaNumeric = /[^a-z0-9_]/i; +export const checkForNumber = /\d/; +export const matchObjectKeys = /([$a-z0-9-_]+):/gi; + +const operatorList = [$OR, $AND, $LT, $LTE, $GT, $GTE, $NE, $IN]; + +export function isOperator(key: string): boolean { + return operatorList.includes(key); +} + +export function arrayOperator(op: string): boolean { + return [$AND, $OR, $IN].includes(op) + +} + +export function translateOperator(op: string): string { + switch (op) { + case $OR: + return "OR"; + case $AND: + return "AND"; + case $LT: + return "<"; + case $LTE: + return "=<"; + case $GT: + return ">"; + case $GTE: + return ">="; + case $NE: + return "!="; + case $IN: + return "IN"; + default: + throw new Error(`unrecognized operator: ${op}`); + } +} diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..066a465 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "exclude": [ + "src/**/*.test.ts" + ] + } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2e3a2f7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,111 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": ["es2019"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + "rootDir": "src", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./bin", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..e6ca474 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2299 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.6.tgz#8be77cd77c55baadcc1eae1c33df90ab6d2151d4" + integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.6" + "@babel/parser" "^7.23.6" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.6" + "@babel/types" "^7.23.6" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.6", "@babel/generator@^7.7.2": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.6.tgz#d03af2ee5fb34691eec0cda90f5ecbb4d4da145a" + integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.6" + "@babel/types" "^7.23.6" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" + integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/template@^7.22.15", "@babel/template@^7.3.3": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.6.tgz#b53526a2367a0dd6edc423637f3d2d0f2521abc5" + integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.6" + "@babel/types" "^7.23.6" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.3.3": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" + integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== + dependencies: + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + dependencies: + expect "^29.7.0" + jest-snapshot "^29.7.0" + +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== + dependencies: + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.20.4" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.4.tgz#ec2c06fed6549df8bc0eb4615b683749a4a92e1b" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== + dependencies: + "@babel/types" "^7.20.7" + +"@types/figlet@^1.5.8": + version "1.5.8" + resolved "https://registry.yarnpkg.com/@types/figlet/-/figlet-1.5.8.tgz#96b8186c7e2a388b4f8d09ee3276cba2af88bb0b" + integrity sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ== + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.11": + version "29.5.11" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.11.tgz#0c13aa0da7d0929f078ab080ae5d4ced80fa2f2c" + integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/node@*", "@types/node@^20.10.5": + version "20.10.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.5.tgz#47ad460b514096b7ed63a1dae26fad0914ed3ab2" + integrity sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw== + dependencies: + undici-types "~5.26.4" + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" + +acorn-walk@^8.1.1: + version "8.3.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.1.tgz#2f10f5b69329d90ae18c58bf1fa8fccd8b959a43" + integrity sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw== + +acorn@^8.4.1: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + +add@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235" + integrity sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q== + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.22.2: + version "4.22.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001565: + version "1.0.30001571" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz#4182e93d696ff42930f4af7eba515ddeb57917ac" + integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cjs-module-lexer@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dedent@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" + integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +electron-to-chromium@^1.4.601: + version "1.4.616" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz#4bddbc2c76e1e9dbf449ecd5da3d8119826ea4fb" + integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + 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" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +figlet@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.7.0.tgz#46903a04603fd19c3e380358418bb2703587a72e" + integrity sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-instrument@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz#71e87707e8041428732518c6fb5211761753fbdf" + integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-util "^29.7.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.7.0" + graceful-fs "^4.2.9" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + natural-compare "^1.4.0" + pretty-format "^29.7.0" + semver "^7.5.3" + +jest-util@^29.0.0, jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + 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" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +pure-rand@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" + integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +resolve@^1.20.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-jest@^29.1.1: + version "29.1.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typescript@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.1: + version "9.2.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + 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" + +yarn@^1.22.21: + version "1.22.21" + resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.21.tgz#1959a18351b811cdeedbd484a8f86c3cc3bbaf72" + integrity sha512-ynXaJsADJ9JiZ84zU25XkPGOvVMmZ5b7tmTSpKURYwgELdjucAOydqIOrOfTxVYcNXe91xvLZwcRh68SR3liCg== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==