From c8ecccaa51a1bb29e5f8f07dd4dfdcf74330be62 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:06:10 +0900 Subject: [PATCH 01/79] github actions workflow wip --- .circleci/config.yml | 143 ----------------------------- .github/workiflows/python.yaml | 60 ++++++++++++ .github/workiflows/typescript.yaml | 63 +++++++++++++ README.rst | 4 - python/ci_requirements.txt | 4 +- python/pytest.ini | 3 + python/tox.ini | 44 --------- 7 files changed, 129 insertions(+), 192 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workiflows/python.yaml create mode 100644 .github/workiflows/typescript.yaml create mode 100644 python/pytest.ini delete mode 100644 python/tox.ini diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index e420640..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,143 +0,0 @@ -version: 2 -jobs: - -# python_test: -# docker: -# - image: cimg/python:3.11.2 -# steps: -# - checkout -# - restore_cache: -# keys: -# - venv-{{ checksum "python/ci_requirements.txt"}} -# - tox-{{ checksum "python/tox.ini" }} -# -# - run: -# name: install dependencies -# command: | -# cd python/ -# python3 -m venv venv || true -# python3 -m pip install -U pip -# python3 -m pip install -r ci_requirements.txt -# -# - save_cache: -# paths: -# - python/venv -# key: venv-{{ checksum "python/ci_requirements.txt"}} -# -# - save_cache: -# paths: -# - python/.tox -# key: tox-{{ checksum "python/tox.ini" }} -# -# - run: -# name: run python tests -# command: | -# cd python/ -# venv/bin/tox -e py3112 -e black-check -e cov -e codecov -# -# python_deploy: -# docker: -# - image: cimg/python:3.11.2 -# steps: -# - checkout -# - restore_cache: -# keys: -# - venv-{{ checksum "python/ci_requirements.txt"}} -# -# - run: -# name: install dependencies -# command: | -# cd python/ -# python3 -m venv venv || true -# python3 -m pip install -U pip -# python3 -m pip install -r ci_requirements.txt -# -# - save_cache: -# paths: -# - python/venv -# key: venv-{{ checksum "python/ci_requirements.txt"}} -# -# - run: -# name: build and push -# command: | -# cd python/ -# source venv/bin/activate -# python ./setup.py sdist bdist_wheel -# venv/bin/twine upload dist/* --non-interactive --skip-existing - - node_test: - docker: - - image: circleci/node:stretch - steps: - - checkout - - restore_cache: - keys: - - node_modules-{{ checksum "typescript/package.json" }} - - - run: - name: install dependencies - command: | - cd typescript/ - npm install - - - save_cache: - paths: - - typescript/node_modules - key: node_modules-{{ checksum "typescript/package.json" }} - - - run: - name: run node tests - command: | - cd typescript/ - npm test -- --coverage - npm run codecov - - node_deploy: - docker: - - image: circleci/node:stretch - steps: - - checkout - - restore_cache: - keys: - - node_modules-{{ checksum "typescript/package.json" }} - - - run: - name: install dependencies - command: | - cd typescript/ - npm install - - - save_cache: - paths: - - typescript/node_modules - key: node_modules-{{ checksum "typescript/package.json" }} - - - run: - name: Authenticate with registry - command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > typescript/.npmrc - - - run: - name: build and push - command: | - cd typescript/ - npm run build - npm publish || true - -workflows: - version: 2 - test_deploy: - jobs: - - python_test - - node_test - - python_deploy: - filters: - branches: - only: master - requires: - - python_test - - node_deploy: - filters: - branches: - only: master - requires: - - node_test \ No newline at end of file diff --git a/.github/workiflows/python.yaml b/.github/workiflows/python.yaml new file mode 100644 index 0000000..68e2fbc --- /dev/null +++ b/.github/workiflows/python.yaml @@ -0,0 +1,60 @@ +name: python +on: + push: + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.7", "3.11"] + defaults: + run: + working-directory: python + + steps: + - uses: actions/checkout@v3 + - name: setup + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: install + run: | + python -m pip install --upgrade pip + python -m pip install -r ci_requirements.txt + - name: test + run: | + pytest --cov=covertable + - name: codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + + release: + needs: tests + runs-on: ubuntu-latest + defaults: + run: + working-directory: python + if: github.ref == 'refs/heads/master' + name: npm upload + steps: + - uses: actions/checkout@v3 + - name: setup + uses: actions/setup-python@v4 + with: + python-version: 3.11 + - name: install + run: | + python -m pip install --upgrade pip + python -m pip install -r ci_requirements.txt + - name: build + run: | + python ./setup.py sdist bdist_wheel + twine upload dist/* --non-interactive --skip-existing + - name: upload + run: twine upload dist/* --non-interactive --skip-existing + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workiflows/typescript.yaml b/.github/workiflows/typescript.yaml new file mode 100644 index 0000000..480de1a --- /dev/null +++ b/.github/workiflows/typescript.yaml @@ -0,0 +1,63 @@ +name: typescript +on: + push: + +jobs: + tests: + runs-on: ubuntu-latest + defaults: + run: + working-directory: typescript + + steps: + - uses: actions/checkout@v3 + - name: setup + uses: actions/setup-node@v3 + with: + node-version: "16" + - name: cache + uses: actions/cache@v3 + with: + path: | + node_modules + key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} + - name: install + run: | + npm install + - name: test + run: | + npm test -- --coverage + npm run codecov + - name: codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + + release: + needs: tests + runs-on: ubuntu-latest + defaults: + run: + working-directory: typescript + + if: github.ref == 'refs/heads/master' + name: npm upload + steps: + - uses: actions/checkout@v3 + - name: setup + uses: actions/setup-node@v3 + with: + node-version: "16" + - name: cache + uses: actions/cache@v3 + with: + path: | + node_modules + key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} + - name: upload + run: | + npm install + npm run build + echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc + npm run publish || true diff --git a/README.rst b/README.rst index 4b554e8..fd3d597 100644 --- a/README.rst +++ b/README.rst @@ -200,7 +200,3 @@ History :1.0.x: - First release 🎉 - -.. note:: - - It moved from `twopairs`. diff --git a/python/ci_requirements.txt b/python/ci_requirements.txt index 8091e2b..03914f4 100644 --- a/python/ci_requirements.txt +++ b/python/ci_requirements.txt @@ -1,4 +1,6 @@ -tox +pytest +pytest-cov setuptools wheel twine +black diff --git a/python/pytest.ini b/python/pytest.ini new file mode 100644 index 0000000..b42ddf9 --- /dev/null +++ b/python/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +python_files = tests.py + diff --git a/python/tox.ini b/python/tox.ini deleted file mode 100644 index 460300e..0000000 --- a/python/tox.ini +++ /dev/null @@ -1,44 +0,0 @@ -[tox] -envlist = py37, blacken -skipsdist = True - -[pytest] -addopts = --durations=10 -python_paths = . -python_files = tests.py - -[testenv] -deps = - pytest - pytest-pythonpath -commands = py.test {posargs} - -[testenv:cov] -deps = - pytest - pytest-pythonpath - pytest-cov - coverage -commands = py.test {posargs} \ - --junitxml={toxinidir}/.junit.xml \ - --cov="covertable" --cov="sorters/" --cov="criteria" --cov="exceptions" - -[testenv:blacken] -basepython = python3.7 -deps = black -commands = - black . - -[testenv:black-check] -basepython = python3.7 -deps = black -commands = - black . --check - -[testenv:codecov] -passenv = - TOXENV - CI - CODECOV_* -deps = codecov -commands = codecov From 73f300013c5579b738e8060754fa96dba3355afd Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:07:38 +0900 Subject: [PATCH 02/79] typo --- .github/{workiflows => workflows}/python.yaml | 0 .github/{workiflows => workflows}/typescript.yaml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .github/{workiflows => workflows}/python.yaml (100%) rename .github/{workiflows => workflows}/typescript.yaml (100%) diff --git a/.github/workiflows/python.yaml b/.github/workflows/python.yaml similarity index 100% rename from .github/workiflows/python.yaml rename to .github/workflows/python.yaml diff --git a/.github/workiflows/typescript.yaml b/.github/workflows/typescript.yaml similarity index 100% rename from .github/workiflows/typescript.yaml rename to .github/workflows/typescript.yaml From 63e17b5fd3e96cab4de546a38fa1e34069e19a10 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:27:38 +0900 Subject: [PATCH 03/79] update readme --- .github/workflows/python.yaml | 2 +- README.rst | 9 +++++---- python/README.rst | 4 ++-- typescript/README.md | 1 + 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 68e2fbc..4a02d0e 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -38,7 +38,7 @@ jobs: run: working-directory: python if: github.ref == 'refs/heads/master' - name: npm upload + name: pypi upload steps: - uses: actions/checkout@v3 - name: setup diff --git a/README.rst b/README.rst index fd3d597..fa58202 100644 --- a/README.rst +++ b/README.rst @@ -1,10 +1,6 @@ .. image:: ./covertable.png :alt: covertable logo - -.. image:: https://circleci.com/gh/walkframe/covertable.svg?style=shield - :target: https://circleci.com/gh/walkframe/covertable - Time is limited. It is not realistic to create a test case that satisfies all the multiple factors, @@ -19,13 +15,18 @@ Now it has 2 implementations. - .. image:: https://badge.fury.io/py/covertable.svg :target: https://badge.fury.io/py/covertable + - .. image:: https://github.com/walkframe/covertable/actions/workflows/python.yaml/badge.svg + :target: https://github.com/walkframe/covertable/actions/workflows/python.yaml - `README `__ - `Code `__ + :TypeScript: - .. image:: https://badge.fury.io/js/covertable.svg :target: https://badge.fury.io/js/covertable + - .. image:: https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg + :target: https://github.com/walkframe/covertable/actions/workflows/typescript.yaml - `README `__ - `Code `__ diff --git a/python/README.rst b/python/README.rst index c06c2d3..30154ec 100644 --- a/python/README.rst +++ b/python/README.rst @@ -1,8 +1,8 @@ .. image:: https://badge.fury.io/py/covertable.svg :target: https://badge.fury.io/py/covertable -.. image:: https://circleci.com/gh/walkframe/covertable.svg?style=shield - :target: https://circleci.com/gh/walkframe/covertable +.. image:: https://github.com/walkframe/covertable/actions/workflows/python.yaml/badge.svg + :target: https://github.com/walkframe/covertable/actions/workflows/python.yaml .. image:: https://codecov.io/gh/walkframe/covertable/branch/master/graph/badge.svg :target: https://codecov.io/gh/walkframe/covertable diff --git a/typescript/README.md b/typescript/README.md index 7259b70..dcdaace 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -1,4 +1,5 @@ [![npm version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) +[![Workflow](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) [![CircleCI](https://circleci.com/gh/walkframe/covertable.svg?style=shield)](https://circleci.com/gh/walkframe/covertable) [![codecov](https://codecov.io/gh/walkframe/covertable/branch/master/graph/badge.svg)](https://codecov.io/gh/walkframe/covertable) From 8a39e5d7d27133a9db05bab981d3c04bfbccf8f8 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:33:00 +0900 Subject: [PATCH 04/79] username --- .github/workflows/python.yaml | 2 +- python/README.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 4a02d0e..08a3b24 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -56,5 +56,5 @@ jobs: - name: upload run: twine upload dist/* --non-interactive --skip-existing env: - TWINE_USERNAME: __token__ + TWINE_USERNAME: righ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} diff --git a/python/README.rst b/python/README.rst index 30154ec..d983654 100644 --- a/python/README.rst +++ b/python/README.rst @@ -17,7 +17,7 @@ Requirements ============ - Python: 3.3 or later. - - Tested with 3.7 + - Tested with 3.7, 3.11 Installation From a9b000afb0fa487270202aa695b0a384ae435699 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:39:41 +0900 Subject: [PATCH 05/79] delete badge --- typescript/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/typescript/README.md b/typescript/README.md index dcdaace..f655ee6 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -1,6 +1,5 @@ [![npm version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) [![Workflow](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) -[![CircleCI](https://circleci.com/gh/walkframe/covertable.svg?style=shield)](https://circleci.com/gh/walkframe/covertable) [![codecov](https://codecov.io/gh/walkframe/covertable/branch/master/graph/badge.svg)](https://codecov.io/gh/walkframe/covertable) # Installation From a86be1bcab0db8e865033f081c9e1deb449a845e Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:42:18 +0900 Subject: [PATCH 06/79] publish --- .github/workflows/typescript.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index 480de1a..4b43e7e 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -60,4 +60,4 @@ jobs: npm install npm run build echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc - npm run publish || true + npm publish || true From 85bd7e050fb25b5df179e87da7ae855ee496c977 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:47:08 +0900 Subject: [PATCH 07/79] token --- .github/workflows/python.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 08a3b24..00a4d88 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -56,5 +56,5 @@ jobs: - name: upload run: twine upload dist/* --non-interactive --skip-existing env: - TWINE_USERNAME: righ + TWINE_USERNAME: token TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} From 678eb30e37675bc225b32cf1c197032b936eeeb1 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 18:55:40 +0900 Subject: [PATCH 08/79] delete --- .github/workflows/python.yaml | 1 - .github/workflows/typescript.yaml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 00a4d88..5047626 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -52,7 +52,6 @@ jobs: - name: build run: | python ./setup.py sdist bdist_wheel - twine upload dist/* --non-interactive --skip-existing - name: upload run: twine upload dist/* --non-interactive --skip-existing env: diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index 4b43e7e..f57b8ff 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -61,3 +61,4 @@ jobs: npm run build echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc npm publish || true + From 2a01cd431a92c574bd228969898e006b916430d7 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 20:24:04 +0900 Subject: [PATCH 09/79] make async and rename --- .github/workflows/python.yaml | 3 +- python/.gitignore | 3 +- python/covertable/criteria/greedy.py | 10 ++-- python/covertable/criteria/simple.py | 4 +- python/covertable/main.py | 86 +++++++++++++++++----------- python/covertable/sorters/hash.py | 4 +- python/covertable/sorters/random.py | 4 +- typescript/src/criteria/greedy.ts | 14 ++--- typescript/src/criteria/simple.ts | 6 +- typescript/src/index.ts | 24 ++++---- typescript/src/types.ts | 4 +- 11 files changed, 93 insertions(+), 69 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 5047626..8a57765 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -24,11 +24,12 @@ jobs: python -m pip install -r ci_requirements.txt - name: test run: | - pytest --cov=covertable + pytest --cov=covertable --cov-report=xml - name: codecov uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.xml verbose: true release: diff --git a/python/.gitignore b/python/.gitignore index 5f5970b..ba7e8c5 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -3,9 +3,10 @@ __pycache__/ .tox/ venv/ .coverage +coverage.xml .junit.xml htmlcov/ pip-wheel-metadata *.egg-info build/ -dist/ \ No newline at end of file +dist/ diff --git a/python/covertable/criteria/greedy.py b/python/covertable/criteria/greedy.py index 389a2d6..27953be 100644 --- a/python/covertable/criteria/greedy.py +++ b/python/covertable/criteria/greedy.py @@ -3,19 +3,19 @@ from itertools import combinations -def get_num_removable_pairs(indexes, incompleted, length): +def get_num_removable_pairs(indexes, incomplete, length): removing_keys = combinations(indexes, length) - return len(incompleted.intersection(removing_keys)) + return len(incomplete.intersection(removing_keys)) def extract( - sorted_incompleted, row, parents, length, incompleted, tolerance=0, **kwargs + sorted_incomplete, row, parents, length, incomplete, tolerance=0, **kwargs ): while True: max_num_pairs = None efficient_pair = None - for pair in sorted_incompleted: + for pair in sorted_incomplete: if not row: yield pair continue @@ -31,7 +31,7 @@ def extract( continue num_pairs = get_num_removable_pairs( - sorted({*row.values(), *pair}), incompleted, length + sorted({*row.values(), *pair}), incomplete, length ) if num_pairs + tolerance > len(row) * storable: efficient_pair = pair diff --git a/python/covertable/criteria/simple.py b/python/covertable/criteria/simple.py index b14f5ea..66517a8 100644 --- a/python/covertable/criteria/simple.py +++ b/python/covertable/criteria/simple.py @@ -1,5 +1,5 @@ -def extract(sorted_incompleted, row, parents, **kwargs): - for pair in sorted_incompleted: +def extract(sorted_incomplete, row, parents, **kwargs): + for pair in sorted_incomplete: storable = row.storable([(parents[p], p) for p in pair]) if storable is None: continue diff --git a/python/covertable/main.py b/python/covertable/main.py index 1e5c490..7fb519c 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -29,12 +29,12 @@ def convert_factors_to_serials(factors): return serials, parents -def make_incompleted(serials, length): - incompleted = set() +def make_incomplete(serials, length): + incomplete = set() for keys in combinations([k for k, _ in get_items(serials)], length): for pair in product(*[serials[keys[i]] for i in range(length)]): - incompleted.add(pair) - return incompleted + incomplete.add(pair) + return incomplete class Row(dict): @@ -65,7 +65,7 @@ def storable(self, candidate=[]): if self.pre_filter is None: return num nxt = self.new({**self, **dict(candidate)}) - if not self.pre_filter(nxt.restore()): + if not self.pre_filter(nxt.resolve()): return None return num @@ -79,14 +79,21 @@ def complement(self): raise InvalidCondition(InvalidCondition.message) return self - def restore(self): + def resolve(self): return self.new( [key, self.factors[key][serial - self.serials[key][0]]] for key, serial in self.items() ) + def restore(self): + resolved = self.resolve() + if issubclass(self.type, list): + return [r for _, r in sorted(resolved.items())] + if issubclass(self.type, dict): + return dict(resolved) + -def make( +def make_async( factors, length=2, progress=False, @@ -97,20 +104,21 @@ def make( **params, ): serials, parents = convert_factors_to_serials(factors) - incompleted = make_incompleted(serials, length) - len_incompleted = float(len(incompleted)) + incomplete = make_incomplete(serials, length) + len_incomplete = float(len(incomplete)) md5_cache = {} - rows, row = [], Row(None, factors, serials, pre_filter) + row = Row(None, factors, serials, pre_filter) # When pre_filter is specified, - # it will be applied to incompleted through `row.storable` beforehand. - for pair in list(filter(lambda _: pre_filter, incompleted)): + # it will be applied to incomplete through `row.storable` beforehand. + for pair in list(filter(lambda _: pre_filter, incomplete)): ######### if not row.storable([(parents[p], p) for p in pair]): - incompleted.discard(pair) + incomplete.discard(pair) - while incompleted: + while incomplete: if row.filled(): - rows.append(row) + if post_filter is None or post_filter(row.resolve()): + yield row.restore() row = row.new() common_kwargs = { @@ -118,34 +126,48 @@ def make( "row": row, "parents": parents, "length": length, - "incompleted": incompleted, + "incomplete": incomplete, "md5_cache": md5_cache, } - sorted_incompleted = sorter.sort(**common_kwargs) - for pair in criterion.extract(sorted_incompleted, **common_kwargs): + sorted_incomplete = sorter.sort(**common_kwargs) + for pair in criterion.extract(sorted_incomplete, **common_kwargs): if row.filled(): break row.update((parents[p], p) for p in pair) for vs in combinations(sorted(row.values()), length): - incompleted.discard(vs) + incomplete.discard(vs) else: if not row.filled(): row.complement() if progress: - rate = (len_incompleted - len(incompleted)) / len_incompleted + rate = (len_incomplete - len(incomplete)) / len_incomplete print("{0:.2%}\r".format(rate), end="") if row: - rows.append(row.complement()) - - result = [] - for row in rows: - restored = row.restore() - if post_filter and not post_filter(restored): - continue - if issubclass(row.type, list): - result.append([r for _, r in sorted(restored.items())]) - elif issubclass(row.type, dict): - result.append(dict(restored)) - return result + row.complement() + if post_filter is None or post_filter(row.resolve()): + yield row.restore() + + +def make( + factors, + length=2, + progress=False, + sorter=sorters.hash, + criterion=criteria.greedy, + pre_filter=None, + post_filter=None, + **params, +): + gen = make_async( + factors, + length=length, + progress=progress, + sorter=sorter, + criterion=criterion, + pre_filter=pre_filter, + post_filter=post_filter, + **params, + ) + return list(gen) diff --git a/python/covertable/sorters/hash.py b/python/covertable/sorters/hash.py index ec2238d..4e433d8 100644 --- a/python/covertable/sorters/hash.py +++ b/python/covertable/sorters/hash.py @@ -4,7 +4,7 @@ import hashlib -def sort(incompleted, md5_cache, seed="", use_cache=True, *args, **kwargs): +def sort(incomplete, md5_cache, seed="", use_cache=True, *args, **kwargs): def comparer(v): if use_cache and v in md5_cache: return md5_cache[v] @@ -15,4 +15,4 @@ def comparer(v): md5_cache[v] = value return value - return sorted(incompleted, key=comparer) + return sorted(incomplete, key=comparer) diff --git a/python/covertable/sorters/random.py b/python/covertable/sorters/random.py index 67cbfcf..8851b1f 100644 --- a/python/covertable/sorters/random.py +++ b/python/covertable/sorters/random.py @@ -8,5 +8,5 @@ def random_comparer(_): return random.random() -def sort(incompleted, *args, **kwargs): - return sorted(incompleted, key=random_comparer) +def sort(incomplete, *args, **kwargs): + return sorted(incomplete, key=random_comparer) diff --git a/typescript/src/criteria/greedy.ts b/typescript/src/criteria/greedy.ts index 46c92ae..688d2cf 100644 --- a/typescript/src/criteria/greedy.ts +++ b/typescript/src/criteria/greedy.ts @@ -1,12 +1,12 @@ -import {CriterionArgsType, IncompletedType, PairType} from '../types'; +import {CriterionArgsType, IncompleteType, PairType} from '../types'; import {getCandidate, combinations, ascOrder, unique} from '../utils'; -const getNumRemovablePairs = (indexes: Set, incompleted: IncompletedType, length: number) => { +const getNumRemovablePairs = (indexes: Set, incomplete: IncompleteType, length: number) => { let num = 0; const removingKeys = combinations([... indexes], length); for (let pair of removingKeys) { const key = unique(pair); - if (incompleted.has(key)) { + if (incomplete.has(key)) { num++; } } @@ -14,7 +14,7 @@ const getNumRemovablePairs = (indexes: Set, incompleted: IncompletedType }; export default function* ( - incompleted: IncompletedType, + incomplete: IncompleteType, criterionArgs: CriterionArgsType, ): Generator { let {row, parents, length, tolerance} = criterionArgs; @@ -23,7 +23,7 @@ export default function* ( let maxNumPairs: number | null = null; let efficientPair: PairType | null = null; - for (let [pairKey, pair] of incompleted.entries()) { + for (let [pairKey, pair] of incomplete.entries()) { const rowSize = row.size; if (rowSize === 0) { yield pair; @@ -39,12 +39,12 @@ export default function* ( } if (storable === 0) { - incompleted.delete(pairKey); + incomplete.delete(pairKey); continue; } const numPairs = getNumRemovablePairs( - new Set([... row.values(), ...pair]), incompleted, length + new Set([... row.values(), ...pair]), incomplete, length ); if (numPairs + tolerance > rowSize * storable) { diff --git a/typescript/src/criteria/simple.ts b/typescript/src/criteria/simple.ts index 8ec9515..f42cee6 100644 --- a/typescript/src/criteria/simple.ts +++ b/typescript/src/criteria/simple.ts @@ -1,12 +1,12 @@ -import {CriterionArgsType, IncompletedType, PairType} from '../types'; +import {CriterionArgsType, IncompleteType, PairType} from '../types'; import {getCandidate} from '../utils'; export default function* ( - incompleted: IncompletedType, + incomplete: IncompleteType, criterionArgs: CriterionArgsType, ): Generator { const {row, parents} = criterionArgs; - for (let pair of incompleted.values()) { + for (let pair of incomplete.values()) { const storable = row.storable(getCandidate(pair, parents)); if (storable === null || storable === 0) { continue; diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 2f9949f..41234c5 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -19,7 +19,7 @@ import { MappingTypes, Scalar, Dict, - IncompletedType, + IncompleteType, ParentsType, CandidateType, RowType, @@ -52,12 +52,12 @@ const serialize = (factors: FactorsType): MappingTypes => { return { serials, parents, indices }; }; -const makeIncompleted = ( +const makeIncomplete = ( mappings: MappingTypes, length: number, sorter: SorterType, seed: Scalar -): IncompletedType => { +): IncompleteType => { const { serials, indices } = mappings; const pairs: PairType[] = []; const allKeys = getItems(serials).map(([k, _]) => k); @@ -68,11 +68,11 @@ const makeIncompleted = ( pairs.push(pair); } } - const incompleted: IncompletedType = new Map(); + const incomplete: IncompleteType = new Map(); for (let pair of sorter(pairs, { seed, indices })) { - incompleted.set(unique(pair), pair); + incomplete.set(unique(pair), pair); } - return incompleted; + return incomplete; }; class Row extends Map implements RowType { @@ -183,16 +183,16 @@ const makeAsync = function* ( const { preFilter, postFilter } = options; const mappings = serialize(factors); const { parents } = mappings; - const incompleted = makeIncompleted(mappings, length, sorter, seed); // {"1,2": [1,2], "3,4": [3,4]} + const incomplete = makeIncomplete(mappings, length, sorter, seed); // {"1,2": [1,2], "3,4": [3,4]} let row: Row = new Row([], mappings, factors, preFilter); - for (let [pairKey, pair] of incompleted.entries()) { + for (let [pairKey, pair] of incomplete.entries()) { if (!row.storable(getCandidate(pair, parents))) { - incompleted.delete(pairKey); + incomplete.delete(pairKey); } } - while (incompleted.size) { + while (incomplete.size) { if (row.filled()) { if (!postFilter || postFilter(row.toObject())) { yield row.restore() as SuggestRowType; @@ -200,7 +200,7 @@ const makeAsync = function* ( row = row.New([]); } let finished = true; - for (let pair of criterion(incompleted, { + for (let pair of criterion(incomplete, { row, parents, length, @@ -216,7 +216,7 @@ const makeAsync = function* ( } for (let p of combinations([...row.values()], length)) { - incompleted.delete(unique(p)); + incomplete.delete(unique(p)); } } if (finished && !row.filled()) { diff --git a/typescript/src/types.ts b/typescript/src/types.ts index 787f31f..c55d536 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -19,7 +19,7 @@ export type FilterType = (row: { export type PairType = number[]; -export type IncompletedType = Map; +export type IncompleteType = Map; export type CandidateType = [Scalar, number][]; @@ -52,7 +52,7 @@ export interface CriterionArgsType { export interface OptionsType { length?: number; sorter?: SorterType; - criterion?: (incompleted: IncompletedType, options: CriterionArgsType) => IterableIterator; + criterion?: (incomplete: IncompleteType, options: CriterionArgsType) => IterableIterator; seed?: Scalar; tolerance?: number; preFilter?: FilterType; From 665eeb42cbb0838a84b906c95319498b1bc14442 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 20:38:53 +0900 Subject: [PATCH 10/79] version 2.1.0 for python --- python/README.rst | 2 +- python/setup.cfg | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/README.rst b/python/README.rst index d983654..07e5389 100644 --- a/python/README.rst +++ b/python/README.rst @@ -158,7 +158,7 @@ Development (venv) $ pip install -r dev_requirements.txt # testing - (venv) $ tox # -e py37 -e cov -e black + (venv) $ pytest Publish diff --git a/python/setup.cfg b/python/setup.cfg index ceb5e32..65df6ed 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = covertable -version = 2.0.1 +version = 2.1.0 author = righ author_email = righ.m9@gmail.com url = https://github.com/walkframe/covertable/ @@ -36,5 +36,5 @@ keywords = covering-arrays pict -description = It makes combinations covering pairs for pairwise testing. +description = A flexible pairwise tool written in Python. long_description = file: README.rst From 036026eccb9e2ad8cb1649ed945c07ac6cd56c62 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 20:42:27 +0900 Subject: [PATCH 11/79] use action --- .github/workflows/python.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 8a57765..9e9e4e9 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -54,7 +54,7 @@ jobs: run: | python ./setup.py sdist bdist_wheel - name: upload - run: twine upload dist/* --non-interactive --skip-existing - env: - TWINE_USERNAME: token - TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.PYPI_TOKEN }} From 04ab0ac2346ab7b34096a978aed4761f66e70ee5 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 20:45:00 +0900 Subject: [PATCH 12/79] update version --- .github/workflows/python.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 9e9e4e9..41fdf40 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -54,7 +54,7 @@ jobs: run: | python ./setup.py sdist bdist_wheel - name: upload - uses: pypa/gh-action-pypi-publish@master + uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} From b8bcfd90eec42f15bc796a7cf46e0d78ccf55de6 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 20:55:21 +0900 Subject: [PATCH 13/79] update --- .github/workflows/python.yaml | 2 ++ python/ci_requirements.txt | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 41fdf40..ef6e610 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -53,8 +53,10 @@ jobs: - name: build run: | python ./setup.py sdist bdist_wheel + ls -l dist/ - name: upload uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} + skip_existing: true diff --git a/python/ci_requirements.txt b/python/ci_requirements.txt index 03914f4..3fbff8a 100644 --- a/python/ci_requirements.txt +++ b/python/ci_requirements.txt @@ -2,5 +2,3 @@ pytest pytest-cov setuptools wheel -twine -black From 6a915a8ef3e2834ed56edda2dbeeece47b146775 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 21:10:03 +0900 Subject: [PATCH 14/79] update --- .github/workflows/python.yaml | 5 ++--- python/ci_requirements.txt | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index ef6e610..6537057 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -45,15 +45,14 @@ jobs: - name: setup uses: actions/setup-python@v4 with: - python-version: 3.11 + python-version: 3.10 - name: install run: | python -m pip install --upgrade pip python -m pip install -r ci_requirements.txt - name: build run: | - python ./setup.py sdist bdist_wheel - ls -l dist/ + python -m build --sdist --wheel --outdir dist/ . - name: upload uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/python/ci_requirements.txt b/python/ci_requirements.txt index 3fbff8a..15c1add 100644 --- a/python/ci_requirements.txt +++ b/python/ci_requirements.txt @@ -1,4 +1,3 @@ pytest pytest-cov -setuptools -wheel +build From 11e55600ecffd50aa3e75cb5e85e7eb1cb62994c Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 21:12:08 +0900 Subject: [PATCH 15/79] stringify --- .github/workflows/python.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 6537057..908880c 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -45,7 +45,7 @@ jobs: - name: setup uses: actions/setup-python@v4 with: - python-version: 3.10 + python-version: "3.10" - name: install run: | python -m pip install --upgrade pip From 2624af24875b4f844c5b440e3c294694cb08784a Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 22:10:02 +0900 Subject: [PATCH 16/79] specify dist --- .github/workflows/python.yaml | 1 + python/covertable/main.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 908880c..7a33ae0 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -58,4 +58,5 @@ jobs: with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} + package: dist/* skip_existing: true diff --git a/python/covertable/main.py b/python/covertable/main.py index 7fb519c..7d86b9b 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -111,7 +111,7 @@ def make_async( row = Row(None, factors, serials, pre_filter) # When pre_filter is specified, # it will be applied to incomplete through `row.storable` beforehand. - for pair in list(filter(lambda _: pre_filter, incomplete)): ######### + for pair in list(filter(lambda _: pre_filter, incomplete)): if not row.storable([(parents[p], p) for p in pair]): incomplete.discard(pair) From 691b237b6a7df88df48045207b8d41efc34d7c5f Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 22:18:36 +0900 Subject: [PATCH 17/79] debug --- .github/workflows/python.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 7a33ae0..f13142b 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -53,6 +53,9 @@ jobs: - name: build run: | python -m build --sdist --wheel --outdir dist/ . + ls -la + ls -la dist + pwd - name: upload uses: pypa/gh-action-pypi-publish@release/v1 with: From ecc97e19f69443c9fdfee15a563aa6d6964d928e Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 22:32:54 +0900 Subject: [PATCH 18/79] upload by twine --- .github/workflows/python.yaml | 7 +++++++ python/ci_requirements.txt | 1 + 2 files changed, 8 insertions(+) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index f13142b..5b70702 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -53,9 +53,16 @@ jobs: - name: build run: | python -m build --sdist --wheel --outdir dist/ . + - name: Upload + run: | ls -la ls -la dist pwd + twine upload dist/* --non-interactive --skip-existing + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + - name: upload uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/python/ci_requirements.txt b/python/ci_requirements.txt index 15c1add..e577f2f 100644 --- a/python/ci_requirements.txt +++ b/python/ci_requirements.txt @@ -1,3 +1,4 @@ pytest pytest-cov build +twine From 174802912af7008dc3c04e3ad566627489cb3a2a Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 22:36:20 +0900 Subject: [PATCH 19/79] do not use pypa/gh-action-pypi-publish@release/v1 --- .github/workflows/python.yaml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 5b70702..27fd6d1 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -53,20 +53,9 @@ jobs: - name: build run: | python -m build --sdist --wheel --outdir dist/ . - - name: Upload + - name: upload run: | - ls -la - ls -la dist - pwd twine upload dist/* --non-interactive --skip-existing env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} - - - name: upload - uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.PYPI_TOKEN }} - package: dist/* - skip_existing: true From 737ae17b37742afb58ef8dbb1e3e1fe0ae9d7ff8 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 22:47:48 +0900 Subject: [PATCH 20/79] codecov --- .github/workflows/python.yaml | 1 + python/ci_requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 27fd6d1..c4e2f01 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -25,6 +25,7 @@ jobs: - name: test run: | pytest --cov=covertable --cov-report=xml + codecov - name: codecov uses: codecov/codecov-action@v3 with: diff --git a/python/ci_requirements.txt b/python/ci_requirements.txt index e577f2f..2e4f605 100644 --- a/python/ci_requirements.txt +++ b/python/ci_requirements.txt @@ -1,4 +1,5 @@ pytest pytest-cov +codecov build twine From 6f99e8567b8801478c61c305fc115dc4e83d2a75 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 23:10:26 +0900 Subject: [PATCH 21/79] use action --- .github/workflows/python.yaml | 3 +-- .github/workflows/typescript.yaml | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index c4e2f01..67b27bc 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -25,12 +25,11 @@ jobs: - name: test run: | pytest --cov=covertable --cov-report=xml - codecov - name: codecov uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ./coverage.xml + file: ./python/coverage.xml verbose: true release: diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index f57b8ff..bd7b039 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -27,11 +27,12 @@ jobs: - name: test run: | npm test -- --coverage - npm run codecov + # npm run codecov - name: codecov uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} + file: ./python/coverage/lcov.info verbose: true release: From 2e66202c36318608dd03a6e73574a721d6a0f4b7 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Feb 2023 23:14:28 +0900 Subject: [PATCH 22/79] fix path --- .github/workflows/typescript.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index bd7b039..536e942 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -32,7 +32,7 @@ jobs: uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ./python/coverage/lcov.info + file: ./typescript/coverage/lcov.info verbose: true release: From f0ea342bea3977383a597b22371e11c05a4798e9 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 5 Aug 2024 03:25:16 +0900 Subject: [PATCH 23/79] pict constraints --- typescript/src/__tests__/pict.test.ts | 250 +++++++++++++++++ typescript/src/types.ts | 6 +- typescript/src/utils/pict.ts | 378 ++++++++++++++++++++++++++ 3 files changed, 632 insertions(+), 2 deletions(-) create mode 100644 typescript/src/__tests__/pict.test.ts create mode 100644 typescript/src/utils/pict.ts diff --git a/typescript/src/__tests__/pict.test.ts b/typescript/src/__tests__/pict.test.ts new file mode 100644 index 0000000..808057e --- /dev/null +++ b/typescript/src/__tests__/pict.test.ts @@ -0,0 +1,250 @@ +import { PictConstraintsLexer } from "../utils/pict"; + +describe('PictConstraintsLexer with single constraints', () => { + it('should filter correctly with LIKE and IN conditions', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] LIKE "Alic?" THEN [STATUS] IN {"Active", "Pending"} ELSE [AGE] > 20 OR [COUNTRY] = "USA"; + `, false); + const row1 = { NAME: 'Alice', STATUS: 'Active' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { NAME: 'Alice', STATUS: 'Inactive' }; + expect(lexer.filter(row2)).toBe(false); + }); + + it('should filter correctly with numeric conditions', () => { + const lexer = new PictConstraintsLexer(` + IF [PRICE] > 100 THEN [DISCOUNT] = "YES" ELSE [DISCOUNT] = "NO"; + `, false); + const row1 = { PRICE: 150, DISCOUNT: 'YES' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { PRICE: 90, DISCOUNT: 'NO' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { PRICE: 90, DISCOUNT: 'YES' }; + expect(lexer.filter(row3)).toBe(false); + }); + + it('should handle NOT conditions correctly', () => { + const lexer = new PictConstraintsLexer(` + IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] = "Yes" ELSE [AVAILABLE] = "No"; + `, false); + const row1 = { PRODUCT: 'Pen', AVAILABLE: 'Yes' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { PRODUCT: 'Book', AVAILABLE: 'No' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { PRODUCT: 'Pen', AVAILABLE: 'No' }; + expect(lexer.filter(row3)).toBe(false); + }); + + it('should filter with AND conditions', () => { + const lexer = new PictConstraintsLexer(` + IF [CATEGORY] = "Electronics" AND [BRAND] = "Sony" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; + `, false); + const row1 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Included' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { CATEGORY: 'Electronics', BRAND: 'Samsung', WARRANTY: 'Not Included' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Not Included' }; + expect(lexer.filter(row3)).toBe(false); + }); + + it('should handle nested conditions with parentheses', () => { + const lexer = new PictConstraintsLexer(` + IF ([CATEGORY] = "Electronics" AND [BRAND] = "Sony") OR [BRAND] = "Apple" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; + `, false); + const row1 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Included' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { CATEGORY: 'Electronics', BRAND: 'Apple', WARRANTY: 'Included' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { CATEGORY: 'Furniture', BRAND: 'IKEA', WARRANTY: 'Not Included' }; + expect(lexer.filter(row3)).toBe(true); + + const row4 = { CATEGORY: 'Electronics', BRAND: 'Samsung', WARRANTY: 'Included' }; + expect(lexer.filter(row4)).toBe(false); + }); + + it('should handle string equality conditions', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE [STATUS] = "Active"; + `, false); + const row1 = { NAME: 'Bob', STATUS: 'Inactive' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { NAME: 'Alice', STATUS: 'Active' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { NAME: 'Bob', STATUS: 'Active' }; + expect(lexer.filter(row3)).toBe(false); + }); + + it('should handle IN conditions', () => { + const lexer = new PictConstraintsLexer(` + IF [COLOR] IN {"Red", "Blue", "Green"} THEN [CATEGORY] = "Primary" ELSE [CATEGORY] = "Secondary"; + `, false); + const row1 = { COLOR: 'Red', CATEGORY: 'Primary' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { COLOR: 'Yellow', CATEGORY: 'Secondary' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { COLOR: 'Red', CATEGORY: 'Secondary' }; + expect(lexer.filter(row3)).toBe(false); + }); + + it('should handle complex conditions with nested parentheses', () => { + const lexer = new PictConstraintsLexer(` + IF ([AGE] > 20 AND ([COUNTRY] = "USA" OR [COUNTRY] = "Canada")) THEN [STATUS] = "Allowed" ELSE [STATUS] = "Denied"; + `, false); + const row1 = { AGE: 25, COUNTRY: 'USA', STATUS: 'Allowed' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { AGE: 18, COUNTRY: 'USA', STATUS: 'Denied' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { AGE: 25, COUNTRY: 'UK', STATUS: 'Denied' }; + expect(lexer.filter(row3)).toBe(true); + + const row4 = { AGE: 25, COUNTRY: 'Canada', STATUS: 'Allowed' }; + expect(lexer.filter(row4)).toBe(true); + + const row5 = { AGE: 25, COUNTRY: 'Canada', STATUS: 'Denied' }; + expect(lexer.filter(row5)).toBe(false); + }); +}); + +describe('PictConstraintsLexer with multiple constraints', () => { + it('should handle multiple constraints correctly (Test Case 1)', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = "Alice" THEN [AGE] > 20 ELSE [AGE] < 20; + IF [COUNTRY] = "USA" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `, false); + + const row1 = { NAME: 'Alice', AGE: 25, COUNTRY: 'USA', STATUS: 'Active' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { NAME: 'Alice', AGE: 25, COUNTRY: 'Canada', STATUS: 'Inactive' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { NAME: 'Alice', AGE: 18, COUNTRY: 'USA', STATUS: 'Active' }; + expect(lexer.filter(row3)).toBe(false); + + const row4 = { NAME: 'Bob', AGE: 15, COUNTRY: 'USA', STATUS: 'Inactive' }; + expect(lexer.filter(row4)).toBe(false); + }); + + it('should handle multiple constraints correctly (Test Case 2)', () => { + const lexer = new PictConstraintsLexer(` + IF [SCORE] >= 90 THEN [GRADE] = "A" ELSE [GRADE] = "B"; + IF [MEMBER] = "YES" THEN [DISCOUNT] = "20%" ELSE [DISCOUNT] = "10%"; + `, false); + + const row1 = { SCORE: 95, GRADE: 'A', MEMBER: 'YES', DISCOUNT: '20%' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { SCORE: 85, GRADE: 'B', MEMBER: 'NO', DISCOUNT: '10%' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { SCORE: 85, GRADE: 'B', MEMBER: 'YES', DISCOUNT: '20%' }; + expect(lexer.filter(row3)).toBe(true); + + const row4 = { SCORE: 85, GRADE: 'A', MEMBER: 'YES', DISCOUNT: '10%' }; + expect(lexer.filter(row4)).toBe(false); + }); + + it('should handle multiple constraints correctly (Test Case 3)', () => { + const lexer = new PictConstraintsLexer(` + IF [TEMP] > 30 THEN [STATE] = "HOT" ELSE [STATE] = "COLD"; + IF [HUMIDITY] < 50 THEN [COMFORT] = "DRY" ELSE [COMFORT] = "HUMID"; + `, false); + + const row1 = { TEMP: 35, STATE: 'HOT', HUMIDITY: 45, COMFORT: 'DRY' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { TEMP: 25, STATE: 'COLD', HUMIDITY: 55, COMFORT: 'HUMID' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { TEMP: 25, STATE: 'HOT', HUMIDITY: 55, COMFORT: 'DRY' }; + expect(lexer.filter(row3)).toBe(false); + + const row4 = { TEMP: 35, STATE: 'HOT', HUMIDITY: 55, COMFORT: 'HUMID' }; + expect(lexer.filter(row4)).toBe(true); + }); + + it('should handle multiple constraints correctly (Test Case 4)', () => { + const lexer = new PictConstraintsLexer(` + IF [CATEGORY] = "Electronics" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; + IF [PRICE] > 100 THEN [DISCOUNT] = "YES" ELSE [DISCOUNT] = "NO"; + `, false); + + const row1 = { CATEGORY: 'Electronics', WARRANTY: 'Included', PRICE: 150, DISCOUNT: 'YES' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { CATEGORY: 'Furniture', WARRANTY: 'Not Included', PRICE: 90, DISCOUNT: 'NO' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { CATEGORY: 'Electronics', WARRANTY: 'Not Included', PRICE: 150, DISCOUNT: 'NO' }; + expect(lexer.filter(row3)).toBe(false); + + const row4 = { CATEGORY: 'Furniture', WARRANTY: 'Not Included', PRICE: 150, DISCOUNT: 'YES' }; + expect(lexer.filter(row4)).toBe(true); + }); + + it('should handle multiple constraints correctly (Test Case 5)', () => { + const lexer = new PictConstraintsLexer(` + IF [COLOR] = "Red" THEN [CATEGORY] = "Primary" ELSE [CATEGORY] = "Secondary"; + IF [QUANTITY] < 10 THEN [STOCK] = "Low" ELSE [STOCK] = "High"; + `, false); + + const row1 = { COLOR: 'Red', CATEGORY: 'Primary', QUANTITY: 5, STOCK: 'Low' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { COLOR: 'Blue', CATEGORY: 'Secondary', QUANTITY: 20, STOCK: 'High' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { COLOR: 'Red', CATEGORY: 'Secondary', QUANTITY: 5, STOCK: 'High' }; + expect(lexer.filter(row3)).toBe(false); + + const row4 = { COLOR: 'Red', CATEGORY: 'Primary', QUANTITY: 20, STOCK: 'High' }; + expect(lexer.filter(row4)).toBe(true); + }); + + it('should handle multiple constraints correctly (Test Case 6)', () => { + const lexer = new PictConstraintsLexer(` + IF [SIZE] = "Large" THEN [AVAILABILITY] = "In Stock" ELSE [AVAILABILITY] = "Out of Stock"; + IF ([DISCOUNT] = "YES" AND [MEMBER] = "YES") THEN [PRICE] < 100 ELSE [PRICE] >= 100; + `, false); + + const row1 = { SIZE: 'Large', AVAILABILITY: 'In Stock', DISCOUNT: 'YES', MEMBER: 'YES', PRICE: 90 }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { SIZE: 'Medium', AVAILABILITY: 'Out of Stock', DISCOUNT: 'NO', MEMBER: 'NO', PRICE: 120 }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { SIZE: 'Large', AVAILABILITY: 'In Stock', DISCOUNT: 'YES', MEMBER: 'NO', PRICE: 110 }; + expect(lexer.filter(row3)).toBe(true); + }); + + it('should handle multiple constraints correctly (Test Case 7)', () => { + const lexer = new PictConstraintsLexer(` + IF [SEASON] = "Winter" THEN [CLOTHING] = "Coat" ELSE [CLOTHING] = "Shirt"; + IF ([TEMP] < 0 AND [WEATHER] = "Snowy") THEN [ACTIVITY] = "Skiing" ELSE [ACTIVITY] = "Running"; + `, false); + + const row1 = { SEASON: 'Winter', CLOTHING: 'Coat', TEMP: -5, WEATHER: 'Snowy', ACTIVITY: 'Skiing' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { SEASON: 'Summer', CLOTHING: 'Shirt', TEMP: 25, WEATHER: 'Sunny', ACTIVITY: 'Running' }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { SEASON: 'Winter', CLOTHING: 'Coat', TEMP: 5, WEATHER: 'Sunny', ACTIVITY: 'Running' }; + expect(lexer.filter(row3)).toBe(true); + }); +}); diff --git a/typescript/src/types.ts b/typescript/src/types.ts index c55d536..340da9a 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -12,10 +12,12 @@ export type MappingTypes = { indices: IndicesType; }; -export type FilterType = (row: { +export type FilterRowType = { [key: string]: any; [index: number]: any; -}) => boolean; +} + +export type FilterType = (row: FilterRowType) => boolean; export type PairType = number[]; diff --git a/typescript/src/utils/pict.ts b/typescript/src/utils/pict.ts new file mode 100644 index 0000000..c9a38f3 --- /dev/null +++ b/typescript/src/utils/pict.ts @@ -0,0 +1,378 @@ +import { FilterType, FilterRowType } from "../types"; + +type Token = { + type: string; + value: string; +} + +type CacheType = { + [key: string]: any; +}; + +export class PictConstraintsLexer { + private tokens: Token[] = []; + private cache: CacheType = {}; + public filters: (FilterType | null)[] = []; + public errors: string[][] = []; + + constructor(private input: string, private debug=false) { + this.input = input; + this.debug = debug; + this.tokenize(); + this.analyze(); + } + private tokenize(): Token[] { + const constraints = this.input; + const tokens: Token[] = []; + let buffer = ''; + let insideQuotes = false; + let insideBraces = false; + + const addToken = (type: string, value: string) => { + tokens.push({ type, value }); + }; + + for (let i = 0; i < constraints.length; i++) { + const char = constraints[i]; + + if (char === '"') { + insideQuotes = !insideQuotes; + buffer += char; + if (!insideQuotes) { + addToken('STRING', buffer); + buffer = ''; + } + } else if (insideQuotes) { + buffer += char; + } else if (char === '[') { + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + buffer += char; + } else if (char === ']') { + buffer += char; + tokens.push(classifyToken(buffer)); + buffer = ''; + } else if (char === '{') { + insideBraces = true; + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + addToken('LBRACE', char); + } else if (char === '}') { + insideBraces = false; + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + addToken('RBRACE', char); + } else if (char === ',' && insideBraces) { + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + addToken('COMMA', char); + } else if ('[]=<>!();:'.includes(char) && !insideBraces) { + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + if (char === '<' || char === '>' || char === '!' || char === '=') { + const nextChar = constraints[i + 1]; + if (nextChar === '=') { + tokens.push(classifyToken(char + '=')); + i++; + } else if (char === '<' && nextChar === '>') { + tokens.push(classifyToken('<>')); + i++; + } else { + tokens.push(classifyToken(char)); + } + } else { + tokens.push(classifyToken(char)); + } + } else if (isWhiteSpace(char) && !insideBraces) { + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + let whitespaceBuffer = char; + while (i + 1 < constraints.length && isWhiteSpace(constraints[i + 1])) { + whitespaceBuffer += constraints[++i]; + } + addToken('WHITESPACE', whitespaceBuffer); + } else if (isWhiteSpace(char) && insideBraces) { + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + buffer = ''; + } + addToken('WHITESPACE', char); + } else { + buffer += char; + } + } + + if (buffer.length > 0) { + tokens.push(classifyToken(buffer)); + } + this.tokens = tokens; + return tokens; + } + + private analyze() { + let tokenIndex = 0; + let setIndex = 0; + let regexIndex = 0; + let errorMessages: string[] = []; + const errors: string[][] = []; + const tokens = this.tokens; + const filters: (FilterType | null)[] = []; + + const nextToken = () => { + while (tokenIndex < tokens.length && tokens[tokenIndex].type === 'WHITESPACE') { + tokenIndex++; + } + return tokenIndex < tokens.length ? tokens[tokenIndex++] : null; + } + + const parseExpression: () => string = () => { + let expr = parseTerm(); + let token = nextToken(); + while (token && token.type === 'OPERATOR' && token.value === 'OR') { + const right = parseTerm(); + expr = `(${expr} || ${right})`; + token = nextToken(); + } + tokenIndex--; // Go back one token + return expr; + } + + const parseTerm: () => string = () => { + let term = parseFactor(); + let token = nextToken(); + while (token && token.type === 'OPERATOR' && token.value === 'AND') { + const right = parseFactor(); + term = `(${term} && ${right})`; + token = nextToken(); + } + tokenIndex--; // Go back one token + return term; + } + + const parseFactor: () => string = () => { + let token = nextToken(); + if (token && token.type === 'OPERATOR' && token.value === 'NOT') { + const factor = parseFactor(); + return `!(${factor})`; + } else if (token && token.type === 'LPAREN') { + const expr = parseExpression(); + token = nextToken(); + if (!token || token.type !== 'RPAREN') { + errorMessages.push('Expected closing parenthesis'); + return 'false'; + } + return `(${expr})`; + } else { + tokenIndex--; // Go back one token + return parseCondition(); + } + } + + const parseCondition: () => string = () => { + const left = parseOperand(); + const comparerToken = nextToken(); + if (!comparerToken || comparerToken.type !== 'COMPARER') { + errorMessages.push('Expected comparer'); + return 'false'; + } + const comparer = comparerToken.value; + if (comparer === 'IN') { + const right = parseSet(); + return `${right}.has(${left})`; + } + const right = parseOperand(); + switch (comparer) { + case '=': + return `${left} === ${right}`; + case '<>': + return `${left} !== ${right}`; + case '>': + return `${left} > ${right}`; + case '<': + return `${left} < ${right}`; + case '>=': + return `${left} >= ${right}`; + case '<=': + return `${left} <= ${right}`; + case 'LIKE': + const regexPattern = right.slice(1, -1).replace(/\*/g, '.*').replace(/\?/g, '.'); // remove quotes and replace wildcards + const regexKey = `re_${regexIndex++}`; + if (!this.cache[regexKey]) { + this.cache[regexKey] = new RegExp('^' + regexPattern + '$'); + } + return `this.cache['${regexKey}'].test(${left})`; + default: + errorMessages.push(`Unknown comparer: ${comparer}`); + return 'false'; + } + } + + const parseSet: () => string = () => { + const elements: string[] = []; + let token = nextToken(); + if (token && token.type === 'LBRACE') { + token = nextToken(); + while (token && token.type !== 'RBRACE') { + if (token.type === 'STRING') { + elements.push(token.value.slice(1, -1)); // remove quotes + } else if (token.type !== 'COMMA' && token.type !== 'WHITESPACE') { + errorMessages.push(`Unexpected token: ${token.value}`); + } + token = nextToken(); + } + } else { + errorMessages.push(`Expected '{' but found ${token ? token.value : 'null'}`); + } + const setKey = `set_${setIndex++}`; + if (!this.cache[setKey]) { + this.cache[setKey] = new Set(elements); + } + return `this.cache['${setKey}']`; + } + + const parseOperand: () => string = () => { + const token = nextToken(); + if (token == null) { + errorMessages.push('Unexpected end of input'); + return 'false'; + } + if (token.type === 'REF') { + const key = token.value.slice(1, -1); // remove [ and ] + return `row["${key}"]`; + } else if (token.type === 'STRING') { + const value = token.value; // keep quotes for string literals + return `${value}`; + } else if (token.type === 'NUMBER') { + return token.value; + } else if (token.type === 'BOOLEAN') { + return token.value === 'TRUE' ? 'true' : 'false'; + } else if (token.type === 'NULL') { + return 'null'; + } else { + errorMessages.push(`Unexpected token: ${token.value}`); + return 'false'; + } + } + + while (tokenIndex < tokens.length) { + const token = nextToken(); + if (token == null) { + break; + } + if (token.type === 'IF') { + const condition = parseExpression(); + const thenToken = nextToken(); + if (!thenToken || thenToken.type !== 'THEN') { + errorMessages.push('Expected THEN'); + break; + } + const action = parseExpression(); + let elseAction = 'false'; + const elseToken = nextToken(); + if (elseToken && elseToken.type === 'ELSE') { + elseAction = parseExpression(); + } else { + tokenIndex--; // Go back one token if ELSE is not found + } + + const filterCode = `return (${condition} ? (${action}) : (${elseAction}));`; + try { + if (this.debug) { + console.log(`code[${filters.length}]:`, filterCode); + } + const f = this.makeClosure(filterCode); + filters.push(f as FilterType); + } catch (e) { + filters.push(null); + // @ts-ignore + errorMessages.push(e.message); + } + errors.push(errorMessages); + errorMessages = []; + } else if (token.type === 'SEMICOLON') { + // do nothing + } else { + errorMessages.push(`Unexpected token: ${token.value}`); + errors.push(errorMessages); + break; + } + } + this.filters = filters; + this.errors = errors; + } + + private makeClosure (code: string) { + return new Function('row', code).bind(this) as FilterType; + } + + filter(row: FilterRowType, ...additionalFilters: FilterType[]): boolean { + for (const f of this.filters) { + if (f == null) { + continue; + } + if (!f(row)) { + return false; + } + } + for (const f of additionalFilters) { + if (!f(row)) { + return false; + } + } + return true; + } +} + +function classifyToken(token: string): Token { + if (token.startsWith('[') && token.endsWith(']')) { + return { type: 'REF', value: token }; + } + if (token.startsWith('"') && token.endsWith('"')) { + return { type: 'STRING', value: token }; + } + if (!isNaN(parseFloat(token))) { + return { type: 'NUMBER', value: token }; + } + if (['TRUE', 'FALSE'].includes(token.toUpperCase())) { + return { type: 'BOOLEAN', value: token.toUpperCase() }; + } + if (token.toUpperCase() === 'NULL') { + return { type: 'NULL', value: token.toUpperCase() }; + } + if (['IF', 'ELSE', 'THEN'].includes(token.toUpperCase())) { + return { type: token.toUpperCase(), value: token.toUpperCase() }; + } + if (['=', '<>', '>', '<', '>=', '<=', 'IN', 'LIKE'].includes(token.toUpperCase())) { + return { type: 'COMPARER', value: token.toUpperCase() }; + } + if (['AND', 'OR', 'NOT'].includes(token.toUpperCase())) { + return { type: 'OPERATOR', value: token.toUpperCase() }; + } else { + switch (token) { + case '(': return { type: 'LPAREN', value: token }; + case ')': return { type: 'RPAREN', value: token }; + case '{': return { type: 'LBRACE', value: token }; + case '}': return { type: 'RBRACE', value: token }; + case ',': return { type: 'COMMA', value: token }; + case ':': return { type: 'COLON', value: token }; + case ';': return { type: 'SEMICOLON', value: token }; + default: throw new Error(`Unknown token: ${token}`); + } + } +} + +const isWhiteSpace = (char: string) => { + return char === ' ' || char === '\n' || char === '\t'; +}; From 7d37688960ee89a282c55ddb24acac4bc2b57112 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 01:25:20 +0900 Subject: [PATCH 24/79] v2.3.0 alpha --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 10c3bf3..188a67f 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.2.6", + "version": "2.3.0-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.2.6", + "version": "2.3.0-alpha.0", "license": "ISC", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index ebce18c..c2fd18f 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.2.6", + "version": "2.3.0-alpha.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From b3ddf83c09f35d2e834a6e24f8e1370e669519f8 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 02:05:29 +0900 Subject: [PATCH 25/79] exports --- typescript/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/typescript/package.json b/typescript/package.json index c2fd18f..3d065f2 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -70,5 +70,8 @@ }, "dependencies": { "js-md5": "^0.7.3" + }, + "exports": { + "./utils/pict": "./dist/utils/pict.js" } } From 19a8856c8535fd602bec1f17d855b3aa97bc28e4 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 02:06:40 +0900 Subject: [PATCH 26/79] version --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 188a67f..616cf62 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.0-alpha.0", + "version": "2.3.0-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.0-alpha.0", + "version": "2.3.0-alpha.1", "license": "ISC", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 3d065f2..16bcd8c 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.0-alpha.0", + "version": "2.3.0-alpha.1", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From d7544771296a3b7f8c75ca399e6243f0208bee2b Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 03:14:18 +0900 Subject: [PATCH 27/79] export --- typescript/package.json | 3 --- typescript/src/index.ts | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/typescript/package.json b/typescript/package.json index 16bcd8c..1a9d7eb 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -70,8 +70,5 @@ }, "dependencies": { "js-md5": "^0.7.3" - }, - "exports": { - "./utils/pict": "./dist/utils/pict.js" } } diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 41234c5..460bdee 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -236,3 +236,5 @@ const make = (factors: T, options: OptionsType = {}) => { }; export { make as default, make, makeAsync, sorters, criteria }; + +export { PictConstraintsLexer } from "./utils/pict"; From 197e86bdf6dd005aebdedcf8fd2d35ec192aaac7 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 03:15:04 +0900 Subject: [PATCH 28/79] alpha2 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 616cf62..71d644d 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.0-alpha.1", + "version": "2.3.0-alpha.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.0-alpha.1", + "version": "2.3.0-alpha.2", "license": "ISC", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 1a9d7eb..84c9aee 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.0-alpha.1", + "version": "2.3.0-alpha.2", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From fde798d1f85422da419a869a7e7167cf9976fcc0 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 03:21:12 +0900 Subject: [PATCH 29/79] v2.3.0 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 71d644d..15c6bc7 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.0-alpha.2", + "version": "2.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.0-alpha.2", + "version": "2.3.0", "license": "ISC", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 84c9aee..09bd836 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.0-alpha.2", + "version": "2.3.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { @@ -69,6 +69,8 @@ "typescript": "^3.9.3" }, "dependencies": { - "js-md5": "^0.7.3" + "covertable": "^2.3.0-alpha.2", + "js-md5": "^0.7.3", + "ts-node": "^10.9.2" } } From 5f8434dbcb3865b635fc7955f919c1fea042cadc Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 19:22:33 +0900 Subject: [PATCH 30/79] fix: Remove covertable from dependencies --- typescript/package-lock.json | 272 +++++++++++++++++++++++++++++++++-- typescript/package.json | 1 - 2 files changed, 261 insertions(+), 12 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 15c6bc7..7281719 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -7,9 +7,10 @@ "": { "name": "covertable", "version": "2.3.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "js-md5": "^0.7.3" + "js-md5": "^0.7.3", + "ts-node": "^10.9.2" }, "devDependencies": { "@types/jest": "^25.2.3", @@ -570,6 +571,17 @@ "node": ">=0.1.95" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1186,6 +1198,28 @@ "node": ">= 8.3" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", @@ -1216,6 +1250,26 @@ "node": ">= 6" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, "node_modules/@types/babel__core": { "version": "7.1.12", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", @@ -1321,7 +1375,6 @@ "version": "14.14.31", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", - "dev": true, "license": "MIT" }, "node_modules/@types/normalize-package-data": { @@ -1518,6 +1571,11 @@ "dev": true, "license": "MIT" }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2217,6 +2275,11 @@ "node": ">=0.10.0" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2433,6 +2496,14 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", @@ -6042,7 +6113,6 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, "license": "ISC" }, "node_modules/makeerror": { @@ -8069,6 +8139,70 @@ "node": ">=10" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "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" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -8115,7 +8249,6 @@ "version": "3.9.9", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -8237,6 +8370,11 @@ "uuid": "bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, "node_modules/v8-to-istanbul": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", @@ -8496,6 +8634,14 @@ "engines": { "node": ">=6" } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } } }, "dependencies": { @@ -8932,6 +9078,14 @@ "minimist": "^1.2.0" } }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -9414,6 +9568,25 @@ "chalk": "^3.0.0" } }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@sinonjs/commons": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", @@ -9438,6 +9611,26 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, "@types/babel__core": { "version": "7.1.12", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", @@ -9532,8 +9725,7 @@ "@types/node": { "version": "14.14.31", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", - "dev": true + "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -9672,6 +9864,11 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -10173,6 +10370,11 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -10329,6 +10531,11 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, "diff-sequences": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", @@ -12960,8 +13167,7 @@ "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "makeerror": { "version": "1.0.11", @@ -14457,6 +14663,41 @@ } } }, + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "requires": { + "@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" + }, + "dependencies": { + "acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" + }, + "acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "requires": { + "acorn": "^8.11.0" + } + } + } + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -14490,8 +14731,7 @@ "typescript": { "version": "3.9.9", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", - "dev": true + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" }, "union-value": { "version": "1.0.1", @@ -14575,6 +14815,11 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, "v8-to-istanbul": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", @@ -14772,6 +15017,11 @@ "camelcase": "^5.0.0", "decamelize": "^1.2.0" } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } } diff --git a/typescript/package.json b/typescript/package.json index 09bd836..bff9cf7 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -69,7 +69,6 @@ "typescript": "^3.9.3" }, "dependencies": { - "covertable": "^2.3.0-alpha.2", "js-md5": "^0.7.3", "ts-node": "^10.9.2" } From 47c59da9c8253f297573e5f95723069cc920aebe Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 19:22:51 +0900 Subject: [PATCH 31/79] v2.3.1 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 7281719..fb82d22 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.0", + "version": "2.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.0", + "version": "2.3.1", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3", diff --git a/typescript/package.json b/typescript/package.json index bff9cf7..e80dde6 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.0", + "version": "2.3.1", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From b566e8d4932b14fe3bfaa383ede67e9c707e654b Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 22:39:37 +0900 Subject: [PATCH 32/79] 2.3.2-alpha.0 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- typescript/src/__tests__/index.test.ts | 2 +- typescript/src/criteria/greedy.ts | 2 +- typescript/src/criteria/index.ts | 2 -- typescript/src/criteria/simple.ts | 2 +- typescript/src/index.ts | 32 ++++++++++++++++++-------- typescript/src/{utils.ts => lib.ts} | 4 +++- typescript/src/sorters/hash.ts | 2 +- typescript/src/sorters/index.ts | 3 --- typescript/src/utils/pict.ts | 8 +++++-- 11 files changed, 39 insertions(+), 24 deletions(-) delete mode 100644 typescript/src/criteria/index.ts rename typescript/src/{utils.ts => lib.ts} (97%) delete mode 100644 typescript/src/sorters/index.ts diff --git a/typescript/package-lock.json b/typescript/package-lock.json index fb82d22..b5e8a9e 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.1", + "version": "2.3.2-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.1", + "version": "2.3.2-alpha.0", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3", diff --git a/typescript/package.json b/typescript/package.json index e80dde6..68a59d2 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.1", + "version": "2.3.2-alpha.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { diff --git a/typescript/src/__tests__/index.test.ts b/typescript/src/__tests__/index.test.ts index 6de8151..70e439a 100644 --- a/typescript/src/__tests__/index.test.ts +++ b/typescript/src/__tests__/index.test.ts @@ -1,5 +1,5 @@ import { default as make, sorters, criteria } from '../index'; -import { product, combinations, range, len, all, getItems } from '../utils'; +import { product, combinations, range, len, all, getItems } from '../lib'; import { FactorsType, Scalar, Dict, PairType } from '../types'; const getPairs = function* (factors: FactorsType, length = 2) { diff --git a/typescript/src/criteria/greedy.ts b/typescript/src/criteria/greedy.ts index 688d2cf..36cde63 100644 --- a/typescript/src/criteria/greedy.ts +++ b/typescript/src/criteria/greedy.ts @@ -1,5 +1,5 @@ import {CriterionArgsType, IncompleteType, PairType} from '../types'; -import {getCandidate, combinations, ascOrder, unique} from '../utils'; +import {getCandidate, combinations, ascOrder, unique} from '../lib'; const getNumRemovablePairs = (indexes: Set, incomplete: IncompleteType, length: number) => { let num = 0; diff --git a/typescript/src/criteria/index.ts b/typescript/src/criteria/index.ts deleted file mode 100644 index 76a88d0..0000000 --- a/typescript/src/criteria/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {default as simple} from './simple'; -export {default as greedy} from './greedy'; diff --git a/typescript/src/criteria/simple.ts b/typescript/src/criteria/simple.ts index f42cee6..c9a4b83 100644 --- a/typescript/src/criteria/simple.ts +++ b/typescript/src/criteria/simple.ts @@ -1,5 +1,5 @@ import {CriterionArgsType, IncompleteType, PairType} from '../types'; -import {getCandidate} from '../utils'; +import {getCandidate} from '../lib'; export default function* ( incomplete: IncompleteType, diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 460bdee..be96db5 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -1,6 +1,11 @@ -import * as sorters from "./sorters/index"; -import * as criteria from "./criteria/index"; -import * as exceptions from "./exceptions"; + +import hash from "./sorters/hash"; +import random from "./sorters/random"; + +import greedy from "./criteria/greedy"; +import simple from "./criteria/simple"; + +import {InvalidCondition} from "./exceptions"; import { range, product, @@ -11,7 +16,8 @@ import { ascOrder, primeGenerator, unique, -} from "./utils"; +} from "./lib"; + import { IndicesType, FactorsType, @@ -162,7 +168,7 @@ class Row extends Map implements RowType { } }); if (!this.filled()) { - throw new exceptions.InvalidCondition(); + throw new InvalidCondition(); } return this; } @@ -174,8 +180,8 @@ const makeAsync = function* ( ) { let { length = 2, - sorter = sorters.hash, - criterion = criteria.greedy, + sorter = hash, + criterion = greedy, seed = "", tolerance = 0, } = options; @@ -235,6 +241,14 @@ const make = (factors: T, options: OptionsType = {}) => { return [...makeAsync(factors, options)]; }; -export { make as default, make, makeAsync, sorters, criteria }; +const sorters = { hash, random }; +const criteria = { greedy, simple }; + +export { + make as default, + make, + makeAsync, + sorters, + criteria, +}; -export { PictConstraintsLexer } from "./utils/pict"; diff --git a/typescript/src/utils.ts b/typescript/src/lib.ts similarity index 97% rename from typescript/src/utils.ts rename to typescript/src/lib.ts index 24a904b..aeb5c6c 100644 --- a/typescript/src/utils.ts +++ b/typescript/src/lib.ts @@ -1,6 +1,8 @@ // @ts-ignore 2307 export { hex as md5 } from 'js-md5'; -import { FactorsType, Scalar, ParentsType, CandidateType, PairType } from './types'; +import { + FactorsType, Scalar, ParentsType, CandidateType, PairType, +} from './types'; // https://gist.github.com/righ/71e32be8e33f74bde516c06f80c941e8 diff --git a/typescript/src/sorters/hash.ts b/typescript/src/sorters/hash.ts index 39228e1..dda0b2e 100644 --- a/typescript/src/sorters/hash.ts +++ b/typescript/src/sorters/hash.ts @@ -1,4 +1,4 @@ -import {md5} from '../utils'; +import {md5} from '../lib'; import { PairType, SortArgsType, diff --git a/typescript/src/sorters/index.ts b/typescript/src/sorters/index.ts deleted file mode 100644 index 31e8ed9..0000000 --- a/typescript/src/sorters/index.ts +++ /dev/null @@ -1,3 +0,0 @@ - -export {default as random} from './random'; -export {default as hash} from './hash'; diff --git a/typescript/src/utils/pict.ts b/typescript/src/utils/pict.ts index c9a38f3..603e31a 100644 --- a/typescript/src/utils/pict.ts +++ b/typescript/src/utils/pict.ts @@ -1,5 +1,9 @@ -import { FilterType, FilterRowType } from "../types"; +type FilterRowType = { + [key: string]: any; + [index: number]: any; +} +type FilterType = (row: FilterRowType) => boolean; type Token = { type: string; value: string; @@ -317,7 +321,7 @@ export class PictConstraintsLexer { return new Function('row', code).bind(this) as FilterType; } - filter(row: FilterRowType, ...additionalFilters: FilterType[]): boolean { + filter = (row: FilterRowType, ...additionalFilters: FilterType[]) => { for (const f of this.filters) { if (f == null) { continue; From 9da9250fd7818846bf90cd7bf37a0389694d8d6c Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 7 Aug 2024 22:59:10 +0900 Subject: [PATCH 33/79] 2.3.2-alpha.1 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 8 +++++++- typescript/src/criteria/greedy.ts | 2 +- typescript/src/criteria/simple.ts | 2 +- typescript/src/lib.ts | 2 +- typescript/src/sorters/hash.ts | 2 +- typescript/src/sorters/random.ts | 2 +- typescript/src/utils/pict.ts | 6 +----- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index b5e8a9e..afb65a2 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.2-alpha.0", + "version": "2.3.2-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.2-alpha.0", + "version": "2.3.2-alpha.1", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3", diff --git a/typescript/package.json b/typescript/package.json index 68a59d2..1ae8670 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.2-alpha.0", + "version": "2.3.2-alpha.1", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { @@ -71,5 +71,11 @@ "dependencies": { "js-md5": "^0.7.3", "ts-node": "^10.9.2" + }, + "exports": { + "./utils/pict": { + "import": "./dist/utils/pict.js", + "types": "./dist/utils/pict.d.ts" + } } } diff --git a/typescript/src/criteria/greedy.ts b/typescript/src/criteria/greedy.ts index 36cde63..5dddc4d 100644 --- a/typescript/src/criteria/greedy.ts +++ b/typescript/src/criteria/greedy.ts @@ -1,4 +1,4 @@ -import {CriterionArgsType, IncompleteType, PairType} from '../types'; +import type {CriterionArgsType, IncompleteType, PairType} from '../types'; import {getCandidate, combinations, ascOrder, unique} from '../lib'; const getNumRemovablePairs = (indexes: Set, incomplete: IncompleteType, length: number) => { diff --git a/typescript/src/criteria/simple.ts b/typescript/src/criteria/simple.ts index c9a4b83..5f187fc 100644 --- a/typescript/src/criteria/simple.ts +++ b/typescript/src/criteria/simple.ts @@ -1,4 +1,4 @@ -import {CriterionArgsType, IncompleteType, PairType} from '../types'; +import type {CriterionArgsType, IncompleteType, PairType} from '../types'; import {getCandidate} from '../lib'; export default function* ( diff --git a/typescript/src/lib.ts b/typescript/src/lib.ts index aeb5c6c..2f083c0 100644 --- a/typescript/src/lib.ts +++ b/typescript/src/lib.ts @@ -1,6 +1,6 @@ // @ts-ignore 2307 export { hex as md5 } from 'js-md5'; -import { +import type { FactorsType, Scalar, ParentsType, CandidateType, PairType, } from './types'; diff --git a/typescript/src/sorters/hash.ts b/typescript/src/sorters/hash.ts index dda0b2e..be75f52 100644 --- a/typescript/src/sorters/hash.ts +++ b/typescript/src/sorters/hash.ts @@ -1,5 +1,5 @@ import {md5} from '../lib'; -import { +import type { PairType, SortArgsType, } from '../types'; diff --git a/typescript/src/sorters/random.ts b/typescript/src/sorters/random.ts index 82c17e6..b43c453 100644 --- a/typescript/src/sorters/random.ts +++ b/typescript/src/sorters/random.ts @@ -1,4 +1,4 @@ -import {PairType, SortArgsType} from '../types'; +import type {PairType, SortArgsType} from '../types'; const comparer = (a: any, b: any) => { return Math.random() > 0.5 ? 1 : -1; diff --git a/typescript/src/utils/pict.ts b/typescript/src/utils/pict.ts index 603e31a..661806d 100644 --- a/typescript/src/utils/pict.ts +++ b/typescript/src/utils/pict.ts @@ -1,9 +1,5 @@ -type FilterRowType = { - [key: string]: any; - [index: number]: any; -} +import type { FilterRowType, FilterType } from '../types'; -type FilterType = (row: FilterRowType) => boolean; type Token = { type: string; value: string; From f60e1e894f3be17953cd8b4942919ebb61b157fb Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 8 Aug 2024 01:15:02 +0900 Subject: [PATCH 34/79] webpack --- typescript/package-lock.json | 1973 ++++++++++++++++++++++++++++++++-- typescript/package.json | 21 +- typescript/src/index.ts | 5 +- typescript/tsconfig.json | 6 +- typescript/webpack.config.js | 23 + 5 files changed, 1911 insertions(+), 117 deletions(-) create mode 100644 typescript/webpack.config.js diff --git a/typescript/package-lock.json b/typescript/package-lock.json index afb65a2..d394bb6 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,16 +1,15 @@ { "name": "covertable", - "version": "2.3.2-alpha.1", + "version": "2.3.2-alpha.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.2-alpha.1", + "version": "2.3.2-alpha.3", "license": "Apache-2.0", "dependencies": { - "js-md5": "^0.7.3", - "ts-node": "^10.9.2" + "js-md5": "^0.7.3" }, "devDependencies": { "@types/jest": "^25.2.3", @@ -20,7 +19,11 @@ "jest": "^26.0.1", "nyc": "^15.1.0", "ts-jest": "^26.1.0", - "typescript": "^3.9.3" + "ts-loader": "^9.5.1", + "ts-node": "^10.9.2", + "typescript": "^4.9.3", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4" } }, "node_modules/@babel/code-frame": { @@ -575,6 +578,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -582,6 +586,15 @@ "node": ">=12" } }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1198,23 +1211,79 @@ "node": ">= 8.3" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1253,22 +1322,26 @@ "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true }, "node_modules/@types/babel__core": { "version": "7.1.12", @@ -1315,6 +1388,32 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/eslint": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", + "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -1371,10 +1470,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/node": { "version": "14.14.31", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", + "dev": true, "license": "MIT" }, "node_modules/@types/normalize-package-data": { @@ -1415,6 +1521,208 @@ "dev": true, "license": "MIT" }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -1483,6 +1791,31 @@ "node": ">=8" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", @@ -1574,7 +1907,8 @@ "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "1.0.10", @@ -1917,9 +2251,9 @@ "license": "BSD-2-Clause" }, "node_modules/browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -1929,14 +2263,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2033,9 +2370,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001331", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001331.tgz", - "integrity": "sha512-Y1xk6paHpUXKP/P6YjQv1xqyTbgAP05ycHBcRdQjTcyXlWol868sJJPlmk5ylOekw2BrucWes5jk+LvVd7WZ5Q==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true, "funding": [ { @@ -2045,6 +2382,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -2085,6 +2426,15 @@ "node": ">=10" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -2150,6 +2500,20 @@ "wrap-ansi": "^6.2.0" } }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2222,6 +2586,12 @@ "dev": true, "license": "MIT" }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2234,6 +2604,12 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2278,7 +2654,8 @@ "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/cross-spawn": { "version": "6.0.5", @@ -2500,6 +2877,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, "engines": { "node": ">=0.3.1" } @@ -2538,9 +2916,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.107", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz", - "integrity": "sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", + "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", "dev": true }, "node_modules/emittery": { @@ -2573,6 +2951,31 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2583,6 +2986,12 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -2591,11 +3000,10 @@ "license": "MIT" }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -2632,6 +3040,28 @@ "source-map": "~0.6.1" } }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -2646,6 +3076,18 @@ "node": ">=4" } }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", @@ -2664,6 +3106,15 @@ "node": ">=0.10.0" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/exec-sh": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", @@ -2947,6 +3398,12 @@ "node": ">=0.10.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2960,6 +3417,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -3015,6 +3481,15 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -3253,6 +3728,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -3264,11 +3745,10 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true, - "license": "ISC" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "node_modules/growly": { "version": "1.3.0", @@ -3549,6 +4029,15 @@ "dev": true, "license": "ISC" }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -5987,6 +6476,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -6053,6 +6548,15 @@ "dev": true, "license": "MIT" }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -6113,6 +6617,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, "license": "ISC" }, "node_modules/makeerror": { @@ -6296,6 +6801,12 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -6437,9 +6948,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.3.tgz", - "integrity": "sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node_modules/normalize-package-data": { @@ -6810,9 +7321,9 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -6943,9 +7454,18 @@ "node": ">=6" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true, "license": "MIT" @@ -6994,6 +7514,18 @@ "node": ">=8" } }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, "node_modules/regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -7360,6 +7892,24 @@ "node": ">=10" } }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -7370,6 +7920,15 @@ "semver": "bin/semver.js" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -7406,6 +7965,18 @@ "node": ">=0.10.0" } }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -7654,11 +8225,10 @@ } }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -7934,6 +8504,15 @@ "dev": true, "license": "MIT" }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/teeny-request": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz", @@ -7965,6 +8544,109 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/terser": { + "version": "5.31.5", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz", + "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -8139,10 +8821,68 @@ "node": ">=10" } }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -8185,6 +8925,7 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -8196,6 +8937,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, "dependencies": { "acorn": "^8.11.0" }, @@ -8246,10 +8988,10 @@ } }, "node_modules/typescript": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", - "license": "Apache-2.0", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8335,6 +9077,45 @@ "node": ">=0.10.0" } }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -8373,7 +9154,8 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "node_modules/v8-to-istanbul": { "version": "7.1.0", @@ -8444,6 +9226,19 @@ "makeerror": "1.0.x" } }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -8454,6 +9249,210 @@ "node": ">=10.4" } }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-cli/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/webpack-cli/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-cli/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-cli/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-cli/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -8505,6 +9504,12 @@ "dev": true, "license": "ISC" }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -8639,6 +9644,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, "engines": { "node": ">=6" } @@ -9082,10 +10088,17 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" } }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -9568,20 +10581,74 @@ "chalk": "^3.0.0" } }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + } + } + }, "@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + } + } }, "@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -9614,22 +10681,26 @@ "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true }, "@types/babel__core": { "version": "7.1.12", @@ -9672,6 +10743,32 @@ "@babel/types": "^7.3.0" } }, + "@types/eslint": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", + "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -9722,10 +10819,17 @@ "integrity": "sha512-FUPoQkpQTzA5wz9ebrdVRjsjQsFehr+cW1CVhLcI2UwD/SO/4NHPO1esrXPPbx7ux762U0POmWFSrUjQq2ophw==", "dev": true }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "@types/node": { "version": "14.14.31", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" + "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", + "dev": true }, "@types/normalize-package-data": { "version": "2.4.0", @@ -9754,10 +10858,189 @@ "@types/yargs-parser": "*" } }, - "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "requires": {} + }, + "@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, "abab": { @@ -9807,6 +11090,25 @@ "indent-string": "^4.0.0" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", @@ -9867,7 +11169,8 @@ "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "argparse": { "version": "1.0.10", @@ -10118,16 +11421,15 @@ "dev": true }, "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" } }, "bs-logger": { @@ -10196,9 +11498,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001331", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001331.tgz", - "integrity": "sha512-Y1xk6paHpUXKP/P6YjQv1xqyTbgAP05ycHBcRdQjTcyXlWol868sJJPlmk5ylOekw2BrucWes5jk+LvVd7WZ5Q==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true }, "capture-exit": { @@ -10226,6 +11528,12 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -10278,6 +11586,17 @@ "wrap-ansi": "^6.2.0" } }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -10328,6 +11647,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -10337,6 +11662,12 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -10373,7 +11704,8 @@ "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "cross-spawn": { "version": "6.0.5", @@ -10534,7 +11866,8 @@ "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true }, "diff-sequences": { "version": "25.2.6", @@ -10560,9 +11893,9 @@ } }, "electron-to-chromium": { - "version": "1.4.107", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz", - "integrity": "sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", + "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", "dev": true }, "emittery": { @@ -10586,6 +11919,22 @@ "once": "^1.4.0" } }, + "enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -10595,6 +11944,12 @@ "is-arrayish": "^0.2.1" } }, + "es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -10602,9 +11957,9 @@ "dev": true }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "escape-string-regexp": { @@ -10626,12 +11981,39 @@ "source-map": "~0.6.1" } }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", @@ -10644,6 +12026,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, "exec-sh": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", @@ -10861,6 +12249,12 @@ } } }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -10873,6 +12267,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -10912,6 +12312,12 @@ "path-exists": "^4.0.0" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -11063,6 +12469,12 @@ "path-is-absolute": "^1.0.0" } }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -11070,9 +12482,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "growly": { @@ -11279,6 +12691,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -13082,6 +14500,12 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -13125,6 +14549,12 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -13167,7 +14597,8 @@ "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "makeerror": { "version": "1.0.11", @@ -13303,6 +14734,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -13408,9 +14845,9 @@ } }, "node-releases": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.3.tgz", - "integrity": "sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "normalize-package-data": { @@ -13676,9 +15113,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "picomatch": { @@ -13770,6 +15207,15 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -13807,6 +15253,15 @@ "type-fest": "^0.8.1" } }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "requires": { + "resolve": "^1.20.0" + } + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -14079,12 +15534,32 @@ "xmlchars": "^2.2.0" } }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -14114,6 +15589,15 @@ } } }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -14302,9 +15786,9 @@ } }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -14515,6 +15999,12 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, "teeny-request": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz", @@ -14538,6 +16028,71 @@ "supports-hyperlinks": "^2.0.0" } }, + "terser": { + "version": "5.31.5", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz", + "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -14663,10 +16218,48 @@ } } }, + "ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + } + } + }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -14686,12 +16279,14 @@ "acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true }, "acorn-walk": { "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, "requires": { "acorn": "^8.11.0" } @@ -14729,9 +16324,10 @@ } }, "typescript": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true }, "union-value": { "version": "1.0.1", @@ -14791,6 +16387,25 @@ } } }, + "update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -14818,7 +16433,8 @@ "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "v8-to-istanbul": { "version": "7.1.0", @@ -14876,12 +16492,156 @@ "makeerror": "1.0.x" } }, + "watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "dev": true }, + "webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true + }, + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "requires": {} + } + } + }, + "webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true + }, "whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -14923,6 +16683,12 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -15021,7 +16787,8 @@ "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/typescript/package.json b/typescript/package.json index 1ae8670..b1bbddd 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.2-alpha.1", + "version": "2.3.2-alpha.3", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { @@ -36,8 +36,8 @@ "main": "dist/index.js", "scripts": { "test": "jest", - "build": "$(npm bin)/tsc", - "watch": "$(npm bin)/tsc -w", + "build": "rm -rf dist/ && $(npm bin)/webpack", + "watch": "$(npm bin)/webpack --watch", "codecov": "$(npm bin)/codecov" }, "jest": { @@ -66,16 +66,13 @@ "jest": "^26.0.1", "nyc": "^15.1.0", "ts-jest": "^26.1.0", - "typescript": "^3.9.3" + "ts-loader": "^9.5.1", + "ts-node": "^10.9.2", + "typescript": "^4.9.3", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4" }, "dependencies": { - "js-md5": "^0.7.3", - "ts-node": "^10.9.2" - }, - "exports": { - "./utils/pict": { - "import": "./dist/utils/pict.js", - "types": "./dist/utils/pict.d.ts" - } + "js-md5": "^0.7.3" } } diff --git a/typescript/src/index.ts b/typescript/src/index.ts index be96db5..68862a0 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -5,6 +5,8 @@ import random from "./sorters/random"; import greedy from "./criteria/greedy"; import simple from "./criteria/simple"; +import {PictConstraintsLexer} from "./utils/pict"; + import {InvalidCondition} from "./exceptions"; import { range, @@ -245,10 +247,11 @@ const sorters = { hash, random }; const criteria = { greedy, simple }; export { - make as default, make, makeAsync, sorters, criteria, + PictConstraintsLexer, }; +export default make; diff --git a/typescript/tsconfig.json b/typescript/tsconfig.json index 8bf419f..0707532 100644 --- a/typescript/tsconfig.json +++ b/typescript/tsconfig.json @@ -46,7 +46,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ @@ -59,5 +59,9 @@ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "baseUrl": ".", + "paths": { + "covertable/utils/pict": ["./dist/utils/pict"] + } } } diff --git a/typescript/webpack.config.js b/typescript/webpack.config.js new file mode 100644 index 0000000..2d4cf5f --- /dev/null +++ b/typescript/webpack.config.js @@ -0,0 +1,23 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.ts$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + libraryTarget: 'umd', + }, + target: 'node', +}; From 2bdab409820117620443a2e04f97da8c4e3b6f55 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 21 Aug 2024 22:07:23 +0900 Subject: [PATCH 35/79] 2.3.2-alpha.4 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index d394bb6..01e3b63 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.2-alpha.3", + "version": "2.3.2-alpha.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.2-alpha.3", + "version": "2.3.2-alpha.4", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index b1bbddd..0d24d3a 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.2-alpha.3", + "version": "2.3.2-alpha.4", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From 7cf71ac0cbd497a5a14caab2df3d695de458227e Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 22 Aug 2024 00:51:43 +0900 Subject: [PATCH 36/79] fix: set default true --- typescript/src/utils/pict.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/typescript/src/utils/pict.ts b/typescript/src/utils/pict.ts index 661806d..ca1cf50 100644 --- a/typescript/src/utils/pict.ts +++ b/typescript/src/utils/pict.ts @@ -174,6 +174,8 @@ export class PictConstraintsLexer { return 'false'; } return `(${expr})`; + } else if (token && token.type === 'BOOLEAN') { + return token.value.toUpperCase() === 'TRUE' ? 'true' : 'false'; } else { tokenIndex--; // Go back one token return parseCondition(); @@ -278,19 +280,19 @@ export class PictConstraintsLexer { errorMessages.push('Expected THEN'); break; } - const action = parseExpression(); - let elseAction = 'false'; + const thenAction = parseExpression(); + const elseToken = nextToken(); + let elseAction = 'true'; if (elseToken && elseToken.type === 'ELSE') { elseAction = parseExpression(); } else { tokenIndex--; // Go back one token if ELSE is not found } - - const filterCode = `return (${condition} ? (${action}) : (${elseAction}));`; + const filterCode = `return (${condition} ? (${thenAction}) : (${elseAction}));`; try { if (this.debug) { - console.log(`code[${filters.length}]:`, filterCode); + console.debug(`code[${filters.length}]:`, filterCode); } const f = this.makeClosure(filterCode); filters.push(f as FilterType); From 84f670da8229d4201271622e6bc2ffc9718207ff Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 22 Aug 2024 00:52:16 +0900 Subject: [PATCH 37/79] 2.3.2-alpha.5 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 01e3b63..a20f25e 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.2-alpha.4", + "version": "2.3.2-alpha.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.2-alpha.4", + "version": "2.3.2-alpha.5", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 0d24d3a..c08a825 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.2-alpha.4", + "version": "2.3.2-alpha.5", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From 014aa00f6588cb2f837226bea75f20ed8b4c3339 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 25 Aug 2024 01:24:05 +0900 Subject: [PATCH 38/79] fix: conditions for application of prefilter --- typescript/src/__tests__/filter.test.ts | 62 ++++++ typescript/src/__tests__/index.test.ts | 17 -- typescript/src/controller.ts | 277 ++++++++++++++++++++++++ typescript/src/criteria/greedy.ts | 32 +-- typescript/src/criteria/simple.ts | 14 +- typescript/src/exceptions.ts | 11 +- typescript/src/index.ts | 246 +++------------------ typescript/src/lib.ts | 14 ++ typescript/src/types.ts | 44 ++-- 9 files changed, 427 insertions(+), 290 deletions(-) create mode 100644 typescript/src/__tests__/filter.test.ts create mode 100644 typescript/src/controller.ts diff --git a/typescript/src/__tests__/filter.test.ts b/typescript/src/__tests__/filter.test.ts new file mode 100644 index 0000000..7354042 --- /dev/null +++ b/typescript/src/__tests__/filter.test.ts @@ -0,0 +1,62 @@ +import { Dict, SuggestRowType } from "../types"; +import { make, makeAsync, sorters, criteria } from "../index"; + +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; + +test('exclude impossible combinations', () => { + const factors = {machine, os, browser}; + const preFilter = (row: Dict) => { + return !( + (row.machine === 'iPhone' && row.os !== 'iOS') || + (row.machine !== 'iPhone' && row.os === 'iOS') + ); + }; + const rows = make(factors, { preFilter }); + expect(rows.filter(row => row.machine === 'iPhone' && row.os === 'iOS').length).toBe(browser.length); + expect(rows.filter(row => row.machine === 'iPhone' && row.os !== 'iOS').length).toBe(0); + expect(rows.filter(row => row.machine !== 'iPhone' && row.os === 'iOS').length).toBe(0); + + expect(rows.filter(row => row.machine === 'Pixel' && row.os === 'Android').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'XPERIA' && row.os === 'Android').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'ZenFone' && row.os === 'Android').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'Galaxy' && row.os === 'Android').length).toBeGreaterThanOrEqual(1); + + expect(rows.filter(row => row.machine === 'iPhone' && row.browser === 'FireFox').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'iPhone' && row.browser === 'Chrome').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'iPhone' && row.browser === 'Safari').length).toBeGreaterThanOrEqual(1); + + expect(rows.filter(row => row.machine === 'Pixel' && row.browser === 'FireFox').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'Pixel' && row.browser === 'Chrome').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.machine === 'Pixel' && row.browser === 'Safari').length).toBeGreaterThanOrEqual(1); + + expect(rows.filter(row => row.os === 'iOS' && row.browser === 'FireFox').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.os === 'iOS' && row.browser === 'Chrome').length).toBeGreaterThanOrEqual(1); + expect(rows.filter(row => row.os === 'iOS' && row.browser === 'Safari').length).toBeGreaterThanOrEqual(1); +}); + +test('Limited to iphone and iOS combinations only.', () => { + const factors = {machine, os, browser}; + const preFilter = (row: SuggestRowType) => row.machine === 'iPhone' && row.os === 'iOS'; + const rows = make(factors, { preFilter }); + expect(rows.length).toBe(browser.length); + expect(rows.filter(row => row.machine === 'iPhone' && row.os === 'iOS').length).toBe(browser.length); + expect(rows.filter(row => row.machine === 'Pixel').length).toBe(0); + expect(rows.filter(row => row.os == 'Android').length).toBe(0); +}); + + +test('Use a constant-false function for preFilter', () => { + const factors = {machine, os, browser}; + const preFilter = (row: Dict) => false; + const rows = make(factors, { preFilter }); + expect(rows).toEqual([]); +}); + +test('Use the wrong conditional function for preFilter', () => { + const factors = {machine, os, browser}; + const preFilter = (row: Dict) => row.machine === 'WindowsPhone'; + const rows = make(factors, { preFilter }); + expect(rows).toEqual([]); +}); diff --git a/typescript/src/__tests__/index.test.ts b/typescript/src/__tests__/index.test.ts index 70e439a..904ab6f 100644 --- a/typescript/src/__tests__/index.test.ts +++ b/typescript/src/__tests__/index.test.ts @@ -89,23 +89,6 @@ test('prefilter excludes specified pairs before', () => { } }); -test('never matching prefilter throws an exception', () => { - const factors = [ - ["a", "b", "c"], - ["d", "e"], - ["f"], - ]; - const preFilter = (row: Dict) => { - if (row[2] === "f") { - return false; - } - return true; - } - expect(() => { - make(factors, { preFilter }) - }).toThrow(); -}); - test("greedy sorter should make rows less than seed's one with 2", () => { const factors = [ ["a", "b", "c"], diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts new file mode 100644 index 0000000..dc7c071 --- /dev/null +++ b/typescript/src/controller.ts @@ -0,0 +1,277 @@ + +import hash from "./sorters/hash"; +import { + range, + product, + combinations, + len, + getItems, + getCandidate, + ascOrder, + primeGenerator, + unique, + proxyHandler, +} from "./lib"; + +import { + IndicesType, + FactorsType, + SerialsType, + Scalar, + Dict, + PairByKey, + ParentsType, + CandidateType, + RowType, + OptionsType, + PairType, + SuggestRowType, +} from "./types"; +import { NeverMatch, NotReady } from "./exceptions"; + +export class Row extends Map implements RowType { + // index: number + public consumed: PairByKey = new Map(); + + constructor(row: CandidateType) { + super(); + for (const [k, v] of row) { + this.set(k, v); + } + } + getPairKey(...newPair: number[]) { + const pair = [...this.values(), ...newPair]; + return unique(pair); + } + copy(row: Row) { + for (let [k, v] of row.entries()) { + this.set(k, v); + } + } +} + +export class Controller { + public factorLength: number; + public factorIsArray: Boolean; + + private serials: SerialsType = new Map(); + private parents: ParentsType = new Map(); + private indices: IndicesType = new Map(); + public incomplete: PairByKey = new Map(); + + private rejected: Set = new Set(); + public row: Row; + + constructor(public factors: FactorsType, public options: OptionsType) { + this.serialize(factors); + this.setIncomplete(); + this.row = new Row([]); + this.factorLength = len(factors); + this.factorIsArray = factors instanceof Array; + + // Delete initial pairs that do not satisfy preFilter + for (const [pairKey, pair] of this.incomplete.entries()) { + const cand = this.getCandidate(pair); + const storable = this.storable(cand); + if (storable == null) { + this.incomplete.delete(pairKey); + } + } + } + + private serialize(factors: FactorsType) { + let origin = 0; + const primer = primeGenerator(); + getItems(factors).map(([subscript, elements]) => { + const lenElements = len(elements); + const serialList: number[] = []; + range(origin, origin + lenElements).map((index) => { + const serial = primer.next().value; + serialList.push(serial); + this.parents.set(serial, subscript); + this.indices.set(serial, index); + }); + this.serials.set(subscript, serialList); + origin += lenElements; + }); + }; + + private setIncomplete() { + const { sorter = hash, seed = "" } = this.options; + const pairs: PairType[] = []; + const allKeys = getItems(this.serials).map(([k, _]) => k); + for (const keys of combinations(allKeys, this.pairwiseCount)) { + const comb = range(0, this.pairwiseCount).map((i) => this.serials.get(keys[i]) as PairType); + for (let pair of product(...comb)) { + pair = pair.sort(ascOrder); + pairs.push(pair); + } + } + for (let pair of sorter(pairs, { seed, indices: this.indices })) { + this.incomplete.set(unique(pair), pair); + } + } + + setPair(pair: PairType) { + for (let [key, value] of this.getCandidate(pair)) { + this.row.set(key, value); + } + //this.consume(pair); + for (let p of combinations([...this.row.values()], this.pairwiseCount)) { + this.consume(p); + } + } + + consume(pair: PairType) { + const pairKey = unique(pair); + const deleted = this.incomplete.delete(pairKey); + if (deleted) { + this.row.consumed.set(pairKey, pair); + } + } + + getCandidate(pair: PairType) { + return getCandidate(pair, this.parents); + } + + // Returns a negative value if it is unknown if it can be stored. + storable(candidate: CandidateType) { + let num = 0; + for (let [key, el] of candidate) { + let existing: number | undefined = this.row.get(key); + if (typeof existing === "undefined") { + num++; + } else if (existing != el) { + return null; + } + } + if (!this.options.preFilter) { + return num; + } + const candidates: CandidateType = [...this.row.entries()].concat(candidate); + const nxt = new Row(candidates); + const proxy = this.toProxy(nxt); + try { + const ok = this.options.preFilter(proxy); + if (!ok) { + return null; + } + } catch (e) { + if (e instanceof NotReady) { + return -num; + } + throw e + } + return num; + } + + isFilled(row: Row): boolean { + return row.size === this.factorLength; + } + + toMap(row: Row): Map { + const result: Map = new Map(); + for (let [key, serial] of row.entries()) { + const index = this.indices.get(serial) as number; + const first = this.indices.get((this.serials.get(key) as PairType)[0]); + // @ts-ignore TS7015 + result.set(key, this.factors[key][index - first]); + } + return result; + } + + toProxy(row: Row) { + const obj: Dict = {}; + for (let [key, value] of this.toMap(row).entries()) { + obj[key] = value; + } + return new Proxy(obj, proxyHandler) as SuggestRowType; + } + + toObject(row: Row) { + const obj: Dict = {}; + for (let [key, value] of this.toMap(row).entries()) { + obj[key] = value; + } + return obj as SuggestRowType; + } + + reset() { + this.row.consumed.forEach((pair, pairKey) => { + this.incomplete.set(pairKey, pair); + }); + this.row = new Row([]); + } + + discard() { + this.rejected.add(this.row.getPairKey()); + this.row = new Row([]); + } + + restore() { + const row = this.row; + this.row = new Row([]); + if (this.factorIsArray) { + const map = this.toMap(row); + return getItems(map) + .sort((a, b) => (a[0] > b[0] ? 1 : -1)) + .map(([_, v]) => v); + } + return this.toObject(row); + } + + close() { + const trier = new Row([...this.row.entries()]); + const kvs = getItems(this.serials); + for (let [k, vs] of kvs) { + for (let v of vs) { + const pairKey = trier.getPairKey(v); + if (this.rejected.has(pairKey)) { + continue; + } + const cand: CandidateType = [[k, v]]; + const storable = this.storable(cand); + if (storable == null) { + this.rejected.add(pairKey); + continue; + } + trier.set(k, v); + break; + } + } + this.row.copy(trier); + if (this.isComplete) { + return true; + } + if (trier.size === 0) { + return false; + } + const pairKey = trier.getPairKey(); + if (this.rejected.has(pairKey)) { + throw new NeverMatch(); + } + this.rejected.add(pairKey); + this.reset(); + return false; + } + + get pairwiseCount() { + return this.options.length || 2; + } + + get isComplete() { + const filled = this.isFilled(this.row); + if (!filled) { + return false; + } + const proxy = this.toProxy(this.row); + try { + return this.options.preFilter ? this.options.preFilter(proxy) : true; + } catch (e) { + if (e instanceof NotReady) { + return false; + } + throw e; + } + } +} diff --git a/typescript/src/criteria/greedy.ts b/typescript/src/criteria/greedy.ts index 5dddc4d..b5529c0 100644 --- a/typescript/src/criteria/greedy.ts +++ b/typescript/src/criteria/greedy.ts @@ -1,7 +1,8 @@ -import type {CriterionArgsType, IncompleteType, PairType} from '../types'; -import {getCandidate, combinations, ascOrder, unique} from '../lib'; +import type {FactorsType, PairByKey, PairType} from '../types'; +import { combinations, unique } from '../lib'; +import { Controller } from '../controller'; -const getNumRemovablePairs = (indexes: Set, incomplete: IncompleteType, length: number) => { +const getNumRemovablePairs = (indexes: Set, incomplete: PairByKey, length: number) => { let num = 0; const removingKeys = combinations([... indexes], length); for (let pair of removingKeys) { @@ -13,41 +14,40 @@ const getNumRemovablePairs = (indexes: Set, incomplete: IncompleteType, return num; }; -export default function* ( - incomplete: IncompleteType, - criterionArgs: CriterionArgsType, -): Generator { - let {row, parents, length, tolerance} = criterionArgs; - +export default function* (ctrl: Controller): Generator { while (true) { let maxNumPairs: number | null = null; let efficientPair: PairType | null = null; - for (let [pairKey, pair] of incomplete.entries()) { - const rowSize = row.size; + for (const [pairKey, pair] of ctrl.incomplete.entries()) { + const rowSize = ctrl.row.size; if (rowSize === 0) { yield pair; continue; } - if (row.filled()) { + if (ctrl.isFilled(ctrl.row)) { break; } - const storable = row.storable(getCandidate(pair, parents)); + const storable = ctrl.storable(ctrl.getCandidate(pair)); if (storable === null) { continue; } if (storable === 0) { - incomplete.delete(pairKey); + ctrl.consume(pair); continue; } + const storableAbs = Math.abs(storable); + const { tolerance = 0 } = ctrl.options!; const numPairs = getNumRemovablePairs( - new Set([... row.values(), ...pair]), incomplete, length + new Set([...ctrl.row.values(), ...pair]), + ctrl.incomplete, + ctrl.pairwiseCount, ); - if (numPairs + tolerance > rowSize * storable) { + if (numPairs + tolerance > rowSize * storableAbs) { efficientPair = pair; break; } diff --git a/typescript/src/criteria/simple.ts b/typescript/src/criteria/simple.ts index 5f187fc..e3000d6 100644 --- a/typescript/src/criteria/simple.ts +++ b/typescript/src/criteria/simple.ts @@ -1,13 +1,11 @@ -import type {CriterionArgsType, IncompleteType, PairType} from '../types'; -import {getCandidate} from '../lib'; +import type {FactorsType, PairType} from '../types'; +import { Controller } from '../controller'; -export default function* ( - incomplete: IncompleteType, - criterionArgs: CriterionArgsType, -): Generator { - const {row, parents} = criterionArgs; +export default function* (ctrl: Controller): Generator { + const incomplete = ctrl.incomplete; for (let pair of incomplete.values()) { - const storable = row.storable(getCandidate(pair, parents)); + const cand = ctrl.getCandidate(pair); + const storable = ctrl.storable(cand); if (storable === null || storable === 0) { continue; } diff --git a/typescript/src/exceptions.ts b/typescript/src/exceptions.ts index ca6e51e..9450bac 100644 --- a/typescript/src/exceptions.ts +++ b/typescript/src/exceptions.ts @@ -1,5 +1,10 @@ +import { Scalar } from "./types"; -export class InvalidCondition { - public name = 'InvalidCondition'; - public message = 'It will never meet the condition'; +export class NotReady extends Error { + constructor(public key: Scalar) { + super(`Not yet '${key}' in the object`); + } +} + +export class NeverMatch extends Error { }; diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 68862a0..f3be2af 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -6,240 +6,46 @@ import greedy from "./criteria/greedy"; import simple from "./criteria/simple"; import {PictConstraintsLexer} from "./utils/pict"; - -import {InvalidCondition} from "./exceptions"; -import { - range, - product, - combinations, - len, - getItems, - getCandidate, - ascOrder, - primeGenerator, - unique, -} from "./lib"; - -import { - IndicesType, - FactorsType, - SerialsType, - MappingTypes, - Scalar, - Dict, - IncompleteType, - ParentsType, - CandidateType, - RowType, - OptionsType, - FilterType, - PairType, - SorterType, - SuggestRowType, -} from "./types"; - -const serialize = (factors: FactorsType): MappingTypes => { - let origin = 0; - const serials: SerialsType = new Map(); - const indices: IndicesType = new Map(); - const parents: ParentsType = new Map(); - - const primer = primeGenerator(); - getItems(factors).map(([subscript, factorList]) => { - const length = len(factorList); - const serialList: number[] = []; - range(origin, origin + length).map((index) => { - const serial = primer.next().value; - serialList.push(serial); - parents.set(serial, subscript); - indices.set(serial, index); - }); - serials.set(subscript, serialList); - origin += length; - }); - return { serials, parents, indices }; -}; - -const makeIncomplete = ( - mappings: MappingTypes, - length: number, - sorter: SorterType, - seed: Scalar -): IncompleteType => { - const { serials, indices } = mappings; - const pairs: PairType[] = []; - const allKeys = getItems(serials).map(([k, _]) => k); - for (const keys of combinations(allKeys, length)) { - const comb = range(0, length).map((i) => serials.get(keys[i]) as PairType); - for (let pair of product(...comb)) { - pair = pair.sort(ascOrder); - pairs.push(pair); - } - } - const incomplete: IncompleteType = new Map(); - for (let pair of sorter(pairs, { seed, indices })) { - incomplete.set(unique(pair), pair); - } - return incomplete; -}; - -class Row extends Map implements RowType { - // index: number - private length: number; - public isArray: Boolean; - constructor( - row: CandidateType, - private mappings: MappingTypes, - private factors: FactorsType, - public preFilter?: FilterType - ) { - super(); - for (const [k, v] of row) { - this.set(k, v); - } - this.length = len(factors); - this.isArray = factors instanceof Array; - } - - filled(): boolean { - return this.size === this.length; - } - - New(row?: CandidateType) { - return new Row(row || [], this.mappings, this.factors, this.preFilter); - } - - storable(candidate: CandidateType) { - let num = 0; - for (let [key, el] of candidate) { - let existing: number | undefined = this.get(key); - if (typeof existing === "undefined") { - num++; - } else if (existing != el) { - return null; - } - } - if (!this.preFilter) { - return num; - } - const candidates: CandidateType = [...this.entries()].concat(candidate); - const nxt: Row = this.New(candidates); - if (!this.preFilter(nxt.toObject())) { - return null; - } - return num; - } - - toMap(): Map { - const result: Map = new Map(); - const { indices, serials } = this.mappings; - for (let [key, serial] of this.entries()) { - const index = indices.get(serial) as number; - const first = indices.get((serials.get(key) as PairType)[0]); - // @ts-ignore TS7015 - result.set(key, this.factors[key][index - first]); - } - return result; - } - - toObject() { - const obj: Dict = {}; - for (let [key, value] of this.toMap().entries()) { - obj[key] = value; - } - return obj; - } - - restore() { - if (this.isArray) { - const map = this.toMap(); - return getItems(map) - .sort((a, b) => (a[0] > b[0] ? 1 : -1)) - .map(([_, v]) => v); - } - return this.toObject(); - } - - complement(): Row { - getItems(this.mappings.serials).map(([k, vs]) => { - for (let v of vs) { - if (this.storable([[k, v]])) { - this.set(k, v); - break; - } - } - }); - if (!this.filled()) { - throw new InvalidCondition(); - } - return this; - } -} +import { FactorsType, OptionsType, SuggestRowType } from "./types"; +import { Controller } from "./controller"; +import { NeverMatch } from "./exceptions"; const makeAsync = function* ( factors: T, - options: OptionsType = {} + options: OptionsType = {} ) { - let { - length = 2, - sorter = hash, + const { criterion = greedy, - seed = "", - tolerance = 0, + postFilter, } = options; - const { preFilter, postFilter } = options; - const mappings = serialize(factors); - const { parents } = mappings; - const incomplete = makeIncomplete(mappings, length, sorter, seed); // {"1,2": [1,2], "3,4": [3,4]} - - let row: Row = new Row([], mappings, factors, preFilter); - - for (let [pairKey, pair] of incomplete.entries()) { - if (!row.storable(getCandidate(pair, parents))) { - incomplete.delete(pairKey); - } - } - while (incomplete.size) { - if (row.filled()) { - if (!postFilter || postFilter(row.toObject())) { - yield row.restore() as SuggestRowType; - } - row = row.New([]); - } - let finished = true; - for (let pair of criterion(incomplete, { - row, - parents, - length, - tolerance, - })) { - if (row.filled()) { - finished = false; + const ctrl = new Controller(factors, options); + do { + for (let pair of criterion(ctrl)) { + if (ctrl.isFilled(ctrl.row)) { break; } - - for (let [key, value] of getCandidate(pair, parents)) { - row.set(key, value); + ctrl.setPair(pair); + } + try { + const complete = ctrl.close(); + if (complete) { + if (!postFilter || postFilter(ctrl.toObject(ctrl.row))) { + yield ctrl.restore() as SuggestRowType; + } else { + ctrl.discard(); + } } - - for (let p of combinations([...row.values()], length)) { - incomplete.delete(unique(p)); + } catch (e) { + if (e instanceof NeverMatch) { + break; } + throw e; } - if (finished && !row.filled()) { - row.complement(); - } - } - if (row.size) { - row = row.complement(); - if (!postFilter || postFilter(row.toObject())) { - yield row.restore() as SuggestRowType; - } - } + } while (ctrl.incomplete.size); }; -const make = (factors: T, options: OptionsType = {}) => { +const make = (factors: T, options: OptionsType = {}) => { return [...makeAsync(factors, options)]; }; diff --git a/typescript/src/lib.ts b/typescript/src/lib.ts index 2f083c0..cd9d0cc 100644 --- a/typescript/src/lib.ts +++ b/typescript/src/lib.ts @@ -1,7 +1,9 @@ // @ts-ignore 2307 export { hex as md5 } from 'js-md5'; +import { NotReady } from './exceptions'; import type { FactorsType, Scalar, ParentsType, CandidateType, PairType, + Dict, } from './types'; // https://gist.github.com/righ/71e32be8e33f74bde516c06f80c941e8 @@ -125,3 +127,15 @@ export function* primeGenerator(): Generator { } } } + + + +export const proxyHandler = { + get(obj: Dict, key: string, receiver: any) { + if (key in obj) { + return obj[key]; + } + throw new NotReady(key); + }, +}; + diff --git a/typescript/src/types.ts b/typescript/src/types.ts index 340da9a..c5058b6 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -1,3 +1,5 @@ +import type { Controller } from "./controller"; + export type Scalar = number | string; export type Dict = { [s: string]: any }; export type List = { [index: number]: any[] }; @@ -6,32 +8,31 @@ export type SerialsType = Map; export type ParentsType = Map; export type IndicesType = Map; -export type MappingTypes = { - serials: SerialsType; - parents: ParentsType; - indices: IndicesType; -}; - export type FilterRowType = { [key: string]: any; [index: number]: any; } +export type ArrayTuple = any[][]; +export type ArrayObject = { [s: string]: any[] }; +export type FactorsType = ArrayTuple | ArrayObject; + +export type SuggestRowType = T extends ArrayTuple + ? T[number][number][] + : T extends ArrayObject ? { [K in keyof T]: T[K][number] } + : unknown; + export type FilterType = (row: FilterRowType) => boolean; +export type SuggestFilterType = (row: SuggestRowType) => boolean; export type PairType = number[]; -export type IncompleteType = Map; - +export type PairByKey = Map; export type CandidateType = [Scalar, number][]; export interface RowType { - size: number; - isArray: Boolean; - filled: () => Boolean; - values: () => IterableIterator; - storable: (candidate: CandidateType) => number | null; + consumed: PairByKey; }; export type SorterType = ( @@ -51,21 +52,12 @@ export interface CriterionArgsType { tolerance: number; }; -export interface OptionsType { +export interface OptionsType { length?: number; sorter?: SorterType; - criterion?: (incomplete: IncompleteType, options: CriterionArgsType) => IterableIterator; + criterion?: (ctrl: Controller) => IterableIterator; seed?: Scalar; tolerance?: number; - preFilter?: FilterType; - postFilter?: FilterType; + preFilter?: FilterType | SuggestFilterType; + postFilter?: FilterType | SuggestFilterType; }; - -export type ArrayTuple = any[][]; -export type ArrayObject = { [s: string]: any[] }; -export type FactorsType = ArrayTuple | ArrayObject; - -export type SuggestRowType = T extends ArrayTuple - ? T[number][number][] - : T extends ArrayObject ? { [K in keyof T]: T[K][number] } - : unknown; From 4a3ec74adfe03a6c26781bf83ba6bdc31dadc4bf Mon Sep 17 00:00:00 2001 From: righ Date: Tue, 27 Aug 2024 03:18:02 +0900 Subject: [PATCH 39/79] 2.4.0-alpha.0 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index a20f25e..38fefbd 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.3.2-alpha.5", + "version": "2.4.0-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.3.2-alpha.5", + "version": "2.4.0-alpha.0", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index c08a825..24f03df 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.3.2-alpha.5", + "version": "2.4.0-alpha.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From 8faaedff911dfbb97e510e388a6271929294fbe4 Mon Sep 17 00:00:00 2001 From: righ Date: Wed, 28 Aug 2024 01:32:59 +0900 Subject: [PATCH 40/79] test: add tests --- typescript/src/__tests__/pict.test.ts | 149 ++++++++++- typescript/src/utils/pict.ts | 349 ++++++++++++++++---------- 2 files changed, 358 insertions(+), 140 deletions(-) diff --git a/typescript/src/__tests__/pict.test.ts b/typescript/src/__tests__/pict.test.ts index 808057e..5e8c279 100644 --- a/typescript/src/__tests__/pict.test.ts +++ b/typescript/src/__tests__/pict.test.ts @@ -28,7 +28,7 @@ describe('PictConstraintsLexer with single constraints', () => { it('should handle NOT conditions correctly', () => { const lexer = new PictConstraintsLexer(` - IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] = "Yes" ELSE [AVAILABLE] = "No"; + IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] <> "No" ELSE [AVAILABLE] = "No"; `, false); const row1 = { PRODUCT: 'Pen', AVAILABLE: 'Yes' }; expect(lexer.filter(row1)).toBe(true); @@ -47,7 +47,7 @@ describe('PictConstraintsLexer with single constraints', () => { const row1 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Included' }; expect(lexer.filter(row1)).toBe(true); - const row2 = { CATEGORY: 'Electronics', BRAND: 'Samsung', WARRANTY: 'Not Included' }; + const row2 = { CATEGORY: 'Electronics', BRAND: 'General Electric Company', WARRANTY: 'Not Included' }; expect(lexer.filter(row2)).toBe(true); const row3 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Not Included' }; @@ -71,17 +71,17 @@ describe('PictConstraintsLexer with single constraints', () => { expect(lexer.filter(row4)).toBe(false); }); - it('should handle string equality conditions', () => { + it('should handle fields containing spaces', () => { const lexer = new PictConstraintsLexer(` - IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE [STATUS] = "Active"; + IF [PRODUCT NAME] = "Laptop" THEN [PRICE] > 500 ELSE [PRICE] <= 500; `, false); - const row1 = { NAME: 'Bob', STATUS: 'Inactive' }; + const row1 = { 'PRODUCT NAME': 'Laptop', PRICE: 600 }; expect(lexer.filter(row1)).toBe(true); - const row2 = { NAME: 'Alice', STATUS: 'Active' }; - expect(lexer.filter(row2)).toBe(true); + const row2 = { 'PRODUCT NAME': 'Laptop', PRICE: 400 }; + expect(lexer.filter(row2)).toBe(false); - const row3 = { NAME: 'Bob', STATUS: 'Active' }; + const row3 = { 'PRODUCT NAME': 'Desktop', PRICE: 600 }; expect(lexer.filter(row3)).toBe(false); }); @@ -118,6 +118,40 @@ describe('PictConstraintsLexer with single constraints', () => { const row5 = { AGE: 25, COUNTRY: 'Canada', STATUS: 'Denied' }; expect(lexer.filter(row5)).toBe(false); }); + it('should handle false in ELSE condition', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE FALSE; + `, false); + const row1 = { NAME: 'Bob', STATUS: 'Inactive' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { NAME: 'Alice', STATUS: 'Active' }; + expect(lexer.filter(row2)).toBe(false); + }); + + it('should handle true in ELSE condition', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE true; + `, false); + const row1 = { NAME: 'Bob', STATUS: 'Inactive' }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { NAME: 'Alice', STATUS: 'Active' }; + expect(lexer.filter(row2)).toBe(true); + }); + it('Compare with other fields', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = [ALIAS] THEN [AGE] <= 26; + `, false); + const row1 = { NAME: 'Bob', ALIAS: 'Bob', AGE: 18 }; + expect(lexer.filter(row1)).toBe(true); + + const row2 = { NAME: 'Alice', ALIAS: 'Lissie', AGE: 25 }; + expect(lexer.filter(row2)).toBe(true); + + const row3 = { NAME: 'Shohei', ALIAS: 'Shohei', AGE: 30 }; + expect(lexer.filter(row3)).toBe(false); + }); }); describe('PictConstraintsLexer with multiple constraints', () => { @@ -248,3 +282,102 @@ describe('PictConstraintsLexer with multiple constraints', () => { expect(lexer.filter(row3)).toBe(true); }); }); + +describe('PictConstraintsLexer with invalid constraints', () => { + it('Unknown comparer', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] @ "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Unknown comparison operator: @'); + }); + + it('Comparison operator missing, got a value', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Expected comparison operator but found value: "Alice"'); + }); + + it('Comparison operator missing, got an operator', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] AND TRUE THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Expected comparison operator but found operator: AND'); + }); + + it('Comparison operator and value missing, got then', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive" + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('A comparison operator and value are required after the field.'); + }); + it('Nothing after IF', () => { + const lexer = new PictConstraintsLexer(` + IF THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive" + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); + }); + + it('Nothing after THEN', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = "Summer" THEN ELSE [STATUS] = "Active" + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); + }); + + it('Nothing after ELSE', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); + }); + + + it('IF is missing, typo', () => { + const lexer = new PictConstraintsLexer(` + F [NAME] = "Summer" THEN [STATUS] = "Active" + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('Unknown token: F'); + }); + + it('IF is nothing', () => { + const lexer = new PictConstraintsLexer(` + [NAME] = "Summer" THEN [STATUS] = "Active" + `, false); + expect(lexer.errors.length).toBe(1); + expect(lexer.errors[0]).toBe('The leading "IF" is missing, found [NAME]'); + }); + + + it('Multiple invalid expressions', () => { + const lexer = new PictConstraintsLexer(` + IF [NAME] THEN [STATUS] = "Active"; + IF [NAME] = "Summer" THEN [STATUS] = "Active"; + IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE; + IF [NAME] = "Summer" THEN [STATUS] = "Active"; + IF [NAME] @ "Summer" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `, false); + + expect(lexer.errors.length).toBe(5); + + expect(lexer.errors[0]).toBe('A comparison operator and value are required after the field.' ); + expect(lexer.errors[1]).toBe(null); + expect(lexer.errors[2]).toBe('Expected field or value after "IF", "THEN", "ELSE"' ); + expect(lexer.errors[3]).toBe(null); + expect(lexer.errors[4]).toBe('Unknown comparison operator: @'); + + expect(lexer.filters[0]).toBeNull(); + expect(lexer.filters[1]).not.toBeNull(); + expect(lexer.filters[2]).toBeNull(); + expect(lexer.filters[3]).not.toBeNull(); + expect(lexer.filters[4]).toBeNull(); + }); +}); \ No newline at end of file diff --git a/typescript/src/utils/pict.ts b/typescript/src/utils/pict.ts index ca1cf50..5ebef26 100644 --- a/typescript/src/utils/pict.ts +++ b/typescript/src/utils/pict.ts @@ -1,7 +1,7 @@ import type { FilterRowType, FilterType } from '../types'; type Token = { - type: string; + type: TokenType; value: string; } @@ -9,15 +9,76 @@ type CacheType = { [key: string]: any; }; +enum TokenType { + REF = 'REF', + STRING = 'STRING', + NUMBER = 'NUMBER', + BOOLEAN = 'BOOLEAN', + NULL = 'NULL', + IF = 'IF', + ELSE = 'ELSE', + THEN = 'THEN', + COMPARER = 'COMPARER', + OPERATOR = 'OPERATOR', + LPAREN = 'LPAREN', + RPAREN = 'RPAREN', + LBRACE = 'LBRACE', + RBRACE = 'RBRACE', + COMMA = 'COMMA', + COLON = 'COLON', + SEMICOLON = 'SEMICOLON', + WHITESPACE = 'WHITESPACE', + UNKNOWN = 'UNKNOWN', +} + +function classifyToken(token: string): Token { + if (token.startsWith('[') && token.endsWith(']')) { + return { type: TokenType.REF, value: token }; + } + if (token.startsWith('"') && token.endsWith('"')) { + return { type: TokenType.STRING, value: token }; + } + if (!isNaN(parseFloat(token))) { + return { type: TokenType.NUMBER, value: token }; + } + if (['TRUE', 'FALSE'].includes(token.toUpperCase())) { + return { type: TokenType.BOOLEAN, value: token.toUpperCase() }; + } + if (token.toUpperCase() === TokenType.NULL) { + return { type: TokenType.NULL, value: token.toUpperCase() }; + } + if ([TokenType.IF, TokenType.ELSE, TokenType.THEN].includes(token.toUpperCase() as TokenType)) { + return { type: token.toUpperCase() as TokenType, value: token.toUpperCase() }; + } + if (['=', '<>', '>', '<', '>=', '<=', 'IN', 'LIKE'].includes(token.toUpperCase())) { + return { type: TokenType.COMPARER, value: token.toUpperCase() }; + } + if (['AND', 'OR', 'NOT'].includes(token.toUpperCase())) { + return { type: TokenType.OPERATOR, value: token.toUpperCase() }; + } + switch (token) { + case '(': return { type: TokenType.LPAREN, value: token }; + case ')': return { type: TokenType.RPAREN, value: token }; + case '{': return { type: TokenType.LBRACE, value: token }; + case '}': return { type: TokenType.RBRACE, value: token }; + case ',': return { type: TokenType.COMMA, value: token }; + case ':': return { type: TokenType.COLON, value: token }; + case ';': return { type: TokenType.SEMICOLON, value: token }; + default: return { type: TokenType.UNKNOWN, value: token }; + } +} + +const isWhiteSpace = (char: string) => { + return char === ' ' || char === '\n' || char === '\t'; +}; + export class PictConstraintsLexer { private tokens: Token[] = []; private cache: CacheType = {}; public filters: (FilterType | null)[] = []; - public errors: string[][] = []; + public errors: (string | null)[] = []; constructor(private input: string, private debug=false) { - this.input = input; - this.debug = debug; this.tokenize(); this.analyze(); } @@ -27,8 +88,9 @@ export class PictConstraintsLexer { let buffer = ''; let insideQuotes = false; let insideBraces = false; + let insideBrackets = false; - const addToken = (type: string, value: string) => { + const addToken = (type: TokenType, value: string) => { tokens.push({ type, value }); }; @@ -39,7 +101,7 @@ export class PictConstraintsLexer { insideQuotes = !insideQuotes; buffer += char; if (!insideQuotes) { - addToken('STRING', buffer); + addToken(TokenType.STRING, buffer); buffer = ''; } } else if (insideQuotes) { @@ -49,10 +111,12 @@ export class PictConstraintsLexer { tokens.push(classifyToken(buffer)); buffer = ''; } + insideBrackets = true; buffer += char; - } else if (char === ']') { + } else if (char === ']' && insideBrackets) { buffer += char; tokens.push(classifyToken(buffer)); + insideBrackets = false; buffer = ''; } else if (char === '{') { insideBraces = true; @@ -60,21 +124,21 @@ export class PictConstraintsLexer { tokens.push(classifyToken(buffer)); buffer = ''; } - addToken('LBRACE', char); + addToken(TokenType.LBRACE, char); } else if (char === '}') { insideBraces = false; if (buffer.length > 0) { tokens.push(classifyToken(buffer)); buffer = ''; } - addToken('RBRACE', char); + addToken(TokenType.RBRACE, char); } else if (char === ',' && insideBraces) { if (buffer.length > 0) { tokens.push(classifyToken(buffer)); buffer = ''; } - addToken('COMMA', char); - } else if ('[]=<>!();:'.includes(char) && !insideBraces) { + addToken(TokenType.COMMA, char); + } else if ('[]=<>!();:'.includes(char) && !insideBraces && !insideBrackets) { if (buffer.length > 0) { tokens.push(classifyToken(buffer)); buffer = ''; @@ -93,7 +157,7 @@ export class PictConstraintsLexer { } else { tokens.push(classifyToken(char)); } - } else if (isWhiteSpace(char) && !insideBraces) { + } else if (isWhiteSpace(char) && !insideBraces && !insideBrackets) { if (buffer.length > 0) { tokens.push(classifyToken(buffer)); buffer = ''; @@ -102,13 +166,9 @@ export class PictConstraintsLexer { while (i + 1 < constraints.length && isWhiteSpace(constraints[i + 1])) { whitespaceBuffer += constraints[++i]; } - addToken('WHITESPACE', whitespaceBuffer); - } else if (isWhiteSpace(char) && insideBraces) { - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } - addToken('WHITESPACE', char); + addToken(TokenType.WHITESPACE, whitespaceBuffer); + } else if (isWhiteSpace(char) && (insideBraces || insideBrackets)) { + buffer += char; } else { buffer += char; } @@ -125,10 +185,7 @@ export class PictConstraintsLexer { let tokenIndex = 0; let setIndex = 0; let regexIndex = 0; - let errorMessages: string[] = []; - const errors: string[][] = []; const tokens = this.tokens; - const filters: (FilterType | null)[] = []; const nextToken = () => { while (tokenIndex < tokens.length && tokens[tokenIndex].type === 'WHITESPACE') { @@ -140,18 +197,25 @@ export class PictConstraintsLexer { const parseExpression: () => string = () => { let expr = parseTerm(); let token = nextToken(); + if (token?.type === TokenType.UNKNOWN) { + throw new Error(`Unexpected token: ${token.value}`); + } while (token && token.type === 'OPERATOR' && token.value === 'OR') { const right = parseTerm(); expr = `(${expr} || ${right})`; token = nextToken(); } tokenIndex--; // Go back one token - return expr; + return expr || 'true'; } const parseTerm: () => string = () => { let term = parseFactor(); + let token = nextToken(); + if (token?.type === TokenType.UNKNOWN) { + throw new Error(`Unexpected token: ${token.value}`); + } while (token && token.type === 'OPERATOR' && token.value === 'AND') { const right = parseFactor(); term = `(${term} && ${right})`; @@ -163,38 +227,57 @@ export class PictConstraintsLexer { const parseFactor: () => string = () => { let token = nextToken(); - if (token && token.type === 'OPERATOR' && token.value === 'NOT') { - const factor = parseFactor(); - return `!(${factor})`; - } else if (token && token.type === 'LPAREN') { - const expr = parseExpression(); - token = nextToken(); - if (!token || token.type !== 'RPAREN') { - errorMessages.push('Expected closing parenthesis'); - return 'false'; + if (token != null) { + if (token.type === 'OPERATOR' && token.value === 'NOT') { + const factor = parseFactor(); + return `!(${factor})`; + } + if (token.type === TokenType.LPAREN) { + const expr = parseExpression(); + token = nextToken(); + if (!token || token.type !== TokenType.RPAREN) { + throw new Error('Expected closing parenthesis'); + } + return `(${expr})`; + } + if (token.type === TokenType.BOOLEAN) { + return token.value.toUpperCase() === 'TRUE' ? 'true' : 'false'; + } + if (token.type === TokenType.UNKNOWN) { + throw new Error(`Unexpected token: ${token.value}`); } - return `(${expr})`; - } else if (token && token.type === 'BOOLEAN') { - return token.value.toUpperCase() === 'TRUE' ? 'true' : 'false'; - } else { - tokenIndex--; // Go back one token - return parseCondition(); } + tokenIndex--; // Go back one token + return parseCondition(); } const parseCondition: () => string = () => { const left = parseOperand(); + if (left == null) { + throw new Error('Expected field or value after "IF", "THEN", "ELSE"'); + + } const comparerToken = nextToken(); - if (!comparerToken || comparerToken.type !== 'COMPARER') { - errorMessages.push('Expected comparer'); - return 'false'; + if ([TokenType.NUMBER, TokenType.STRING, TokenType.BOOLEAN, TokenType.NULL].includes(comparerToken?.type!)) { + throw new Error(`Expected comparison operator but found value: ${comparerToken?.value}`); } - const comparer = comparerToken.value; + if (comparerToken?.type === TokenType.THEN) { + throw new Error('A comparison operator and value are required after the field.'); + } + if (comparerToken?.type === 'OPERATOR') { + throw new Error(`Expected comparison operator but found operator: ${comparerToken.value}`); + } + + const comparer = comparerToken?.value; + if (comparer === 'IN') { const right = parseSet(); return `${right}.has(${left})`; } const right = parseOperand(); + if (right == null) { + throw new Error('Expected field or value'); + } switch (comparer) { case '=': return `${left} === ${right}`; @@ -216,26 +299,25 @@ export class PictConstraintsLexer { } return `this.cache['${regexKey}'].test(${left})`; default: - errorMessages.push(`Unknown comparer: ${comparer}`); - return 'false'; + throw new Error(`Unknown comparison operator: ${comparer}`); } } const parseSet: () => string = () => { const elements: string[] = []; let token = nextToken(); - if (token && token.type === 'LBRACE') { + if (token && token.type === TokenType.LBRACE) { token = nextToken(); - while (token && token.type !== 'RBRACE') { - if (token.type === 'STRING') { + while (token && token.type !== TokenType.RBRACE) { + if (token.type === TokenType.STRING) { elements.push(token.value.slice(1, -1)); // remove quotes - } else if (token.type !== 'COMMA' && token.type !== 'WHITESPACE') { - errorMessages.push(`Unexpected token: ${token.value}`); + } else if (token.type !== TokenType.COMMA && token.type !== TokenType.WHITESPACE) { + throw new Error(`Unexpected token in array: ${token.value}`); } token = nextToken(); } } else { - errorMessages.push(`Expected '{' but found ${token ? token.value : 'null'}`); + throw new Error(`Expected '{' but found ${token ? token.value : TokenType.NULL}`); } const setKey = `set_${setIndex++}`; if (!this.cache[setKey]) { @@ -244,75 +326,119 @@ export class PictConstraintsLexer { return `this.cache['${setKey}']`; } - const parseOperand: () => string = () => { + const parseOperand: () => string | null = () => { const token = nextToken(); if (token == null) { - errorMessages.push('Unexpected end of input'); - return 'false'; + return null; } - if (token.type === 'REF') { + if (token.type === TokenType.REF) { const key = token.value.slice(1, -1); // remove [ and ] return `row["${key}"]`; - } else if (token.type === 'STRING') { + } else if (token.type === TokenType.STRING) { const value = token.value; // keep quotes for string literals return `${value}`; - } else if (token.type === 'NUMBER') { + } else if (token.type === TokenType.NUMBER) { return token.value; - } else if (token.type === 'BOOLEAN') { + } else if (token.type === TokenType.BOOLEAN) { return token.value === 'TRUE' ? 'true' : 'false'; - } else if (token.type === 'NULL') { - return 'null'; + } else if (token.type === TokenType.NULL) { + return TokenType.NULL; + } else { + return null; + } + } + + const abandon = () => { + while (tokenIndex < tokens.length && tokens[tokenIndex].type !== TokenType.SEMICOLON) { + tokenIndex++; + } + } + + const close = (code: string | null, error: string | null) => { + // Invariably, one of the two will be null. + if (code == null) { + if (this.debug) { + console.error(`Error[${this.errors.length}]:`, error); + } + this.filters.push(null); + this.errors.push(error); } else { - errorMessages.push(`Unexpected token: ${token.value}`); - return 'false'; + if (this.debug) { + console.debug(`Code[${this.filters.length}]:`, code); + } + try { + const f = this.makeClosure(code); + this.filters.push(f); + this.errors.push(null); + } catch (e) { + console.error(e); + this.filters.push(null); + // @ts-ignore + this.errors.push(`RuntimeError[${this.errors.length}]:`, e.message); + } + } } - while (tokenIndex < tokens.length) { + const read = () => { + try { + const expr = parseExpression(); + return expr; + } catch (e) { + // @ts-ignore + close(null, e.message); + } + // If the conditional expression ends with “ELSE”, + // the current index reaches a semicolon, and the next expression is skipped by the abandon function. + // Therefore, the index is reset to the previous one. + tokenIndex--; + abandon(); + return null; + }; + + while (tokens[tokenIndex] != null) { const token = nextToken(); if (token == null) { break; } - if (token.type === 'IF') { - const condition = parseExpression(); + if (token.type === TokenType.IF) { + const action = read(); + if (action == null) { + continue; + } const thenToken = nextToken(); - if (!thenToken || thenToken.type !== 'THEN') { - errorMessages.push('Expected THEN'); - break; + if (!thenToken || thenToken.type !== TokenType.THEN) { + abandon() + continue; + } + const thenAction = read(); + if (thenAction == null) { + continue; } - const thenAction = parseExpression(); const elseToken = nextToken(); - let elseAction = 'true'; - if (elseToken && elseToken.type === 'ELSE') { - elseAction = parseExpression(); + let elseAction: string | null = 'true'; + if (elseToken && elseToken.type === TokenType.ELSE) { + elseAction = read(); + if (elseAction == null) { + continue; + } } else { tokenIndex--; // Go back one token if ELSE is not found } - const filterCode = `return (${condition} ? (${thenAction}) : (${elseAction}));`; - try { - if (this.debug) { - console.debug(`code[${filters.length}]:`, filterCode); - } - const f = this.makeClosure(filterCode); - filters.push(f as FilterType); - } catch (e) { - filters.push(null); - // @ts-ignore - errorMessages.push(e.message); - } - errors.push(errorMessages); - errorMessages = []; - } else if (token.type === 'SEMICOLON') { + const code = `return (${action} ? (${thenAction}) : (${elseAction}));`; + close(code, null); + } else if (token.type === TokenType.SEMICOLON) { // do nothing } else { - errorMessages.push(`Unexpected token: ${token.value}`); - errors.push(errorMessages); - break; + if (token.type === TokenType.UNKNOWN) { + close(null, `Unknown token: ${token.value}`); + } else { + close(null, `The leading "IF" is missing, found ${token.value}`); + } + abandon(); } } - this.filters = filters; - this.errors = errors; } private makeClosure (code: string) { @@ -337,44 +463,3 @@ export class PictConstraintsLexer { } } -function classifyToken(token: string): Token { - if (token.startsWith('[') && token.endsWith(']')) { - return { type: 'REF', value: token }; - } - if (token.startsWith('"') && token.endsWith('"')) { - return { type: 'STRING', value: token }; - } - if (!isNaN(parseFloat(token))) { - return { type: 'NUMBER', value: token }; - } - if (['TRUE', 'FALSE'].includes(token.toUpperCase())) { - return { type: 'BOOLEAN', value: token.toUpperCase() }; - } - if (token.toUpperCase() === 'NULL') { - return { type: 'NULL', value: token.toUpperCase() }; - } - if (['IF', 'ELSE', 'THEN'].includes(token.toUpperCase())) { - return { type: token.toUpperCase(), value: token.toUpperCase() }; - } - if (['=', '<>', '>', '<', '>=', '<=', 'IN', 'LIKE'].includes(token.toUpperCase())) { - return { type: 'COMPARER', value: token.toUpperCase() }; - } - if (['AND', 'OR', 'NOT'].includes(token.toUpperCase())) { - return { type: 'OPERATOR', value: token.toUpperCase() }; - } else { - switch (token) { - case '(': return { type: 'LPAREN', value: token }; - case ')': return { type: 'RPAREN', value: token }; - case '{': return { type: 'LBRACE', value: token }; - case '}': return { type: 'RBRACE', value: token }; - case ',': return { type: 'COMMA', value: token }; - case ':': return { type: 'COLON', value: token }; - case ';': return { type: 'SEMICOLON', value: token }; - default: throw new Error(`Unknown token: ${token}`); - } - } -} - -const isWhiteSpace = (char: string) => { - return char === ' ' || char === '\n' || char === '\t'; -}; From 02999111bb2fa4e1b0137213fa4378754bb0582f Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 03:42:03 +0900 Subject: [PATCH 41/79] 2.4.0-alpha.1 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 38fefbd..f249b62 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.4.0-alpha.0", + "version": "2.4.0-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.4.0-alpha.0", + "version": "2.4.0-alpha.1", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 24f03df..1d2f574 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.4.0-alpha.0", + "version": "2.4.0-alpha.1", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From 2184f4bb666522fbcddcff56a97e161599a3ebc6 Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 05:40:12 +0900 Subject: [PATCH 42/79] update README and types --- typescript/README.md | 175 +++++++++++++++--------- typescript/src/__tests__/filter.test.ts | 9 +- typescript/src/__tests__/index.test.ts | 6 +- typescript/src/controller.ts | 22 +-- typescript/src/criteria/greedy.ts | 4 +- typescript/src/exceptions.ts | 4 +- typescript/src/index.ts | 9 +- typescript/src/lib.ts | 12 +- typescript/src/types.ts | 30 ++-- 9 files changed, 160 insertions(+), 111 deletions(-) diff --git a/typescript/README.md b/typescript/README.md index f655ee6..87dce4a 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -2,6 +2,9 @@ [![Workflow](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) [![codecov](https://codecov.io/gh/walkframe/covertable/branch/master/graph/badge.svg)](https://codecov.io/gh/walkframe/covertable) +# What is covertable? +covertable is a powerful tool for generating pairwise combinations of input factors, designed for both Node.js and browser environments. It's easy to use, flexible, and supports advanced filtering options, making it perfect for testing scenarios and generating comprehensive datasets. + # Installation ```sh @@ -10,15 +13,15 @@ $ npm install covertable --save # Usage -## Simple demo in Node.js: +## Simple usage in Node.js: ```javascript var covertable = require('covertable'); -var make = covertable.default; +var make = covertable.make; -var machine = ['iphone', 'pixel']; -var os = ['ios', 'android']; -var browser = ['FireFox', 'Chrome', 'Safari']; +var machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +var os = ["iOS", "Android"]; +var browser = ["FireFox", "Chrome", "Safari"]; make([machine, os, browser]); ``` @@ -26,64 +29,47 @@ Output: ```javascript [ - [ 'pixel', 'android', 'Chrome' ], - [ 'pixel', 'ios', 'Safari' ], - [ 'pixel', 'android', 'FireFox' ], - [ 'iphone', 'android', 'Safari' ], - [ 'iphone', 'ios', 'Chrome' ], - [ 'iphone', 'ios', 'FireFox' ] + [ 'Pixel', 'iOS', 'Chrome' ], + [ 'ZenFone', 'iOS', 'FireFox' ], + [ 'Pixel', 'Android', 'Safari' ], + [ 'Galaxy', 'Android', 'Chrome' ], + [ 'XPERIA', 'Android', 'FireFox' ], + [ 'Pixel', 'iOS', 'FireFox' ], + [ 'iPhone', 'iOS', 'Safari' ], + [ 'Galaxy', 'iOS', 'Safari' ], + [ 'XPERIA', 'iOS', 'Chrome' ], + [ 'ZenFone', 'Android', 'Chrome' ], + [ 'Galaxy', 'iOS', 'FireFox' ], + [ 'iPhone', 'Android', 'Chrome' ], + [ 'iPhone', 'iOS', 'FireFox' ], + [ 'ZenFone', 'iOS', 'Safari' ], + [ 'XPERIA', 'iOS', 'Safari' ] ] ``` Of course, it also works in the browser well. -## Advanced demo in TypeScript: +## Advanced usage in TypeScript: -```typescript -import { default as make, makeAsync, sorters, criteria } from "covertable"; - -const machine = ['iphone', 'pixel']; -const os = ['ios', 'android']; -const browser = ['FireFox', 'Chrome', 'Safari']; - -make([machine, os, browser], { // optional - length: 2, // default: 2 - criterion: criteria.simple, // default: criteria.greedy - sorter: sorters.random, // default: sorters.hash - preFilter: (row: any) => !(row[1] === 'android' && row[0] !== 'pixel'), // default: null - postFilter: (row: any) => !(row[1] === 'ios' && row[2] !== 'Safari'), // default: null -}); -``` +As previously mentioned, when elements are specified as an array, the results will also be in array form. However, if the elements are specified as an object, the results will be in object form. -Output: +The following example uses preFilter and postFilter to apply constraints to the output results. In this case, `SuggestRowType` can also be used to infer the type of row parameters that the filter function receives. ```typescript -[ // filtered - [ 'iphone', 'ios', 'Safari' ], - [ 'pixel', 'android', 'Chrome' ], - [ 'pixel', 'ios', 'Safari' ] -] -``` +import { make, sorters, criteria, SuggestRowType, DictType } from "covertable"; -You can use also `makeAsync` function (generator). -- It receives the same arguments with `make` function. -- It returns the row at the time it's made. +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; -## Object input and output +const factors = {machine, os, browser}; -You can specify `factors` as object type: - -```typescript -import { default as make, sorters, criteria } from "covertable"; - -const machine = ['iphone', 'pixel']; -const os = ['ios', 'android']; -const browser = ['FireFox', 'Chrome', 'Safari']; - -make({machine, os, browser}, { // optional +make(factors, { // optional length: 2, - preFilter: (row: any) => !(row.os === 'android' && row.machine !== 'pixel'), // default: null - postFilter: (row: any) => !(row.os === 'ios' && row.browser !== 'Safari'), // default: null + // SuggestRowType is { machine: string, os: string, browser: string } + preFilter: (row: SuggestRowType) => !(row.os === 'Android' && row.machine !== 'Pixel'), // default: null + // Or DictType that is { [key: string]: string } + postFilter: (row: DictType) => !(row.os === 'iOS' && row.browser !== 'Safari'), // default: null }); ``` @@ -91,16 +77,29 @@ Then the output will change as follows: ```typescript [ // filtered - { machine: 'iphone', browser: 'Safari', os: 'ios' }, - { machine: 'pixel', browser: 'Chrome', os: 'android' }, - { machine: 'pixel', browser: 'Safari', os: 'ios' }, + { machine: 'Pixel', os: 'Android', browser: 'FireFox' }, + { machine: 'iPhone', os: 'iOS', browser: 'Safari' }, + { machine: 'Galaxy', browser: 'Safari', os: 'iOS' }, + { machine: 'Pixel', browser: 'Safari', os: 'iOS' }, + { machine: 'ZenFone', browser: 'Safari', os: 'iOS' }, + { machine: 'XPERIA', browser: 'Safari', os: 'iOS' } ] ``` -## Options -`covertable.make` function has options as `object` at 2nd argument. +You can use also `makeAsync` function (generator). +- It receives the same arguments with `make` function. +- It returns the row at the time it's made. -All options are omittable. +```js +import { makeAsync } from "covertable"; + +for await (const row of makeAsync([machine, os, browser])) { + console.log(row); +} +``` + +## Options +The `covertable.make` function accepts an options object as its second argument. Here are the available options: ### length Number of factors to be covered. (default: 2) @@ -108,9 +107,7 @@ Number of factors to be covered. (default: 2) Obviously the more it increases, the more number of combinations increases. ### sorter -Combinations depend on the order of spreading all over the rows. - -You can choice a sorter from the following: +Determines the order of combinations. - sorters.random: It makes different combinations everytime. (fastest) - sorters.hash: It makes combinations depending on hash of the pair and seed. (default) @@ -120,7 +117,7 @@ You can choice a sorter from the following: - When the combination of factors and seed are the same, covertable reproduces the same collective. ### criterion -You can choice a criterion from the following: +Determines the efficiency of combinations. - `criteria.simple`: it extracts any pairs that can be stored into the processing row. - `criteria.greedy`: it attempts to make most efficient combinations. (default) @@ -132,23 +129,69 @@ Although the latter is superior to former in terms of fewer combinations general Not relevant options will be ignored. ### preFilter -This is a function to filter beforehand. - -It receives an argument `row` as `object` type. +Function to filter combinations before they are registered. When the function returns `false`, the row combination will not be registered. - If factors type is `Array`, you should specify an index at the subscript like `row => row[1] < 6`. - If factors type is `Object`, you should specify a key at the subscript like `row => row.month < 6` or `row => row['month'] < 6` ### postFilter -This means a function to filter later. +Function to filter combinations after they are generated. The usage is the same as `preFilter`, only the difference is the timing of the call. It will delete rows not matched this function at the last. For this reason, the final test cases may not satisfy the factors coverage. -# Requirement +### PictConstraintsLexer + +Filter functions can also be generated using PictConstraintsLexer. Use as follows +This function is supported only in the typescript version. + +```js +import { make, PictConstraintsLexer } from "covertable"; + +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; + +const lexer = new PictConstraintsLexer( + ` + IF [machine] = "iPhone" THEN [os] = "iOS"; + IF [os] = "iOS" THEN [machine] = "iPhone"; + `, true +); + +make({machine, os, browser}, { // optional + preFilter: lexer.filter, +}); +``` + +```js +[ + { machine: 'ZenFone', browser: 'FireFox', os: 'Android' }, + { os: 'Android', browser: 'Safari', machine: 'Pixel' }, + { machine: 'Galaxy', browser: 'Chrome', os: 'Android' }, + { machine: 'XPERIA', os: 'Android', browser: 'FireFox' }, + { machine: 'Pixel', browser: 'Chrome', os: 'Android' }, + { os: 'iOS', browser: 'FireFox', machine: 'iPhone' }, + { machine: 'Pixel', browser: 'FireFox', os: 'Android' }, + { os: 'iOS', browser: 'Chrome', machine: 'iPhone' }, + { machine: 'Galaxy', browser: 'Safari', os: 'Android' }, + { machine: 'ZenFone', browser: 'Chrome', os: 'Android' }, + { os: 'iOS', browser: 'Safari', machine: 'iPhone' }, + { machine: 'Galaxy', browser: 'FireFox', os: 'Android' }, + { machine: 'XPERIA', browser: 'Chrome', os: 'Android' }, + { machine: 'ZenFone', browser: 'Safari', os: 'Android' }, + { machine: 'XPERIA', browser: 'Safari', os: 'Android' } +] +``` + +This feature acts as a conversion tool that enables the implementation of PICT constraint conditions within CoverTable, +allowing users to seamlessly apply complex constraints to their test data generation. + + +# Requirements ES2015 or later @@ -179,6 +222,6 @@ $ npm version patch $ npm publish ``` -# More info +# More information - [walkframe/covertable - GitHub](https://github.com/walkframe/covertable) diff --git a/typescript/src/__tests__/filter.test.ts b/typescript/src/__tests__/filter.test.ts index 7354042..d6ccad1 100644 --- a/typescript/src/__tests__/filter.test.ts +++ b/typescript/src/__tests__/filter.test.ts @@ -1,5 +1,4 @@ -import { Dict, SuggestRowType } from "../types"; -import { make, makeAsync, sorters, criteria } from "../index"; +import { make, DictType, SuggestRowType } from "../"; const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; const os = ["iOS", "Android"]; @@ -7,7 +6,7 @@ const browser = ["FireFox", "Chrome", "Safari"]; test('exclude impossible combinations', () => { const factors = {machine, os, browser}; - const preFilter = (row: Dict) => { + const preFilter = (row: DictType) => { return !( (row.machine === 'iPhone' && row.os !== 'iOS') || (row.machine !== 'iPhone' && row.os === 'iOS') @@ -49,14 +48,14 @@ test('Limited to iphone and iOS combinations only.', () => { test('Use a constant-false function for preFilter', () => { const factors = {machine, os, browser}; - const preFilter = (row: Dict) => false; + const preFilter = (row: DictType) => false; const rows = make(factors, { preFilter }); expect(rows).toEqual([]); }); test('Use the wrong conditional function for preFilter', () => { const factors = {machine, os, browser}; - const preFilter = (row: Dict) => row.machine === 'WindowsPhone'; + const preFilter = (row: DictType) => row.machine === 'WindowsPhone'; const rows = make(factors, { preFilter }); expect(rows).toEqual([]); }); diff --git a/typescript/src/__tests__/index.test.ts b/typescript/src/__tests__/index.test.ts index 904ab6f..db68b71 100644 --- a/typescript/src/__tests__/index.test.ts +++ b/typescript/src/__tests__/index.test.ts @@ -1,6 +1,6 @@ import { default as make, sorters, criteria } from '../index'; import { product, combinations, range, len, all, getItems } from '../lib'; -import { FactorsType, Scalar, Dict, PairType } from '../types'; +import { FactorsType, ScalarType, DictType, PairType } from '../types'; const getPairs = function* (factors: FactorsType, length = 2) { const allKeys = getItems(factors).map(([k, _]) => k); @@ -69,7 +69,7 @@ test('prefilter excludes specified pairs before', () => { ["d", "e"], ["f"], ]; - const preFilter = (row: Dict) => { + const preFilter = (row: DictType) => { if (row[0] === "a" && row[1] === "d") { return false; } @@ -151,7 +151,7 @@ test('dict type factors make dict row', () => { 'key5': ["m", "n", "o"], }; const rows = make(factors); - const sorter = (a: Scalar, b: Scalar) => a > b ? 1 : -1; + const sorter = (a: ScalarType, b: ScalarType) => a > b ? 1 : -1; for (let row of rows) { const keys1 = Object.keys(row).sort(sorter); const keys2 = Object.keys(factors).sort(sorter); diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index dc7c071..03820e8 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -17,9 +17,9 @@ import { IndicesType, FactorsType, SerialsType, - Scalar, - Dict, - PairByKey, + ScalarType, + DictType, + PairByKeyType, ParentsType, CandidateType, RowType, @@ -29,9 +29,9 @@ import { } from "./types"; import { NeverMatch, NotReady } from "./exceptions"; -export class Row extends Map implements RowType { +export class Row extends Map implements RowType { // index: number - public consumed: PairByKey = new Map(); + public consumed: PairByKeyType = new Map(); constructor(row: CandidateType) { super(); @@ -57,9 +57,9 @@ export class Controller { private serials: SerialsType = new Map(); private parents: ParentsType = new Map(); private indices: IndicesType = new Map(); - public incomplete: PairByKey = new Map(); + public incomplete: PairByKeyType = new Map(); - private rejected: Set = new Set(); + private rejected: Set = new Set(); public row: Row; constructor(public factors: FactorsType, public options: OptionsType) { @@ -169,8 +169,8 @@ export class Controller { return row.size === this.factorLength; } - toMap(row: Row): Map { - const result: Map = new Map(); + toMap(row: Row): Map { + const result: Map = new Map(); for (let [key, serial] of row.entries()) { const index = this.indices.get(serial) as number; const first = this.indices.get((this.serials.get(key) as PairType)[0]); @@ -181,7 +181,7 @@ export class Controller { } toProxy(row: Row) { - const obj: Dict = {}; + const obj: DictType = {}; for (let [key, value] of this.toMap(row).entries()) { obj[key] = value; } @@ -189,7 +189,7 @@ export class Controller { } toObject(row: Row) { - const obj: Dict = {}; + const obj: DictType = {}; for (let [key, value] of this.toMap(row).entries()) { obj[key] = value; } diff --git a/typescript/src/criteria/greedy.ts b/typescript/src/criteria/greedy.ts index b5529c0..512b6de 100644 --- a/typescript/src/criteria/greedy.ts +++ b/typescript/src/criteria/greedy.ts @@ -1,8 +1,8 @@ -import type {FactorsType, PairByKey, PairType} from '../types'; +import type {FactorsType, PairByKeyType, PairType} from '../types'; import { combinations, unique } from '../lib'; import { Controller } from '../controller'; -const getNumRemovablePairs = (indexes: Set, incomplete: PairByKey, length: number) => { +const getNumRemovablePairs = (indexes: Set, incomplete: PairByKeyType, length: number) => { let num = 0; const removingKeys = combinations([... indexes], length); for (let pair of removingKeys) { diff --git a/typescript/src/exceptions.ts b/typescript/src/exceptions.ts index 9450bac..677f9fe 100644 --- a/typescript/src/exceptions.ts +++ b/typescript/src/exceptions.ts @@ -1,7 +1,7 @@ -import { Scalar } from "./types"; +import { ScalarType } from "./types"; export class NotReady extends Error { - constructor(public key: Scalar) { + constructor(public key: ScalarType) { super(`Not yet '${key}' in the object`); } } diff --git a/typescript/src/index.ts b/typescript/src/index.ts index f3be2af..9a78f72 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -6,7 +6,7 @@ import greedy from "./criteria/greedy"; import simple from "./criteria/simple"; import {PictConstraintsLexer} from "./utils/pict"; -import { FactorsType, OptionsType, SuggestRowType } from "./types"; +import { FactorsType, OptionsType, SuggestRowType, DictType, ListType } from "./types"; import { Controller } from "./controller"; import { NeverMatch } from "./exceptions"; @@ -60,4 +60,11 @@ export { PictConstraintsLexer, }; +export type { + OptionsType, + SuggestRowType, + DictType, + ListType, +} + export default make; diff --git a/typescript/src/lib.ts b/typescript/src/lib.ts index cd9d0cc..90e454b 100644 --- a/typescript/src/lib.ts +++ b/typescript/src/lib.ts @@ -2,8 +2,8 @@ export { hex as md5 } from 'js-md5'; import { NotReady } from './exceptions'; import type { - FactorsType, Scalar, ParentsType, CandidateType, PairType, - Dict, + FactorsType, ScalarType, ParentsType, CandidateType, PairType, + DictType, } from './types'; // https://gist.github.com/righ/71e32be8e33f74bde516c06f80c941e8 @@ -79,7 +79,7 @@ export const len = (obj: any[] | object): number => { return Object.keys(obj).length; } -export const getItems = (container: FactorsType | Map): [Scalar, any[]][] => { +export const getItems = (container: FactorsType | Map): [ScalarType, any[]][] => { if (Array.isArray(container)) { return container.map((v, i) => [i, v]); } @@ -90,13 +90,13 @@ export const getItems = (container: FactorsType | Map): [Scalar, } export const getCandidate = (pair: number[], parents: ParentsType): CandidateType => { - const keys: Scalar[] = pair.map(p => parents.get(p) || 0); + const keys: ScalarType[] = pair.map(p => parents.get(p) || 0); return zip(keys, pair); } export const ascOrder = (a: number, b: number) => a > b ? 1 : -1; -export const unique = (pair: PairType): Scalar => { +export const unique = (pair: PairType): ScalarType => { const total = pair.reduce((a, b) => a * b); if (Number.isSafeInteger(total)) { return total; @@ -131,7 +131,7 @@ export function* primeGenerator(): Generator { export const proxyHandler = { - get(obj: Dict, key: string, receiver: any) { + get(obj: DictType, key: string, receiver: any) { if (key in obj) { return obj[key]; } diff --git a/typescript/src/types.ts b/typescript/src/types.ts index c5058b6..e48be1d 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -1,11 +1,11 @@ import type { Controller } from "./controller"; -export type Scalar = number | string; -export type Dict = { [s: string]: any }; -export type List = { [index: number]: any[] }; +export type ScalarType = number | string; +export type DictType = { [s: string]: any }; +export type ListType = { [index: number]: any[] }; -export type SerialsType = Map; -export type ParentsType = Map; +export type SerialsType = Map; +export type ParentsType = Map; export type IndicesType = Map; export type FilterRowType = { @@ -13,13 +13,13 @@ export type FilterRowType = { [index: number]: any; } -export type ArrayTuple = any[][]; -export type ArrayObject = { [s: string]: any[] }; -export type FactorsType = ArrayTuple | ArrayObject; +export type ArrayTupleType = any[][]; +export type ArrayObjectType = { [s: string]: any[] }; +export type FactorsType = ArrayTupleType | ArrayObjectType; -export type SuggestRowType = T extends ArrayTuple +export type SuggestRowType = T extends ArrayTupleType ? T[number][number][] - : T extends ArrayObject ? { [K in keyof T]: T[K][number] } + : T extends ArrayObjectType ? { [K in keyof T]: T[K][number] } : unknown; export type FilterType = (row: FilterRowType) => boolean; @@ -27,12 +27,12 @@ export type SuggestFilterType = (row: SuggestRowType) export type PairType = number[]; -export type PairByKey = Map; +export type PairByKeyType = Map; -export type CandidateType = [Scalar, number][]; +export type CandidateType = [ScalarType, number][]; export interface RowType { - consumed: PairByKey; + consumed: PairByKeyType; }; export type SorterType = ( @@ -41,7 +41,7 @@ export type SorterType = ( ) => PairType[]; export interface SortArgsType { - seed: Scalar; + seed: ScalarType; indices: IndicesType; }; @@ -56,7 +56,7 @@ export interface OptionsType { length?: number; sorter?: SorterType; criterion?: (ctrl: Controller) => IterableIterator; - seed?: Scalar; + seed?: ScalarType; tolerance?: number; preFilter?: FilterType | SuggestFilterType; postFilter?: FilterType | SuggestFilterType; From 1151c43805856d3345dab902181fd42cad6b462e Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 05:40:29 +0900 Subject: [PATCH 43/79] 2.4.0-alpha.2 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index f249b62..11269c4 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.4.0-alpha.1", + "version": "2.4.0-alpha.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.4.0-alpha.1", + "version": "2.4.0-alpha.2", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 1d2f574..696de66 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.4.0-alpha.1", + "version": "2.4.0-alpha.2", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From 9bdb036725caf62171973de0982cb5786ec2eb00 Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 05:58:55 +0900 Subject: [PATCH 44/79] update --- typescript/README.md | 10 +++++----- typescript/src/__tests__/pict.test.ts | 10 +++++++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/typescript/README.md b/typescript/README.md index 87dce4a..f6da668 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -68,7 +68,7 @@ make(factors, { // optional length: 2, // SuggestRowType is { machine: string, os: string, browser: string } preFilter: (row: SuggestRowType) => !(row.os === 'Android' && row.machine !== 'Pixel'), // default: null - // Or DictType that is { [key: string]: string } + // Or DictType that is { [key: string]: any } postFilter: (row: DictType) => !(row.os === 'iOS' && row.browser !== 'Safari'), // default: null }); ``` @@ -109,8 +109,8 @@ Obviously the more it increases, the more number of combinations increases. ### sorter Determines the order of combinations. -- sorters.random: It makes different combinations everytime. (fastest) -- sorters.hash: It makes combinations depending on hash of the pair and seed. (default) +- sorters.random: Generates different combinations each time. (fastest) +- sorters.hash: Uses a hash-based method for reproducibility. (default) - It receives `seed`. - `seed` option decides the order of storing from unstored pairs. @@ -119,8 +119,8 @@ Determines the order of combinations. ### criterion Determines the efficiency of combinations. -- `criteria.simple`: it extracts any pairs that can be stored into the processing row. -- `criteria.greedy`: it attempts to make most efficient combinations. (default) +- `criteria.simple`: Quickly generates combinations. +- `criteria.greedy`: Attempts to minimize the number of combinations, but is more time-intensive. (default) - It receives [tolerance](https://github.com/walkframe/covertable#tolerance) option. While `criteria.simple` processes quickly, `criteria.greedy` makes fewer combinations. diff --git a/typescript/src/__tests__/pict.test.ts b/typescript/src/__tests__/pict.test.ts index 5e8c279..ad75558 100644 --- a/typescript/src/__tests__/pict.test.ts +++ b/typescript/src/__tests__/pict.test.ts @@ -1,6 +1,15 @@ import { PictConstraintsLexer } from "../utils/pict"; describe('PictConstraintsLexer with single constraints', () => { + it('Blank', () => { + const lexer = new PictConstraintsLexer(``, true); + expect(lexer.filters.length).toBe(0); + expect(lexer.errors.length).toBe(0); + + const row1 = { PRICE: 150, DISCOUNT: 'YES' }; + expect(lexer.filter(row1)).toBe(true); + }); + it('should filter correctly with LIKE and IN conditions', () => { const lexer = new PictConstraintsLexer(` IF [NAME] LIKE "Alic?" THEN [STATUS] IN {"Active", "Pending"} ELSE [AGE] > 20 OR [COUNTRY] = "USA"; @@ -355,7 +364,6 @@ describe('PictConstraintsLexer with invalid constraints', () => { expect(lexer.errors.length).toBe(1); expect(lexer.errors[0]).toBe('The leading "IF" is missing, found [NAME]'); }); - it('Multiple invalid expressions', () => { const lexer = new PictConstraintsLexer(` From c0d0684230ec00255ccfb25b620d271e157664a8 Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 05:59:47 +0900 Subject: [PATCH 45/79] 2.4.0 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 11269c4..ae7f173 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.4.0-alpha.2", + "version": "2.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.4.0-alpha.2", + "version": "2.4.0", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 696de66..b948fbb 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.4.0-alpha.2", + "version": "2.4.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://github.com/walkframe/covertable", "repository": { From ababb7f57dd4713a09432b536fdef0830c5793a1 Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 19:56:41 +0900 Subject: [PATCH 46/79] update README --- README.md | 75 ++++++++++++++++ README.rst | 203 ------------------------------------------ python/history.md | 22 +++++ typescript/history.md | 38 ++++++++ 4 files changed, 135 insertions(+), 203 deletions(-) create mode 100644 README.md delete mode 100644 README.rst create mode 100644 python/history.md create mode 100644 typescript/history.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..89a2102 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# Covertable + +![covertable logo](./covertable.png) + +Time is limited. + +Creating a test case that satisfies all possible factors is often unrealistic and, more importantly, tedious. + +Save time with Covertable, a flexible pairwise tool that generates combinations covering two (or more) factors. + +## Implementations + +Covertable is available in two implementations, with TypeScript as the primary focus and Python offered as a secondary option. + +### TypeScript + +[![NPM Version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) + +- [README](https://github.com/walkframe/covertable/blob/master/typescript) +- [History](https://github.com/walkframe/covertable/blob/master/typescript/history.md) + +### Python (Legacy Support) + +[![PyPI Version](https://badge.fury.io/py/covertable.svg)](https://badge.fury.io/py/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/python.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/python.yaml) + +- [README](https://github.com/walkframe/covertable/blob/master/python/README.rst) +- [History](https://github.com/walkframe/covertable/blob/master/python/history.md) + + +For more details, please refer to the links above. + +## Performance + +> **Note:** +> The following data was measured in Python 3.7.7 on a `3.1 GHz 6-Core Intel Core i5`. +> The coverage number is `2`. + +| Combination | Default | Minimum case | Fastest case | +|-------------------|-------------------------------------|---------------------------------------|------------------------------------| +| **3^4** | num: `9`
time: `0.0006s` | num: `9`
time: `0.0006s` | num: `14`
time: `0.0005s` | +| **3^13** | num: `19`
time: `0.03s` | num: `17`
time: `0.03s` | num: `21`
time: `0.003s` | +| **4^15 + 3^17 + 2^29** | num: `36`
time: `7.41s` | num: `34`
time: `7.47s` | num: `42`
time: `0.40s` | +| **4^1 + 3^39 + 2^35** | num: `27`
time: `15.19s` | num: `26`
time: `14.70s` | num: `30`
time: `0.51s` | +| **2^100** | num: `14`
time: `23.97s` | num: `12`
time: `0.63s` | num: `13`
time: `0.48s` | +| **10^20** | num: `198`
time: `14.28s` | num: `195`
time: `14.48s` | num: `284`
time: `0.53s` | + +In general, as the number of elements or coverage increases, the number of combinations tends to increase significantly. + +## Tolerance + +If you use the `greedy` criterion and specify a positive integer for the `tolerance` option, you can increase speed at the expense of the number of combinations. + +The greater the `tolerance`, the faster the speed and the larger the number of combinations. + +### Example: 10^20 Test Cases + +| Tolerance | num | time | +|-----------|------|--------| +| 0 (default) | `195` | `14.48s` | +| 1 | `199` | `12.45s` | +| 2 | `201` | `9.48s` | +| 3 | `201` | `7.17s` | +| 4 | `207` | `5.70s` | +| 5 | `212` | `4.58s` | +| 6 | `212` | `3.65s` | +| 7 | `216` | `3.07s` | +| 8 | `223` | `2.57s` | +| 9 | `226` | `2.14s` | +| 10 | `233` | `1.84s` | +| 11 | `237` | `1.61s` | +| 12 | `243` | `1.43s` | +| 13 | `249` | `1.28s` | +| 14 | `254` | `1.19s` | + + diff --git a/README.rst b/README.rst deleted file mode 100644 index fa58202..0000000 --- a/README.rst +++ /dev/null @@ -1,203 +0,0 @@ -.. image:: ./covertable.png - :alt: covertable logo - -Time is limited. - -It is not realistic to create a test case that satisfies all the multiple factors, -and above all, it is tedious. - -Save time with covertable. It is a flexible pairwise tool to create a two (or more) factor covered combination. - - -Now it has 2 implementations. - -:Python: - - - .. image:: https://badge.fury.io/py/covertable.svg - :target: https://badge.fury.io/py/covertable - - .. image:: https://github.com/walkframe/covertable/actions/workflows/python.yaml/badge.svg - :target: https://github.com/walkframe/covertable/actions/workflows/python.yaml - - `README `__ - - `Code `__ - - -:TypeScript: - - - .. image:: https://badge.fury.io/js/covertable.svg - :target: https://badge.fury.io/js/covertable - - .. image:: https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg - :target: https://github.com/walkframe/covertable/actions/workflows/typescript.yaml - - `README `__ - - `Code `__ - - -Go see the detail from these links. - -Performance -=================== - -.. note:: - - - The following data was measured in Python 3.7.7 and ``3.1 GHz 6 Cores Intel Core i5``. - - coverage number is `2`. - -.. list-table:: Number and time of combinations. - :widths: 1 3 3 3 - :header-rows: 1 - :stub-columns: 1 - - * - Combination - - Default - - Minimum case - - Fastest case - * - 3^4 - - - num: ``9`` - - cond: *default* - - time: ``0.0006s`` - - - num: ``9`` - - cond: *default* - - time: ``0.0006s`` - - - num: ``14`` - - cond: ``sorter: random, criterion: simple`` - - time: ``0.0005s`` - * - 3^13 - - - num: ``19`` - - cond: *default* - - time: ``0.03s`` - - - num: ``17`` - - cond: ``seed: 1084`` - - time: ``0.03s`` - - - num: ``21`` - - cond: ``sorter: random, criterion: simple`` - - time: ``0.003s`` - * - 4^15 + 3^17 + 2^29 - - - num: ``36`` - - cond: *default* - - time: ``7.41s`` - - - num: ``34`` - - cond: ``seed: 19`` - - time: ``7.47s`` - - - num: ``42`` - - cond: ``sorter: random, criterion: simple`` - - time: ``0.40s`` - * - 4^1 + 3^39 + 2^35 - - - num: ``27`` - - cond: *default* - - time: ``15.19s`` - - - num: ``26`` - - cond: ``seed: 14`` - - time: ``14.70s`` - - - num: ``30`` - - cond: ``sorter: random, criterion: simple`` - - time: ``0.51s`` - * - 2^100 - - - num: ``14`` - - cond: *default* - - time: ``23.97s`` - - - num: ``12`` - - cond: ``seed: 6, criterion: simple`` - - time: ``0.63s`` - - - num: ``13`` - - cond: ``sorter: random, criterion: simple`` - - time: ``0.48s`` - * - 10^20 - - - num: ``198`` - - cond: *default* - - time: ``14.28s`` - - - num: ``195`` - - cond: ``seed: 1139`` - - time: ``14.48s`` - - - num: ``284`` - - cond: ``sorter: random, criterion: simple`` - - time: ``0.53s`` - -In general, as the number of elements or coverage increases, -the number of combinations have a tendency to increase significantly. - -Tolerance ----------------- - -If you use `greedy` criterion and specify a positive integer to `tolerance` option, -it can increase the speed at the expense of the number of combinations. - -The greater the `tolerance`, the shorter the speed and bigger the number of combinations. - -.. list-table:: Table for the case when combinations are created from ``10^20`` test cases. - :widths: 1 3 3 - :header-rows: 1 - :stub-columns: 1 - - * - tolerance - - num - - time - * - 0 (default) - - ``195`` - - ``14.48s`` - * - 1 - - ``199`` - - ``12.45s`` - * - 2 - - ``201`` - - ``9.48s`` - * - 3 - - ``201`` - - ``7.17s`` - * - 4 - - ``207`` - - ``5.70s`` - * - 5 - - ``212`` - - ``4.58s`` - * - 6 - - ``212`` - - ``3.65s`` - * - 7 - - ``216`` - - ``3.07s`` - * - 8 - - ``223`` - - ``2.57s`` - * - 9 - - ``226`` - - ``2.14s`` - * - 10 - - ``233`` - - ``1.84s`` - * - 11 - - ``237`` - - ``1.61s`` - * - 12 - - ``243`` - - ``1.43s`` - * - 13 - - ``249`` - - ``1.28s`` - * - 14 - - ``254`` - - ``1.19s`` - - -History -======= -:2.0.x: - - - sorter option was splitted into sorter and criterion. - - - e.g. greedy -> hash sorter + greedy criterion. - - - `greedy` method is much faster than before. - - `greedy` method got an option `tolerance` to balance speed and results. - - - sequenctial sorter was dropped. - - - Because The number of combinations would be huge in TypeScript. - -:1.1.x: - - - Greedy sorter improved in both implementations. - - - It got increased in speed. - -:1.0.x: - - - First release 🎉 diff --git a/python/history.md b/python/history.md new file mode 100644 index 0000000..004b330 --- /dev/null +++ b/python/history.md @@ -0,0 +1,22 @@ +# History + +## 2.1.x +- Add `make_async` function to generate combinations sequentially. + +## 2.0.x + +- The `sorter` option was split into `sorter` and `criterion`. + - e.g., greedy -> hash sorter + greedy criterion. +- The `greedy` method is much faster than before. +- The `greedy` method now includes a `tolerance` option to balance speed and results. +- The sequential sorter was dropped. + - Due to the potential for huge numbers of combinations in TypeScript. + +## 1.1.x + +- The greedy sorter was improved in both implementations. + - Speed has been increased. + +## 1.0.x + +- First release 🎉 diff --git a/typescript/history.md b/typescript/history.md new file mode 100644 index 0000000..810b3a8 --- /dev/null +++ b/typescript/history.md @@ -0,0 +1,38 @@ +# History + +## 2.4.x +- Fixed an issue where preFilter was evaluating and excluding incomplete elements. This is a minor upgrade due to the large scope of the impact. +- Type names are now unified with the Type suffix. + +## 2.3.x +- PictConstraintsLexer was added. ([#37](https://github.com/walkframe/covertable/pull/37)) + - It is a lexer designed to parse PICT constraints. + - It parses constraints written in the PICT format, enabling the evaluation of complex conditions. + - The parsed constraints are then used in the make function to dynamically filter the generated combinations based on the specified rules. + +## 2.2.x +- Speed is increased by expressing combinations of elements as a product of prime numbers. +- Added `SuggestRowType` to infer the row type. + +## 2.1.x +- Speed up processing speed by pre-sorting target pairs. +- Added `makeAsync` function to generate combinations sequentially. + + +## 2.0.x + +- The `sorter` option was split into `sorter` and `criterion`. + - e.g., greedy -> hash sorter + greedy criterion. +- The `greedy` method is much faster than before. +- The `greedy` method now includes a `tolerance` option to balance speed and results. +- The sequential sorter was dropped. + - Due to the potential for huge numbers of combinations in TypeScript. + +## 1.1.x + +- The greedy sorter was improved in both implementations. + - Speed has been increased. + +## 1.0.x + +- First release 🎉 From 89b1b7e69abc26ea6760f6d45420861c70b38bfa Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 20:01:06 +0900 Subject: [PATCH 47/79] update --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 89a2102..9b28e68 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Covertable +# CoverTable ![covertable logo](./covertable.png) @@ -6,11 +6,11 @@ Time is limited. Creating a test case that satisfies all possible factors is often unrealistic and, more importantly, tedious. -Save time with Covertable, a flexible pairwise tool that generates combinations covering two (or more) factors. +Save time with CoverTable, a flexible pairwise tool that generates combinations covering two (or more) factors. ## Implementations -Covertable is available in two implementations, with TypeScript as the primary focus and Python offered as a secondary option. +CoverTable is available in two implementations, with TypeScript as the primary focus and Python offered as a secondary option. ### TypeScript From 3dca4236d55c6a99bc46d4c4198c2c6c11547e96 Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 29 Aug 2024 20:05:06 +0900 Subject: [PATCH 48/79] update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b28e68..0d6fdfc 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ CoverTable is available in two implementations, with TypeScript as the primary f [![NPM Version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) -- [README](https://github.com/walkframe/covertable/blob/master/typescript) +- [README](https://github.com/walkframe/covertable/blob/master/typescript/README.md) - [History](https://github.com/walkframe/covertable/blob/master/typescript/history.md) ### Python (Legacy Support) From 3288393517f160102f3c598d423a0b7bb9185a5d Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 1 Sep 2024 05:17:39 +0900 Subject: [PATCH 49/79] update link --- typescript/README.md | 203 ++-------------------------------------- typescript/package.json | 2 +- 2 files changed, 9 insertions(+), 196 deletions(-) diff --git a/typescript/README.md b/typescript/README.md index f6da668..134dd77 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -1,31 +1,20 @@ [![npm version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) [![Workflow](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) [![codecov](https://codecov.io/gh/walkframe/covertable/branch/master/graph/badge.svg)](https://codecov.io/gh/walkframe/covertable) +[![github](https://img.shields.io/github/stars/walkframe/covertable)](https://github.com/walkframe/covertable) # What is covertable? covertable is a powerful tool for generating pairwise combinations of input factors, designed for both Node.js and browser environments. It's easy to use, flexible, and supports advanced filtering options, making it perfect for testing scenarios and generating comprehensive datasets. -# Installation - -```sh -$ npm install covertable --save -``` - -# Usage - -## Simple usage in Node.js: +# Simple usage ```javascript -var covertable = require('covertable'); -var make = covertable.make; - -var machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; -var os = ["iOS", "Android"]; -var browser = ["FireFox", "Chrome", "Safari"]; - +import { make } from "covertable"; +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; make([machine, os, browser]); ``` -Output: ```javascript [ @@ -47,181 +36,5 @@ Output: ] ``` -Of course, it also works in the browser well. - -## Advanced usage in TypeScript: - -As previously mentioned, when elements are specified as an array, the results will also be in array form. However, if the elements are specified as an object, the results will be in object form. - -The following example uses preFilter and postFilter to apply constraints to the output results. In this case, `SuggestRowType` can also be used to infer the type of row parameters that the filter function receives. - -```typescript -import { make, sorters, criteria, SuggestRowType, DictType } from "covertable"; - -const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; -const os = ["iOS", "Android"]; -const browser = ["FireFox", "Chrome", "Safari"]; - -const factors = {machine, os, browser}; - -make(factors, { // optional - length: 2, - // SuggestRowType is { machine: string, os: string, browser: string } - preFilter: (row: SuggestRowType) => !(row.os === 'Android' && row.machine !== 'Pixel'), // default: null - // Or DictType that is { [key: string]: any } - postFilter: (row: DictType) => !(row.os === 'iOS' && row.browser !== 'Safari'), // default: null -}); -``` - -Then the output will change as follows: - -```typescript -[ // filtered - { machine: 'Pixel', os: 'Android', browser: 'FireFox' }, - { machine: 'iPhone', os: 'iOS', browser: 'Safari' }, - { machine: 'Galaxy', browser: 'Safari', os: 'iOS' }, - { machine: 'Pixel', browser: 'Safari', os: 'iOS' }, - { machine: 'ZenFone', browser: 'Safari', os: 'iOS' }, - { machine: 'XPERIA', browser: 'Safari', os: 'iOS' } -] -``` - -You can use also `makeAsync` function (generator). -- It receives the same arguments with `make` function. -- It returns the row at the time it's made. - -```js -import { makeAsync } from "covertable"; - -for await (const row of makeAsync([machine, os, browser])) { - console.log(row); -} -``` - -## Options -The `covertable.make` function accepts an options object as its second argument. Here are the available options: - -### length -Number of factors to be covered. (default: 2) - -Obviously the more it increases, the more number of combinations increases. - -### sorter -Determines the order of combinations. - -- sorters.random: Generates different combinations each time. (fastest) -- sorters.hash: Uses a hash-based method for reproducibility. (default) - - - It receives `seed`. - - `seed` option decides the order of storing from unstored pairs. - - When the combination of factors and seed are the same, covertable reproduces the same collective. - -### criterion -Determines the efficiency of combinations. - -- `criteria.simple`: Quickly generates combinations. -- `criteria.greedy`: Attempts to minimize the number of combinations, but is more time-intensive. (default) - - It receives [tolerance](https://github.com/walkframe/covertable#tolerance) option. - -While `criteria.simple` processes quickly, `criteria.greedy` makes fewer combinations. -Although the latter is superior to former in terms of fewer combinations generally, it is time-intensive process. - -Not relevant options will be ignored. - -### preFilter -Function to filter combinations before they are registered. - -When the function returns `false`, the row combination will not be registered. -- If factors type is `Array`, you should specify an index at the subscript like `row => row[1] < 6`. -- If factors type is `Object`, you should specify a key at the subscript like `row => row.month < 6` or `row => row['month'] < 6` - -### postFilter -Function to filter combinations after they are generated. - -The usage is the same as `preFilter`, only the difference is the timing of the call. -It will delete rows not matched this function at the last. - -For this reason, the final test cases may not satisfy the factors coverage. - -### PictConstraintsLexer - -Filter functions can also be generated using PictConstraintsLexer. Use as follows -This function is supported only in the typescript version. - -```js -import { make, PictConstraintsLexer } from "covertable"; - -const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; -const os = ["iOS", "Android"]; -const browser = ["FireFox", "Chrome", "Safari"]; - -const lexer = new PictConstraintsLexer( - ` - IF [machine] = "iPhone" THEN [os] = "iOS"; - IF [os] = "iOS" THEN [machine] = "iPhone"; - `, true -); - -make({machine, os, browser}, { // optional - preFilter: lexer.filter, -}); -``` - -```js -[ - { machine: 'ZenFone', browser: 'FireFox', os: 'Android' }, - { os: 'Android', browser: 'Safari', machine: 'Pixel' }, - { machine: 'Galaxy', browser: 'Chrome', os: 'Android' }, - { machine: 'XPERIA', os: 'Android', browser: 'FireFox' }, - { machine: 'Pixel', browser: 'Chrome', os: 'Android' }, - { os: 'iOS', browser: 'FireFox', machine: 'iPhone' }, - { machine: 'Pixel', browser: 'FireFox', os: 'Android' }, - { os: 'iOS', browser: 'Chrome', machine: 'iPhone' }, - { machine: 'Galaxy', browser: 'Safari', os: 'Android' }, - { machine: 'ZenFone', browser: 'Chrome', os: 'Android' }, - { os: 'iOS', browser: 'Safari', machine: 'iPhone' }, - { machine: 'Galaxy', browser: 'FireFox', os: 'Android' }, - { machine: 'XPERIA', browser: 'Chrome', os: 'Android' }, - { machine: 'ZenFone', browser: 'Safari', os: 'Android' }, - { machine: 'XPERIA', browser: 'Safari', os: 'Android' } -] -``` - -This feature acts as a conversion tool that enables the implementation of PICT constraint conditions within CoverTable, -allowing users to seamlessly apply complex constraints to their test data generation. - - -# Requirements - -ES2015 or later - -- [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) -- [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) -- [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) -- [Object.keys](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) -- [Object.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) - -# Development - -```sh -$ npm install -``` - -## Testing -```sh -$ npm test -- --coverage -``` - -## Publish - -```sh -$ # npm adduser -$ npm run build -$ npm version patch -$ npm publish -``` - -# More information - -- [walkframe/covertable - GitHub](https://github.com/walkframe/covertable) +# Advanced usage +Advanced usage is [here](https://docs.walkframe.com/covertable/advanced) \ No newline at end of file diff --git a/typescript/package.json b/typescript/package.json index b948fbb..c96254e 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -2,7 +2,7 @@ "name": "covertable", "version": "2.4.0", "description": "A flexible pairwise tool written in TypeScript", - "homepage": "https://github.com/walkframe/covertable", + "homepage": "https://docs.walkframe.com/covertable", "repository": { "type": "git", "url": "git+https://github.com/walkframe/covertable.git" From 6b06f52003b3045cbd0b3c4220554b495247eb6a Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 1 Sep 2024 05:20:27 +0900 Subject: [PATCH 50/79] 2.4.1 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index ae7f173..294c1ca 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.4.0", + "version": "2.4.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.4.0", + "version": "2.4.1", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index c96254e..2ad6e2e 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.4.0", + "version": "2.4.1", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://docs.walkframe.com/covertable", "repository": { From 636eae7d0cdafa218a868ff1319aa68d1a2810c6 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 17 Mar 2025 22:03:17 +0900 Subject: [PATCH 51/79] feat: Controller and progress --- typescript/src/controller.ts | 61 +++++++++++++++++++++++++++--------- typescript/src/index.ts | 41 +++++------------------- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index 03820e8..0bf4b0f 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -1,4 +1,4 @@ - +import greedy from "./criteria/greedy"; import hash from "./sorters/hash"; import { range, @@ -58,13 +58,15 @@ export class Controller { private parents: ParentsType = new Map(); private indices: IndicesType = new Map(); public incomplete: PairByKeyType = new Map(); + private numAllChunks: number = 0; private rejected: Set = new Set(); public row: Row; - constructor(public factors: FactorsType, public options: OptionsType) { + constructor(public factors: FactorsType, public options: OptionsType = {}) { this.serialize(factors); this.setIncomplete(); + this.numAllChunks = this.incomplete.size; this.row = new Row([]); this.factorLength = len(factors); this.factorIsArray = factors instanceof Array; @@ -112,7 +114,7 @@ export class Controller { } } - setPair(pair: PairType) { + private setPair(pair: PairType) { for (let [key, value] of this.getCandidate(pair)) { this.row.set(key, value); } @@ -122,7 +124,7 @@ export class Controller { } } - consume(pair: PairType) { + public consume(pair: PairType) { const pairKey = unique(pair); const deleted = this.incomplete.delete(pairKey); if (deleted) { @@ -130,12 +132,12 @@ export class Controller { } } - getCandidate(pair: PairType) { + public getCandidate(pair: PairType) { return getCandidate(pair, this.parents); } // Returns a negative value if it is unknown if it can be stored. - storable(candidate: CandidateType) { + public storable(candidate: CandidateType) { let num = 0; for (let [key, el] of candidate) { let existing: number | undefined = this.row.get(key); @@ -165,11 +167,11 @@ export class Controller { return num; } - isFilled(row: Row): boolean { + public isFilled(row: Row): boolean { return row.size === this.factorLength; } - toMap(row: Row): Map { + private toMap(row: Row): Map { const result: Map = new Map(); for (let [key, serial] of row.entries()) { const index = this.indices.get(serial) as number; @@ -180,7 +182,7 @@ export class Controller { return result; } - toProxy(row: Row) { + private toProxy(row: Row) { const obj: DictType = {}; for (let [key, value] of this.toMap(row).entries()) { obj[key] = value; @@ -188,7 +190,7 @@ export class Controller { return new Proxy(obj, proxyHandler) as SuggestRowType; } - toObject(row: Row) { + private toObject(row: Row) { const obj: DictType = {}; for (let [key, value] of this.toMap(row).entries()) { obj[key] = value; @@ -196,19 +198,19 @@ export class Controller { return obj as SuggestRowType; } - reset() { + private reset() { this.row.consumed.forEach((pair, pairKey) => { this.incomplete.set(pairKey, pair); }); this.row = new Row([]); } - discard() { + private discard() { this.rejected.add(this.row.getPairKey()); this.row = new Row([]); } - restore() { + private restore() { const row = this.row; this.row = new Row([]); if (this.factorIsArray) { @@ -220,7 +222,7 @@ export class Controller { return this.toObject(row); } - close() { + private close() { const trier = new Row([...this.row.entries()]); const kvs = getItems(this.serials); for (let [k, vs] of kvs) { @@ -274,4 +276,35 @@ export class Controller { throw e; } } + + get progress() { + return 1 - this.incomplete.size / this.numAllChunks; + } + + public *makeAsync(): Generator, void, unknown> { + const {criterion = greedy, postFilter} = this.options; + do { + for (let pair of criterion(this)) { + if (this.isFilled(this.row)) { + break; + } + this.setPair(pair); + } + try { + const complete = this.close(); + if (complete) { + if (!postFilter || postFilter(this.toObject(this.row))) { + yield this.restore() as SuggestRowType; + } else { + this.discard(); + } + } + } catch (e) { + if (e instanceof NeverMatch) { + break; + } + throw e; + } + } while (this.incomplete.size); + } } diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 9a78f72..2b86560 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -8,41 +8,13 @@ import simple from "./criteria/simple"; import {PictConstraintsLexer} from "./utils/pict"; import { FactorsType, OptionsType, SuggestRowType, DictType, ListType } from "./types"; import { Controller } from "./controller"; -import { NeverMatch } from "./exceptions"; const makeAsync = function* ( factors: T, options: OptionsType = {} -) { - const { - criterion = greedy, - postFilter, - } = options; - +): Generator, void, unknown> { const ctrl = new Controller(factors, options); - do { - for (let pair of criterion(ctrl)) { - if (ctrl.isFilled(ctrl.row)) { - break; - } - ctrl.setPair(pair); - } - try { - const complete = ctrl.close(); - if (complete) { - if (!postFilter || postFilter(ctrl.toObject(ctrl.row))) { - yield ctrl.restore() as SuggestRowType; - } else { - ctrl.discard(); - } - } - } catch (e) { - if (e instanceof NeverMatch) { - break; - } - throw e; - } - } while (ctrl.incomplete.size); + yield* ctrl.makeAsync(); }; const make = (factors: T, options: OptionsType = {}) => { @@ -53,15 +25,16 @@ const sorters = { hash, random }; const criteria = { greedy, simple }; export { - make, - makeAsync, - sorters, + make, + makeAsync, + sorters, criteria, PictConstraintsLexer, + Controller, }; export type { - OptionsType, + OptionsType, SuggestRowType, DictType, ListType, From 268793a1431608cb7ab3de1133ab5a2b270d3c2c Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 17 Mar 2025 22:04:31 +0900 Subject: [PATCH 52/79] v2.5.0 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 294c1ca..a3e63f0 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.4.1", + "version": "2.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.4.1", + "version": "2.5.0", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index 2ad6e2e..aa4a37e 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.4.1", + "version": "2.5.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://docs.walkframe.com/covertable", "repository": { From 09c6755896df4c5cc6b561e455e9687b9e5f4f72 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 17 Mar 2025 22:38:21 +0900 Subject: [PATCH 53/79] fix: 0div --- typescript/src/controller.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index 0bf4b0f..70d4aa9 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -278,6 +278,9 @@ export class Controller { } get progress() { + if (this.numAllChunks === 0) { + return 0; + } return 1 - this.incomplete.size / this.numAllChunks; } From abcbf43542dedad83846c24d18735d5124286c36 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 17 Mar 2025 22:38:39 +0900 Subject: [PATCH 54/79] v2.5.1 --- typescript/package-lock.json | 4 ++-- typescript/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index a3e63f0..6cab470 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "covertable", - "version": "2.5.0", + "version": "2.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.5.0", + "version": "2.5.1", "license": "Apache-2.0", "dependencies": { "js-md5": "^0.7.3" diff --git a/typescript/package.json b/typescript/package.json index aa4a37e..64b9f9d 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.5.0", + "version": "2.5.1", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://docs.walkframe.com/covertable", "repository": { From 90611d06e56c3c776d40cf3fa7256e2c932c0433 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 28 Mar 2025 20:17:15 +0900 Subject: [PATCH 55/79] fix: consume row pairs when the prefilter does not match. --- typescript/package.json | 2 +- typescript/src/controller.ts | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/typescript/package.json b/typescript/package.json index 64b9f9d..190d03a 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.5.1", + "version": "2.5.2", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://docs.walkframe.com/covertable", "repository": { diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index 70d4aa9..80544c1 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -131,6 +131,11 @@ export class Controller { this.row.consumed.set(pairKey, pair); } } + public consumeRow(row: Row) { + for (let pair of combinations([...row.values()], this.pairwiseCount)) { + this.consume(pair); + } + } public getCandidate(pair: PairType) { return getCandidate(pair, this.parents); @@ -156,6 +161,7 @@ export class Controller { try { const ok = this.options.preFilter(proxy); if (!ok) { + this.consumeRow(nxt); return null; } } catch (e) { @@ -206,7 +212,8 @@ export class Controller { } private discard() { - this.rejected.add(this.row.getPairKey()); + const pairKey = this.row.getPairKey(); + this.rejected.add(pairKey); this.row = new Row([]); } @@ -268,7 +275,7 @@ export class Controller { } const proxy = this.toProxy(this.row); try { - return this.options.preFilter ? this.options.preFilter(proxy) : true; + return this.options.preFilter?.(proxy) ?? true; } catch (e) { if (e instanceof NotReady) { return false; @@ -284,7 +291,7 @@ export class Controller { return 1 - this.incomplete.size / this.numAllChunks; } - public *makeAsync(): Generator, void, unknown> { + public *makeAsync() { const {criterion = greedy, postFilter} = this.options; do { for (let pair of criterion(this)) { @@ -309,5 +316,6 @@ export class Controller { throw e; } } while (this.incomplete.size); + this.incomplete.clear(); } } From 32c4d24851d886139a7d9d6d0c4bbf7a4cc29c1c Mon Sep 17 00:00:00 2001 From: righ Date: Thu, 9 Apr 2026 01:56:39 +0900 Subject: [PATCH 56/79] feat: use fnv1a32 for hash --- .gitignore | 1 + README.md | 19 ++ python/covertable/__init__.py | 2 +- python/covertable/criteria/greedy.py | 36 +-- python/covertable/criteria/simple.py | 9 +- python/covertable/exceptions.py | 10 + python/covertable/lib.py | 34 +++ python/covertable/main.py | 341 ++++++++++++++++++--------- python/covertable/sorters/hash.py | 25 +- python/covertable/sorters/random.py | 8 +- python/tests.py | 8 +- typescript/package-lock.json | 32 +-- typescript/package.json | 5 +- typescript/src/lib.ts | 10 +- typescript/src/sorters/hash.ts | 4 +- 15 files changed, 355 insertions(+), 189 deletions(-) create mode 100644 .gitignore create mode 100644 python/covertable/lib.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f421fb3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +python/.venv diff --git a/README.md b/README.md index 0d6fdfc..8151999 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,23 @@ Creating a test case that satisfies all possible factors is often unrealistic an Save time with CoverTable, a flexible pairwise tool that generates combinations covering two (or more) factors. +## Algorithm + +CoverTable uses a **one-test-at-a-time greedy algorithm** to generate covering arrays. + +1. Assigns a unique prime number ID to each factor value, then enumerates all n-way combinations to be covered. +2. For each test row, the **criterion** selects the most efficient uncovered combination to include next by evaluating how many other uncovered combinations it would simultaneously satisfy. +3. Repeats until all combinations are covered. + +Two criteria are available: + +- **Greedy** (default): Evaluates coverage efficiency for candidate pairs and selects the one that maximizes coverage. The `tolerance` parameter allows trading quality for speed. +- **Simple**: Picks the first feasible pair without efficiency evaluation. Faster, but produces more test cases. + +Additionally, **sorters** (Hash / Random) control the initial ordering of combinations, which influences the quality and reproducibility of the output. + +See also: [Pairwise Testing Tool Comparison](https://www.pairwise.org/efficiency.html) + ## Implementations CoverTable is available in two implementations, with TypeScript as the primary focus and Python offered as a secondary option. @@ -16,6 +33,8 @@ CoverTable is available in two implementations, with TypeScript as the primary f [![NPM Version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) +Works in both **Node.js** and **browsers** (UMD build). + - [README](https://github.com/walkframe/covertable/blob/master/typescript/README.md) - [History](https://github.com/walkframe/covertable/blob/master/typescript/history.md) diff --git a/python/covertable/__init__.py b/python/covertable/__init__.py index 8bf1d35..0a88194 100644 --- a/python/covertable/__init__.py +++ b/python/covertable/__init__.py @@ -1 +1 @@ -from .main import make, sorters +from .main import make, make_async, sorters, criteria, Controller diff --git a/python/covertable/criteria/greedy.py b/python/covertable/criteria/greedy.py index 27953be..a1dffb0 100644 --- a/python/covertable/criteria/greedy.py +++ b/python/covertable/criteria/greedy.py @@ -1,46 +1,52 @@ -import hashlib -from collections import defaultdict from itertools import combinations +from ..lib import unique def get_num_removable_pairs(indexes, incomplete, length): - removing_keys = combinations(indexes, length) - return len(incomplete.intersection(removing_keys)) + num = 0 + for pair in combinations(sorted(indexes), length): + key = unique(pair) + if key in incomplete: + num += 1 + return num -def extract( - sorted_incomplete, row, parents, length, incomplete, tolerance=0, **kwargs -): +def extract(ctrl): while True: max_num_pairs = None efficient_pair = None - for pair in sorted_incomplete: - if not row: + for pair_key, pair in list(ctrl.incomplete.items()): + row_size = len(ctrl.row) + if row_size == 0: yield pair continue - if row.filled(): + if ctrl.is_filled(): break - storable = row.storable([(parents[p], p) for p in pair]) + storable = ctrl.storable(ctrl.get_candidate(pair)) if storable is None: continue if storable == 0: + ctrl.consume(pair) continue + storable_abs = abs(storable) num_pairs = get_num_removable_pairs( - sorted({*row.values(), *pair}), incomplete, length + set(list(ctrl.row.values()) + list(pair)), + ctrl.incomplete, + ctrl.length, ) - if num_pairs + tolerance > len(row) * storable: + + if num_pairs + ctrl.tolerance > row_size * storable_abs: efficient_pair = pair break if max_num_pairs is None or max_num_pairs < num_pairs: max_num_pairs = num_pairs efficient_pair = pair - if not efficient_pair: + if efficient_pair is None: break - yield efficient_pair diff --git a/python/covertable/criteria/simple.py b/python/covertable/criteria/simple.py index 66517a8..fe72903 100644 --- a/python/covertable/criteria/simple.py +++ b/python/covertable/criteria/simple.py @@ -1,6 +1,7 @@ -def extract(sorted_incomplete, row, parents, **kwargs): - for pair in sorted_incomplete: - storable = row.storable([(parents[p], p) for p in pair]) - if storable is None: +def extract(ctrl): + for pair_key, pair in list(ctrl.incomplete.items()): + cand = ctrl.get_candidate(pair) + storable = ctrl.storable(cand) + if storable is None or storable == 0: continue yield pair diff --git a/python/covertable/exceptions.py b/python/covertable/exceptions.py index a919571..b89218f 100644 --- a/python/covertable/exceptions.py +++ b/python/covertable/exceptions.py @@ -1,2 +1,12 @@ class InvalidCondition(BaseException): message = "It will never meet the condition" + + +class NotReady(Exception): + def __init__(self, key): + super().__init__(f"Not yet '{key}' in the object") + self.key = key + + +class NeverMatch(Exception): + pass diff --git a/python/covertable/lib.py b/python/covertable/lib.py new file mode 100644 index 0000000..41795f2 --- /dev/null +++ b/python/covertable/lib.py @@ -0,0 +1,34 @@ +from functools import reduce +from operator import mul + + +def get_items(container): + if isinstance(container, list): + return list(enumerate(container)) + elif isinstance(container, dict): + return list(container.items()) + else: + raise TypeError("factors must be list or dict.") + + +def prime_generator(): + yield 2 + cand = 3 + while True: + is_prime = True + i = 3 + while i * i <= cand: + if cand % i == 0: + is_prime = False + break + i += 2 + if is_prime: + yield cand + cand += 2 + + +def unique(pair): + total = reduce(mul, pair, 1) + if total <= 2**53: + return total + return str(tuple(sorted(pair))) diff --git a/python/covertable/main.py b/python/covertable/main.py index 7d86b9b..4300912 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -2,95 +2,238 @@ from . import sorters from . import criteria -from .exceptions import InvalidCondition +from .exceptions import NotReady, NeverMatch +from .lib import get_items, prime_generator, unique -def get_items(container): - if isinstance(container, list): - return enumerate(container) - elif isinstance(container, dict): - return container.items() - else: - raise TypeError("factors must be list or dict.") +class ProxyRow(dict): + """Dict-like object that raises NotReady for missing keys.""" + def __getitem__(self, key): + if key not in self: + raise NotReady(key) + return super().__getitem__(key) -def convert_factors_to_serials(factors): - items = get_items(factors) - origin = 0 - serials, parents = factors.copy(), {} - for subscript, factor_list in items: - length = len(factor_list) - serial_list = [] - for serial in range(origin, origin + length): - serial_list.append(serial) - parents[serial] = subscript - serials[subscript] = serial_list - origin += length - return serials, parents +class Row(dict): + def __init__(self, entries=None): + super().__init__(entries or {}) + self.consumed = {} + def get_pair_key(self, *new_pair): + pair = list(self.values()) + list(new_pair) + return unique(pair) -def make_incomplete(serials, length): - incomplete = set() - for keys in combinations([k for k, _ in get_items(serials)], length): - for pair in product(*[serials[keys[i]] for i in range(length)]): - incomplete.add(pair) - return incomplete + def copy_from(self, other): + self.update(other) -class Row(dict): - def __init__(self, row, factors, serials, pre_filter): - super().__init__(row or {}) - self.type = type(factors) +class Controller: + def __init__(self, factors, length=2, sorter=None, criterion=None, + seed="", tolerance=0, pre_filter=None, post_filter=None): self.factors = factors - self.serials = serials + self.length = length + self.sorter = sorter or sorters.hash + self.criterion = criterion or criteria.greedy + self.seed = seed + self.tolerance = tolerance self.pre_filter = pre_filter + self.post_filter = post_filter + + self.serials = {} + self.parents = {} + self.indices = {} + self.incomplete = {} + self.rejected = set() + self.row = Row() + + self.factor_length = len(factors) + self.factor_is_list = isinstance(factors, list) + + self._serialize(factors) + self._set_incomplete() + self._num_all_chunks = len(self.incomplete) + + # Delete initial pairs that do not satisfy pre_filter + for pair_key in list(self.incomplete.keys()): + pair = self.incomplete[pair_key] + cand = self.get_candidate(pair) + s = self.storable(cand) + if s is None: + self.incomplete.pop(pair_key, None) + + def _serialize(self, factors): + origin = 0 + primer = prime_generator() + for subscript, elements in get_items(factors): + length = len(elements) + serial_list = [] + for index in range(origin, origin + length): + serial = next(primer) + serial_list.append(serial) + self.parents[serial] = subscript + self.indices[serial] = index + self.serials[subscript] = serial_list + origin += length + + def _set_incomplete(self): + pairs = [] + all_keys = [k for k, _ in get_items(self.serials)] + for keys in combinations(all_keys, self.length): + comb = [self.serials[keys[i]] for i in range(self.length)] + for pair in product(*comb): + pair = tuple(sorted(pair)) + pairs.append(pair) + + sorted_pairs = self.sorter.sort(pairs, seed=self.seed, indices=self.indices) + for pair in sorted_pairs: + self.incomplete[unique(pair)] = pair + + def _set_pair(self, pair): + for key, value in self.get_candidate(pair): + self.row[key] = value + for p in combinations(sorted(self.row.values()), self.length): + self.consume(p) - def __getitem__(self, item): - return super().get(item) + def consume(self, pair): + pair_key = unique(pair) + if pair_key in self.incomplete: + del self.incomplete[pair_key] + self.row.consumed[pair_key] = pair - def filled(self): - return len(self) == len(self.factors) + def consume_row(self, row): + for pair in combinations(sorted(row.values()), self.length): + self.consume(pair) - def new(self, row=None): - return Row(row, self.factors, self.serials, self.pre_filter) + def get_candidate(self, pair): + return [(self.parents[p], p) for p in pair] - def storable(self, candidate=[]): + def storable(self, candidate): num = 0 for key, el in candidate: - _el = self.get(key) - if _el is None: + existing = self.row.get(key) + if existing is None: num += 1 - elif _el != el: + elif existing != el: return None + if self.pre_filter is None: return num - nxt = self.new({**self, **dict(candidate)}) - if not self.pre_filter(nxt.resolve()): - return None + + candidates = list(self.row.items()) + candidate + nxt = Row(candidates) + proxy = self._to_proxy(nxt) + try: + ok = self.pre_filter(proxy) + if not ok: + self.consume_row(nxt) + return None + except NotReady: + return -num + except Exception: + raise return num - def complement(self): + def is_filled(self, row=None): + if row is None: + row = self.row + return len(row) == self.factor_length + + def _to_map(self, row): + result = {} + for key, serial in row.items(): + index = self.indices[serial] + first = self.indices[self.serials[key][0]] + result[key] = self.factors[key][index - first] + return result + + def _to_proxy(self, row): + return ProxyRow(self._to_map(row)) + + def _to_object(self, row): + return self._to_map(row) + + def _reset(self): + for pair_key, pair in self.row.consumed.items(): + self.incomplete[pair_key] = pair + self.row = Row() + + def _discard(self): + pair_key = self.row.get_pair_key() + self.rejected.add(pair_key) + for pk, pair in self.row.consumed.items(): + self.incomplete[pk] = pair + self.row = Row() + + def _restore(self): + row = self.row + self.row = Row() + if self.factor_is_list: + m = self._to_map(row) + return [v for _, v in sorted(m.items())] + return self._to_object(row) + + def _close(self): + trier = Row(self.row.items()) for k, vs in get_items(self.serials): for v in vs: - if self.storable([(k, v)]) is not None: - self[k] = v - break - if not self.filled(): - raise InvalidCondition(InvalidCondition.message) - return self + pair_key = trier.get_pair_key(v) + if pair_key in self.rejected: + continue + cand = [(k, v)] + s = self.storable(cand) + if s is None: + self.rejected.add(pair_key) + continue + trier[k] = v + break + self.row.copy_from(trier) + if self.is_complete: + return True + if len(trier) == 0: + return False + pair_key = trier.get_pair_key() + if pair_key in self.rejected: + raise NeverMatch() + self.rejected.add(pair_key) + self._reset() + return False - def resolve(self): - return self.new( - [key, self.factors[key][serial - self.serials[key][0]]] - for key, serial in self.items() - ) + @property + def is_complete(self): + if not self.is_filled(): + return False + if self.pre_filter is None: + return True + proxy = self._to_proxy(self.row) + try: + return bool(self.pre_filter(proxy)) + except NotReady: + return False - def restore(self): - resolved = self.resolve() - if issubclass(self.type, list): - return [r for _, r in sorted(resolved.items())] - if issubclass(self.type, dict): - return dict(resolved) + @property + def progress(self): + if self._num_all_chunks == 0: + return 0 + return 1 - len(self.incomplete) / self._num_all_chunks + + def make_async(self): + while True: + for pair in self.criterion.extract(self): + if self.is_filled(): + break + self._set_pair(pair) + try: + complete = self._close() + if complete: + if self.post_filter is None or self.post_filter(self._to_object(self.row)): + yield self._restore() + else: + self._discard() + except NeverMatch: + break + if not self.incomplete: + break + self.incomplete.clear() def make_async( @@ -101,53 +244,30 @@ def make_async( criterion=criteria.greedy, pre_filter=None, post_filter=None, + seed="", + tolerance=0, **params, ): - serials, parents = convert_factors_to_serials(factors) - incomplete = make_incomplete(serials, length) - len_incomplete = float(len(incomplete)) - md5_cache = {} - - row = Row(None, factors, serials, pre_filter) - # When pre_filter is specified, - # it will be applied to incomplete through `row.storable` beforehand. - for pair in list(filter(lambda _: pre_filter, incomplete)): - if not row.storable([(parents[p], p) for p in pair]): - incomplete.discard(pair) - - while incomplete: - if row.filled(): - if post_filter is None or post_filter(row.resolve()): - yield row.restore() - row = row.new() - - common_kwargs = { - **params, - "row": row, - "parents": parents, - "length": length, - "incomplete": incomplete, - "md5_cache": md5_cache, - } - sorted_incomplete = sorter.sort(**common_kwargs) - for pair in criterion.extract(sorted_incomplete, **common_kwargs): - if row.filled(): - break - row.update((parents[p], p) for p in pair) - for vs in combinations(sorted(row.values()), length): - incomplete.discard(vs) - else: - if not row.filled(): - row.complement() + # backwards compat: extract seed/tolerance from options dict + options = params.pop("options", {}) + if isinstance(options, dict): + seed = options.get("seed", seed) + tolerance = options.get("tolerance", tolerance) + ctrl = Controller( + factors, + length=length, + sorter=sorter, + criterion=criterion, + seed=seed, + tolerance=tolerance, + pre_filter=pre_filter, + post_filter=post_filter, + ) + for row in ctrl.make_async(): if progress: - rate = (len_incomplete - len(incomplete)) / len_incomplete - print("{0:.2%}\r".format(rate), end="") - - if row: - row.complement() - if post_filter is None or post_filter(row.resolve()): - yield row.restore() + print("{0:.2%}\r".format(ctrl.progress), end="") + yield row def make( @@ -158,9 +278,11 @@ def make( criterion=criteria.greedy, pre_filter=None, post_filter=None, + seed="", + tolerance=0, **params, ): - gen = make_async( + return list(make_async( factors, length=length, progress=progress, @@ -168,6 +290,7 @@ def make( criterion=criterion, pre_filter=pre_filter, post_filter=post_filter, + seed=seed, + tolerance=tolerance, **params, - ) - return list(gen) + )) diff --git a/python/covertable/sorters/hash.py b/python/covertable/sorters/hash.py index 4e433d8..98ab799 100644 --- a/python/covertable/sorters/hash.py +++ b/python/covertable/sorters/hash.py @@ -1,18 +1,21 @@ """Hash sorter """ -import hashlib +def fnv1a32(s): + h = 0x811C9DC5 + for c in s.encode("utf-8"): + h ^= c + h = (h * 0x01000193) & 0xFFFFFFFF + return format(h, '08x') -def sort(incomplete, md5_cache, seed="", use_cache=True, *args, **kwargs): - def comparer(v): - if use_cache and v in md5_cache: - return md5_cache[v] - s = "{} {}".format(",".join(map(str, v)), seed) - value = hashlib.md5(s.encode("utf-8")).hexdigest() - if use_cache: - md5_cache[v] = value - return value +def sort(pairs, seed="", indices=None, **kwargs): + def comparer(pair): + if indices: + key = "{} {}".format(",".join(str(indices[n]) for n in pair), seed) + else: + key = "{} {}".format(",".join(str(n) for n in pair), seed) + return fnv1a32(key) - return sorted(incomplete, key=comparer) + return sorted(pairs, key=comparer) diff --git a/python/covertable/sorters/random.py b/python/covertable/sorters/random.py index 8851b1f..a1eec4e 100644 --- a/python/covertable/sorters/random.py +++ b/python/covertable/sorters/random.py @@ -4,9 +4,5 @@ import random -def random_comparer(_): - return random.random() - - -def sort(incomplete, *args, **kwargs): - return sorted(incomplete, key=random_comparer) +def sort(pairs, **kwargs): + return sorted(pairs, key=lambda _: random.random()) diff --git a/python/tests.py b/python/tests.py index b553dea..753193f 100644 --- a/python/tests.py +++ b/python/tests.py @@ -71,7 +71,7 @@ def pre_filter(row): for row in rows: assert not all(p in row for p in pair), f"{pair} is in a row: {row}" - def test_pre_filter_never_matching_raises_an_exception(self): + def test_pre_filter_never_matching_makes_no_rows(self): factors = [["a", "b", "c"], ["d", "e"], ["f"]] def pre_filter(row): @@ -79,10 +79,8 @@ def pre_filter(row): return False return True - from covertable.exceptions import InvalidCondition - - with pytest.raises(InvalidCondition): - call(factors, length=2, pre_filter=pre_filter) + rows = call(factors, length=2, pre_filter=pre_filter) + assert not rows def test_post_filter_never_matching_makes_no_rows(self): factors = [["a", "b", "c"], ["d", "e"], ["f"]] diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 6cab470..7924fcd 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,19 +1,15 @@ { "name": "covertable", - "version": "2.5.1", + "version": "2.5.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "covertable", - "version": "2.5.1", + "version": "2.5.2", "license": "Apache-2.0", - "dependencies": { - "js-md5": "^0.7.3" - }, "devDependencies": { "@types/jest": "^25.2.3", - "@types/js-md5": "^0.4.2", "@types/node": "^14.0.9", "codecov": "^3.7.1", "jest": "^26.0.1", @@ -1463,13 +1459,6 @@ "pretty-format": "^25.2.1" } }, - "node_modules/@types/js-md5": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/js-md5/-/js-md5-0.4.2.tgz", - "integrity": "sha512-FUPoQkpQTzA5wz9ebrdVRjsjQsFehr+cW1CVhLcI2UwD/SO/4NHPO1esrXPPbx7ux762U0POmWFSrUjQq2ophw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -6358,12 +6347,6 @@ "node": ">= 10.14.2" } }, - "node_modules/js-md5": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", - "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==", - "license": "MIT" - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10813,12 +10796,6 @@ "pretty-format": "^25.2.1" } }, - "@types/js-md5": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/js-md5/-/js-md5-0.4.2.tgz", - "integrity": "sha512-FUPoQkpQTzA5wz9ebrdVRjsjQsFehr+cW1CVhLcI2UwD/SO/4NHPO1esrXPPbx7ux762U0POmWFSrUjQq2ophw==", - "dev": true - }, "@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -14414,11 +14391,6 @@ "supports-color": "^7.0.0" } }, - "js-md5": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", - "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/typescript/package.json b/typescript/package.json index 190d03a..c17747b 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -60,7 +60,6 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^25.2.3", - "@types/js-md5": "^0.4.2", "@types/node": "^14.0.9", "codecov": "^3.7.1", "jest": "^26.0.1", @@ -72,7 +71,5 @@ "webpack": "^5.93.0", "webpack-cli": "^5.1.4" }, - "dependencies": { - "js-md5": "^0.7.3" - } + "dependencies": {} } diff --git a/typescript/src/lib.ts b/typescript/src/lib.ts index 90e454b..9493f37 100644 --- a/typescript/src/lib.ts +++ b/typescript/src/lib.ts @@ -1,5 +1,3 @@ -// @ts-ignore 2307 -export { hex as md5 } from 'js-md5'; import { NotReady } from './exceptions'; import type { FactorsType, ScalarType, ParentsType, CandidateType, PairType, @@ -139,3 +137,11 @@ export const proxyHandler = { }, }; +export const fnv1a32 = (str: string): string => { + let hash = 0x811c9dc5; + for (let i = 0; i < str.length; i++) { + hash ^= str.charCodeAt(i); + hash = Math.imul(hash, 0x01000193); + } + return (hash >>> 0).toString(16).padStart(8, '0'); +}; diff --git a/typescript/src/sorters/hash.ts b/typescript/src/sorters/hash.ts index be75f52..d84fe7c 100644 --- a/typescript/src/sorters/hash.ts +++ b/typescript/src/sorters/hash.ts @@ -1,4 +1,4 @@ -import {md5} from '../lib'; +import {fnv1a32} from '../lib'; import type { PairType, SortArgsType, @@ -12,7 +12,7 @@ export default function ( const comparer = (a: PairType, b: PairType) => { const aKey = `${a.map((n) => indices.get(n) as number)} ${seed}`; const bKey = `${b.map((n) => indices.get(n) as number)} ${seed}`; - return md5(aKey) > md5(bKey) ? 1 : -1; + return fnv1a32(aKey) > fnv1a32(bKey) ? 1 : -1; } return pairs.sort(comparer); }; From 57bb947e2d6e28ffa471d7736c4ad914fb3e4d90 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 11 Apr 2026 03:58:41 +0900 Subject: [PATCH 57/79] feat: add options for pict --- .tool-versions | 1 + docs/.gitignore | 20 + docs/README.md | 41 + docs/contents/advanced/index.mdx | 57 + docs/contents/advanced/options.mdx | 164 + docs/contents/advanced/pict.mdx | 156 + docs/contents/constraint-logic.mdx | 339 + docs/contents/development/python.mdx | 29 + docs/contents/development/typescript.mdx | 41 + docs/contents/history/index.mdx | 14 + docs/contents/history/migration.mdx | 148 + docs/contents/history/v1.mdx | 15 + docs/contents/history/v2.mdx | 36 + docs/contents/history/v3.mdx | 43 + docs/contents/index.mdx | 152 + docs/contents/tools/generate.worker.ts | 72 + docs/contents/tools/pict-online.mdx | 92 + docs/contents/tools/pict.tsx | 1766 ++ docs/docusaurus.config.ts | 143 + docs/package.json | 64 + docs/pnpm-lock.yaml | 13495 +++++++++++++ docs/sidebars.ts | 29 + .../src/components/HomepageFeatures/index.tsx | 71 + .../HomepageFeatures/styles.module.css | 11 + docs/src/css/custom.css | 145 + docs/src/pages/index.module.css | 23 + docs/src/pages/markdown-page.mdx | 7 + docs/static/.nojekyll | 0 docs/static/img/covertable-social-card.png | Bin 0 -> 19132 bytes docs/static/img/docusaurus-social-card.jpg | Bin 0 -> 55746 bytes docs/static/img/docusaurus.png | Bin 0 -> 5142 bytes docs/static/img/favicon.ico | Bin 0 -> 3626 bytes docs/static/img/logo.svg | 1 + .../static/img/undraw_docusaurus_mountain.svg | 171 + docs/static/img/undraw_docusaurus_react.svg | 170 + docs/static/img/undraw_docusaurus_tree.svg | 40 + docs/tsconfig.json | 16 + python/covertable/criteria/greedy.py | 62 +- python/covertable/evaluate.py | 135 + python/covertable/lib.py | 27 - python/covertable/main.py | 720 +- python/covertable/pict/__init__.py | 10 + python/covertable/pict/lexer.py | 441 + python/covertable/pict/model.py | 248 + python/covertable/pict/parser.py | 175 + python/covertable/pict/weights.py | 31 + python/covertable/sorters/hash.py | 6 +- python/test_pict.py | 393 + python/tests.py | 97 +- typescript/.npmrc | 1 + typescript/jest.config.ts | 8 + typescript/package-lock.json | 16766 ---------------- typescript/package.json | 64 +- typescript/pnpm-lock.yaml | 3862 ++++ typescript/src/__tests__/bench.test.ts | 100 + .../src/__tests__/contradictory.test.ts | 77 + .../src/__tests__/coverage-bench.test.ts | 77 + typescript/src/__tests__/filter.test.ts | 49 +- .../__tests__/forward-check-complex.test.ts | 327 + .../__tests__/forward-check-weakness.test.ts | 243 + .../src/__tests__/forward-check.test.ts | 103 + .../src/__tests__/heavy-coverage.test.ts | 149 + .../src/__tests__/heavy-covertable.test.ts | 85 + typescript/src/__tests__/index.test.ts | 179 +- typescript/src/__tests__/pict.test.ts | 1244 +- typescript/src/__tests__/profile.test.ts | 250 + typescript/src/__tests__/salt-sweep.test.ts | 29 + .../src/__tests__/simple-criterion.test.ts | 176 + .../src/__tests__/typo-constraint.test.ts | 22 + typescript/src/_bench.ts | 35 + typescript/src/controller.ts | 776 +- typescript/src/criteria/greedy.ts | 88 +- typescript/src/evaluate.ts | 133 + typescript/src/exceptions.ts | 13 + typescript/src/index.ts | 28 +- .../{utils/pict.ts => pict/constraints.ts} | 370 +- typescript/src/pict/index.ts | 12 + typescript/src/pict/model.ts | 156 + typescript/src/pict/parameters.ts | 176 + typescript/src/pict/parse.ts | 124 + typescript/src/pict/subModels.ts | 12 + typescript/src/pict/types.ts | 31 + typescript/src/pict/weights.ts | 32 + typescript/src/sorters/hash.ts | 6 +- typescript/src/types.ts | 113 +- typescript/tmp/find_best_seed.ts | 36 + typescript/tsconfig.json | 80 +- typescript/tslint.json | 98 - typescript/vite.config.ts | 20 + typescript/webpack.config.js | 23 - 90 files changed, 28380 insertions(+), 17710 deletions(-) create mode 100644 .tool-versions create mode 100644 docs/.gitignore create mode 100644 docs/README.md create mode 100644 docs/contents/advanced/index.mdx create mode 100644 docs/contents/advanced/options.mdx create mode 100644 docs/contents/advanced/pict.mdx create mode 100644 docs/contents/constraint-logic.mdx create mode 100644 docs/contents/development/python.mdx create mode 100644 docs/contents/development/typescript.mdx create mode 100644 docs/contents/history/index.mdx create mode 100644 docs/contents/history/migration.mdx create mode 100644 docs/contents/history/v1.mdx create mode 100644 docs/contents/history/v2.mdx create mode 100644 docs/contents/history/v3.mdx create mode 100644 docs/contents/index.mdx create mode 100644 docs/contents/tools/generate.worker.ts create mode 100644 docs/contents/tools/pict-online.mdx create mode 100644 docs/contents/tools/pict.tsx create mode 100644 docs/docusaurus.config.ts create mode 100644 docs/package.json create mode 100644 docs/pnpm-lock.yaml create mode 100644 docs/sidebars.ts create mode 100644 docs/src/components/HomepageFeatures/index.tsx create mode 100644 docs/src/components/HomepageFeatures/styles.module.css create mode 100644 docs/src/css/custom.css create mode 100644 docs/src/pages/index.module.css create mode 100644 docs/src/pages/markdown-page.mdx create mode 100644 docs/static/.nojekyll create mode 100644 docs/static/img/covertable-social-card.png create mode 100644 docs/static/img/docusaurus-social-card.jpg create mode 100644 docs/static/img/docusaurus.png create mode 100644 docs/static/img/favicon.ico create mode 100644 docs/static/img/logo.svg create mode 100644 docs/static/img/undraw_docusaurus_mountain.svg create mode 100644 docs/static/img/undraw_docusaurus_react.svg create mode 100644 docs/static/img/undraw_docusaurus_tree.svg create mode 100644 docs/tsconfig.json create mode 100644 python/covertable/evaluate.py create mode 100644 python/covertable/pict/__init__.py create mode 100644 python/covertable/pict/lexer.py create mode 100644 python/covertable/pict/model.py create mode 100644 python/covertable/pict/parser.py create mode 100644 python/covertable/pict/weights.py create mode 100644 python/test_pict.py create mode 100644 typescript/.npmrc create mode 100644 typescript/jest.config.ts delete mode 100644 typescript/package-lock.json create mode 100644 typescript/pnpm-lock.yaml create mode 100644 typescript/src/__tests__/bench.test.ts create mode 100644 typescript/src/__tests__/contradictory.test.ts create mode 100644 typescript/src/__tests__/coverage-bench.test.ts create mode 100644 typescript/src/__tests__/forward-check-complex.test.ts create mode 100644 typescript/src/__tests__/forward-check-weakness.test.ts create mode 100644 typescript/src/__tests__/forward-check.test.ts create mode 100644 typescript/src/__tests__/heavy-coverage.test.ts create mode 100644 typescript/src/__tests__/heavy-covertable.test.ts create mode 100644 typescript/src/__tests__/profile.test.ts create mode 100644 typescript/src/__tests__/salt-sweep.test.ts create mode 100644 typescript/src/__tests__/simple-criterion.test.ts create mode 100644 typescript/src/__tests__/typo-constraint.test.ts create mode 100644 typescript/src/_bench.ts create mode 100644 typescript/src/evaluate.ts rename typescript/src/{utils/pict.ts => pict/constraints.ts} (50%) create mode 100644 typescript/src/pict/index.ts create mode 100644 typescript/src/pict/model.ts create mode 100644 typescript/src/pict/parameters.ts create mode 100644 typescript/src/pict/parse.ts create mode 100644 typescript/src/pict/subModels.ts create mode 100644 typescript/src/pict/types.ts create mode 100644 typescript/src/pict/weights.ts create mode 100644 typescript/tmp/find_best_seed.ts delete mode 100644 typescript/tslint.json create mode 100644 typescript/vite.config.ts delete mode 100644 typescript/webpack.config.js diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..9f36e32 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +nodejs 24.1.0 diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b28211a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +## Installation + +```bash +yarn +``` + +## Local Development + +```bash +yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +## Build + +```bash +yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +## Deployment + +Using SSH: + +```bash +USE_SSH=true yarn deploy +``` + +Not using SSH: + +```bash +GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/docs/contents/advanced/index.mdx b/docs/contents/advanced/index.mdx new file mode 100644 index 0000000..d99d853 --- /dev/null +++ b/docs/contents/advanced/index.mdx @@ -0,0 +1,57 @@ +--- +sidebar_position: 1 +title: Advanced Usage +--- + +# Advanced Usage + +Although covertable works with a minimum number of arguments, several options are available. +This section shows how to use them in detail. + +## Type Inference with Object Factors + +When factors are specified as an object, results will also be in object form. You can use `SuggestRowType` to get full type inference: + +```typescript +import { make, SuggestRowType } from "covertable"; + +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; + +const factors = { machine, os, browser }; + +const rows = make(factors, { + strength: 2, + constraints: [ + // iPhone ↔ iOS + { operator: 'or', conditions: [ + { operator: 'ne', field: 'machine', value: 'iPhone' }, + { operator: 'eq', field: 'os', value: 'iOS' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'eq', field: 'machine', value: 'iPhone' }, + { operator: 'ne', field: 'os', value: 'iOS' }, + ]}, + ], +}); +``` + +## Options Reference + +The `make` function accepts an options object as its second argument: + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `strength` | `number` | `2` | Number of factors to be covered (N-wise). | +| `subModels` | `SubModelType[]` | `undefined` | Apply a different combination strength to a specific group of factors. | +| `weights` | `WeightsType` | `undefined` | Index-keyed weights that bias value selection during row completion. | +| `presets` | `PresetRowType[]` | `undefined` | Rows that must be included in the output. Equivalent to PICT's seeding feature. | +| `constraints` | `Condition[]` | `undefined` | Declarative constraints evaluated under three-valued logic. See [Constraint Logic](/constraint-logic). | +| `comparer` | `Comparer` | `undefined` | Custom comparison functions for constraint evaluation. | +| `sorter` | `Function` | `sorters.hash` | Determines the order of combinations. | +| `criterion` | `Function` | `criteria.greedy` | Determines the algorithm for generating combinations. | +| `salt` | `string \| number` | `""` | Value mixed into `sorters.hash` to control the ordering of pairs. | +| `tolerance` | `number` | `0` | Tolerance used by `criteria.greedy` to trade optimality for speed. | + +See [Options Detail](./options) for full documentation of each option, or [PictModel](./pict) for the PICT-compatible model parser. diff --git a/docs/contents/advanced/options.mdx b/docs/contents/advanced/options.mdx new file mode 100644 index 0000000..2059e6e --- /dev/null +++ b/docs/contents/advanced/options.mdx @@ -0,0 +1,164 @@ +--- +sidebar_position: 2 +title: Options Detail +--- + +# Options Detail + +## `strength` + +Number of factors to be covered. Default is `2` (pairwise). + +:::caution +The more `strength` increases, the more the number of combinations increases exponentially. Use values greater than 2 only when truly needed. +::: + +:::info[Renamed from `length`] +In versions prior to 3.0, this option was called `length`. The semantics are unchanged. +::: + +## `subModels` + +`subModels` lets you apply a different N-wise strength to a specific group of factors, while the rest of the factors stay at the default `strength`. This is the same concept as PICT's [sub-models](https://github.com/microsoft/pict/blob/main/doc/pict.md#sub-models). + +```typescript +import { make } from "covertable"; + +const factors = { + PLATFORM: ["Win", "Mac", "Linux"], + CPUS: ["1", "2", "4"], + RAM: ["512", "1024"], + HDD: ["SATA", "SSD"], +}; + +make(factors, { + strength: 2, + subModels: [ + { keys: ["PLATFORM", "CPUS", "RAM"], strength: 3 }, + ], +}); +``` + +In this example: +- All combinations of `PLATFORM`, `CPUS`, and `RAM` are covered at strength 3. +- Pairs that span the sub-model and other factors (e.g. `PLATFORM x HDD`) are still covered at the default strength of 2. + +## `weights` + +`weights` biases the **completion phase** — the moment covertable picks a value to fill in a column once all required pairs have been satisfied. Higher-weighted values are tried first, so they tend to appear in more rows. + +```typescript +import { make } from "covertable"; + +const factors = { + OS: ["Windows", "Linux", "Mac"], + Browser: ["Chrome", "Firefox", "Safari"], +}; + +make(factors, { + weights: { + Browser: { 0: 10 }, // index 0 = "Chrome" gets weight 10 (default is 1) + }, +}); +``` + +The keys of the inner object are **indices into the factor's value array**. To express weights by value instead, use the [`weightsByValue`](./pict#weightsbyvalue) helper from `covertable/pict`. + +:::info[How weights interact with coverage] +Weights only affect the **completion phase**. The pairwise (or N-wise) coverage requirement is always satisfied first; weights only influence which values are picked when the algorithm has free choice. Setting a weight does not change the minimum number of generated rows. +::: + +## `presets` + +`presets` lets you specify rows that **must appear in the output**. covertable processes them before normal generation, so the pairs they cover are subtracted from the work that the generator has to do — often reducing the total number of generated rows. + +```typescript +import { make } from "covertable"; + +const factors = { + OS: ["iOS", "Android"], + Browser: ["Safari", "Chrome", "Firefox"], + Locale: ["en", "ja", "fr"], +}; + +make(factors, { + presets: [ + { OS: "iOS", Browser: "Safari", Locale: "en" }, + { OS: "Android", Browser: "Chrome" }, + { Browser: "Firefox" }, + ], +}); +``` + +**Behavior:** + +| Case | Result | +|------|--------| +| Full row, satisfies constraints | Output as-is, covered pairs are consumed | +| Partial row, can be completed within constraints | Completed via the normal fill-in logic, then output | +| Row violates constraints (or contains an unknown value) | Silently dropped | +| Row cannot be completed (e.g. constraints leave no valid filler) | Silently dropped | + +:::info[Equivalent to PICT's seeding (`/e:file`)] +PICT calls this feature **seeding** and reads the seed rows from a tab-separated file via the `/e:file.txt` CLI option. covertable's `presets` is the same concept, expressed as plain JavaScript objects so you can compose them programmatically. +::: + +## `constraints` + +Declarative constraints evaluated under Kleene three-valued logic. See [Constraint Logic](/constraint-logic) for full documentation. + +```typescript +make(factors, { + constraints: [ + // IF machine = iPhone THEN os = iOS + { operator: 'or', conditions: [ + { operator: 'ne', field: 'machine', value: 'iPhone' }, + { operator: 'eq', field: 'os', value: 'iOS' }, + ]}, + ], +}); +``` + +## `sorter` + +Determines the order in which combinations are generated. + +| Sorter | Description | +|--------|-------------| +| `sorters.hash` | Uses a hash-based method for **reproducible** results. Accepts a `salt` option. **(default)** | +| `sorters.random` | Generates **different** combinations each time. Fastest option. | + +```typescript +import { make, sorters } from "covertable"; + +make(factors, { sorter: sorters.hash, salt: 42 }); +make(factors, { sorter: sorters.random }); +``` + +:::tip[Salt for Reproducibility] +When using `sorters.hash`, the `salt` option controls the ordering of unstored pairs. When the combination of factors and salt are the same, covertable **reproduces the same result set**. Changing the salt is the easiest way to explore alternative orderings without changing the input factors. +::: + +:::info[Renamed from `seed`] +In versions prior to 3.0, this option was called `seed`. It was renamed to `salt` to avoid confusion with the PICT-style _seeding_ feature (rows that must be included in the output). +::: + +## `criterion` + +Determines the efficiency of the covering algorithm. + +| Criterion | Description | +|-----------|-------------| +| `criteria.greedy` | Attempts to **minimize** the number of combinations, but is more time-intensive. **(default)** | +| `criteria.simple` | **Quickly** generates combinations, but may produce more rows. | + +```typescript +import { make, criteria } from "covertable"; + +make(factors, { criterion: criteria.greedy }); +make(factors, { criterion: criteria.simple }); +``` + +:::info[Greedy Tolerance] +The `criteria.greedy` criterion accepts a `tolerance` option to balance speed and result quality. Higher tolerance trades optimality for faster execution. +::: diff --git a/docs/contents/advanced/pict.mdx b/docs/contents/advanced/pict.mdx new file mode 100644 index 0000000..9924d1d --- /dev/null +++ b/docs/contents/advanced/pict.mdx @@ -0,0 +1,156 @@ +--- +sidebar_position: 3 +title: PictModel +--- + +# PictModel + +`PictModel` parses a complete PICT-format model — parameters, sub-models, and constraints — into a single object that can directly generate rows. It is exported from a separate entry point so it does not bloat the bundle of consumers who only need `make`. + +```typescript +import { PictModel } from "covertable/pict"; + +const model = new PictModel(` +Type: Single, Span, Stripe, Mirror, RAID-5 +Size: 10, 100, 500, 1000, 5000, 10000, 40000 +Format method: Quick, Slow +File system: FAT, FAT32, NTFS +Cluster size: 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 +Compression: On, Off + +IF [File system] = "FAT" THEN [Size] <= 4096; +IF [File system] = "FAT32" THEN [Size] <= 32000; +`); + +const rows = model.make(); +``` + +## Constructor + +```typescript +new PictModel(input: string, options?: PictModelOptions) +``` + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `caseInsensitive` | `boolean` | `true` | When `true` (default, matching PICT), constraint comparisons and alias lookups ignore case. | +| `strict` | `boolean` | `false` | When `true`, the constructor throws `PictModelError` if any error-severity issue is collected. | + +The input string is split into three sections: +1. **Parameters** — `Name: value1, value2, ...` +2. **Sub-models** — `{ A, B, C } @ N` +3. **Constraints** — `IF [P] = "x" THEN [Q] = "y";` or unconditional `[P] <> [Q];` + +## Properties + +| Property | Type | Description | +|----------|------|-------------| +| `parameters` | `Record` | Parsed parameter values (canonical form, with aliases removed). | +| `subModels` | `SubModelType[]` | Parsed sub-model definitions. | +| `constraints` | `(FilterType \| null)[]` | Parsed constraint filters. `null` entries indicate parse failure. | +| `negatives` | `Map>` | Values prefixed with `~` (invalid / negative-test values) per parameter. | +| `weights` | `Record>` | Weights extracted from `(N)` syntax. | +| `issues` | `PictModelIssue[]` | All issues collected during parsing. | +| `progress` | `number` | Coverage progress (0 to 1) during generation. | +| `stats` | `ControllerStats \| null` | Generation statistics (available after `make`/`makeAsync`). | + +## Issues + +```typescript +interface PictModelIssue { + severity: "error" | "warning"; + source: "factor" | "subModel" | "constraint"; + index: number; // 0-based index within the source + line: number; // 1-based line number in the original input + message: string; +} +``` + +```typescript +const model = new PictModel(` +A: 1, 2 +Empty: +`); +model.issues; +// [{ severity: "error", source: "factor", index: 1, line: 3, +// message: 'No values for parameter "Empty"' }] +``` + +## Methods + +| Method | Description | +|--------|-------------| +| `filter(row)` | Returns `true` if the row satisfies all constraints **and** has at most one invalid value. | +| `make(options?)` | Generates rows with the model's parameters, constraints, sub-models, and weights. Accepts the same options as the top-level `make`. | +| `makeAsync(options?)` | Generator version of `make`. | + +## Supported PICT Syntax + +| Feature | Example | Notes | +|---------|---------|-------| +| **Parameter** | `Type: Single, Span, Stripe` | Basic parameter declaration. | +| **Comment** | `# this is a comment` | Lines starting with `#` are skipped. | +| **Quoted strings** | `Msg: "hello, world"` | Required for values containing commas. | +| **Parameter reference** | `B: , extra` | Expands to all of parameter `A`'s values. | +| **Aliases** | `OS: Windows \| Win, Linux` | First value is canonical. Aliases work in constraints. | +| **Invalid values** | `Type: Valid, ~Invalid` | Negative-test value. At most one per row. Output includes `~` prefix. | +| **Weights** | `Browser: Chrome (10), Firefox` | Biases value selection during completion. | +| **Sub-models** | `{ A, B, C } @ 3` | Different N-wise strength for listed parameters. | +| **Conditional** | `IF [A] = 1 THEN [B] = 2;` | Standard PICT-style conditional constraints. | +| **Unconditional** | `[A] <> [B];` | Always-applied invariants. | +| **Comparisons** | `=`, `<>`, `>`, `<`, `>=`, `<=`, `IN`, `LIKE` | All standard PICT operators. | +| **Logical** | `AND`, `OR`, `NOT` | With parentheses for grouping. | + +## Invalid Values (`~`) + +When a value is prefixed with `~`, it is treated as a value that should appear in tests **only one at a time**. PictModel automatically rejects rows containing two or more invalid values. The `~` prefix is preserved in output rows. + +```typescript +const model = new PictModel(` +Age: 20, 30, ~-1, ~999 +Country: Japan, USA, ~"Mars" +`); + +const rows = model.make(); +// { Age: 20, Country: "Japan" } — both valid +// { Age: "~-1", Country: "Japan" } — Age is invalid, Country is valid +// { Age: 20, Country: "~Mars" } — Age is valid, Country is invalid +// { Age: "~-1", Country: "~Mars" } — REJECTED (two invalid values) +``` + +## Aliases + +Aliases provide alternative names for the same value. The first name is canonical (appears in output), while alternates are accepted in constraints. + +```typescript +const model = new PictModel(` +OS: "Windows 10" | Win10, "Mac OS" | Mac, Linux +Result: pass, fail + +IF [OS] IN {"Win10", "Mac"} THEN [Result] = "pass"; +`); +``` + +## `weightsByValue` + +A helper that converts a value-keyed weight map into the index-keyed form expected by `weights`. + +```typescript +import { make } from "covertable"; +import { weightsByValue } from "covertable/pict"; + +const factors = { + Browser: ["Chrome", "Firefox", "Safari"], +}; + +make(factors, { + weights: weightsByValue(factors, { + Browser: { Chrome: 10, Safari: 5 }, + }), + // equivalent to: weights: { Browser: { 0: 10, 2: 5 } } +}); +``` + +:::tip[Try it interactively] +Try the [**Compatible PICT**](/tools/pict) tool to experiment with the constraint syntax in your browser. +::: diff --git a/docs/contents/constraint-logic.mdx b/docs/contents/constraint-logic.mdx new file mode 100644 index 0000000..7d8d34d --- /dev/null +++ b/docs/contents/constraint-logic.mdx @@ -0,0 +1,339 @@ +--- +sidebar_position: 3 +title: Constraint Logic +--- + +# Constraint Logic + +covertable v3 introduces declarative constraints with three-valued (Kleene) logic and forward checking. +This page explains how constraints are evaluated, propagated, and how coverage is guaranteed. + +## Overview + +```mermaid +flowchart TD + subgraph Constructor + A[Parse constraints] --> B[Build pairs] + B --> C[Initial pruning] + C --> C1[storableCheck: direct violations] + C --> C2[forwardCheck: chain violations] + end + + Constructor --> Loop + + subgraph Loop[makeAsync loop] + direction TB + P1[Phase 1: Greedy Selection] + P1 --> SP[setPair] + SP --> EV[evaluate: 3-valued check] + SP --> FC[forwardCheck: propagation] + + P2[Phase 2: Close] + P2 --> BT[Backtracking: fill unfilled factors] + + P3[Phase 3: Rescue] + P3 --> RT[Per-pair retry] + + P1 --> P2 + P2 -->|success| Y[yield row] + P2 -->|failure| P1 + Y -->|incomplete remains| P1 + Y -->|all covered| Done[Done] + P1 -->|no valid pairs| P3 + P3 --> Done + end +``` + +## Three-Valued Evaluation + +Constraints are evaluated under **Kleene three-valued logic**. +When a referenced factor is not yet assigned in the row, the result is `null` rather than `false`. + +| A | B | A AND B | A OR B | NOT A | +|---|---|---------|--------|-------| +| true | true | true | true | false | +| true | false | false | true | false | +| true | null | null | true | null | +| false | true | false | true | true | +| false | false | false | false | true | +| false | null | false | null | true | +| null | true | null | true | null | +| null | false | false | null | null | +| null | null | null | null | null | + +This allows the engine to **reject early** when a constraint is definitively violated, +while **deferring** judgment when information is incomplete. + +```typescript +// Example: IF [Region] = "EU" THEN [Currency] IN {"EUR", "GBP"} +// Expressed as: +{ operator: 'or', conditions: [ + { operator: 'ne', field: 'Region', value: 'EU' }, + { operator: 'in', field: 'Currency', values: ['EUR', 'GBP'] }, +]} + +// Row = { Region: "EU" } → null (Currency not set) +// Row = { Region: "EU", Currency: "USD" } → false (rejected) +// Row = { Region: "EU", Currency: "EUR" } → true (accepted) +// Row = { Region: "US" } → true (Region ≠ EU) +``` + +## Initial Pruning + +Before generation begins, the constructor removes pairs from `incomplete` that can never satisfy constraints. + +**Two-pass pruning:** + +| Pass | Method | Detects | +|------|--------|---------| +| 1 | `storableCheck` | Direct violations — the pair's 2 values alone make a constraint `false` | +| 2 | `forwardCheck` | Chain violations — constraint propagation reveals an empty domain for some factor | + +``` +Example: 53 constraints, 3849 total pairs + ├─ storableCheck removes pairs like (Region=JP, Currency=USD) + │ → IF Region=JP THEN Currency IN {JPY} → false + │ + └─ forwardCheck removes pairs like (Language=de, Currency=USD) + → Language=de → Region=EU → Currency ∈ {EUR,GBP} → USD impossible + → 403 pairs pruned, 3446 feasible pairs remain +``` + +## Forward Check (Constraint Propagation) + +When a value is added to a row, `forwardCheck` determines whether remaining factors +can still be filled without violating constraints. + +### Algorithm + +``` +Input: snapshot (row + new pair) + +1. Build domains: for each unfilled factor, domain = all its values +2. Repeat until no change: + a. For each unfilled factor F: + - Try each value v in F's domain + - Set F=v in tempRow, evaluate F's constraints + - If any constraint → false, remove v from domain + - If domain is empty → return false (infeasible) + - If domain shrinks to 1 value → fix it in tempRow, propagate + b. For multi-value domains, check peer factors: + - For each peer P, compute union of P's surviving values + across all candidates of F + - Narrow P's domain to that union +3. Return true (no contradiction found) +``` + +### Propagation Example + +Given constraints: +- C1: `IF [Language] = "de" THEN [Region] = "EU"` +- C2: `IF [Region] = "EU" THEN [Currency] IN {"EUR", "GBP"}` + +When `setPair(Language=de)` is called, the snapshot is `{ Language: "de" }`. + +**Round 1** — Region (constraint C1: Language=de requires Region=EU) + +| Candidate | C1 result | Survives | +|-----------|-----------|----------| +| Region=EU | true | Yes | +| Region=NA | false | No | +| Region=AP | false | No | +| Region=SA | false | No | + +Region narrows to `{EU}` (1 value) → fixed in tempRow, triggers re-propagation. + +**Round 2** — Currency (constraint C2: Region=EU requires Currency in `{EUR, GBP}`) + +| Candidate | C2 result | Survives | +|-----------|-----------|----------| +| Currency=EUR | true | Yes | +| Currency=USD | false | No | +| Currency=GBP | true | Yes | +| Currency=JPY | false | No | + +Currency narrows to `{EUR, GBP}`. + +**Round 3** — No domain changes → done, return `true`. + +### Peer Propagation + +When a domain remains multi-valued (e.g. B = `{10, 20}`), standard propagation stops +because B is not fixed in tempRow. Peer propagation extends this by checking what +each candidate of B forces on other factors. + +Given constraints: +- C1: `A=1 → B IN {10, 20}` +- C2: `B=10 → C=100` +- C3: `B=20 → C=200` + +Snapshot = `{ A=1, C=300 }`. After standard propagation, B = `{10, 20}` (not fixed). + +**Peer check: what does each B candidate allow for C?** + +| B candidate | C surviving values | +|-------------|-------------------| +| B=10 | `{100}` | +| B=20 | `{200}` | +| **Union** | `{100, 200}` | + +C=300 (from snapshot) is not in `{100, 200}` → C's domain is empty → return `false`. + +Without peer propagation, this contradiction would go undetected until `close()` backtracking. + +## Row Construction Pipeline + +Each row goes through a multi-phase pipeline: + +```mermaid +flowchart TD + Start([incomplete pairs remain]) --> G + + subgraph G[Phase 1: Greedy Selection] + G1[Scan incomplete pairs] --> G2{isCompatible?} + G2 -->|no| G1 + G2 -->|yes| G3{storable?} + G3 -->|no| G1 + G3 -->|yes| G4[Score: getNumRemovablePairs] + G4 --> G5[Select best pair] + end + + G5 --> SP + + subgraph SP[setPair] + SP1[Build snapshot] --> SP2{evaluate constraints} + SP2 -->|false| SP5[Reject: add to invalidPairs] + SP2 -->|true/null| SP3{forwardCheck} + SP3 -->|infeasible| SP5 + SP3 -->|ok| SP4[Commit pair to row] + end + + SP4 -->|row not full| G + SP5 -->|try next pair| G + SP4 -->|row full| CL + + subgraph CL[Phase 2: Close] + CL1[Fill unfilled factors] --> CL2{storable?} + CL2 -->|yes| CL3[Next factor] + CL2 -->|no| CL4[Backtrack] + CL3 --> CL5{All filled?} + CL5 -->|no| CL1 + end + + CL5 -->|yes| Y[consumePairs + yield row] + CL4 -->|exhausted| F[Mark invalidPairs] + F --> G + + Y -->|incomplete remains| Start + Y -->|all covered| Done([Done]) + + Start -->|greedy exhausted| R + + subgraph R[Phase 3: Rescue] + R1[Try each remaining pair] --> R2[setPair + close] + R2 -->|success| R3[yield row] + R2 -->|failure| R1 + end + + R --> Done +``` + +## Statistics + +After generation, `Controller.stats` provides coverage diagnostics: + +| Field | Type | Description | +|-------|------|-------------| +| `totalPairs` | `number` | All factor-value pair combinations before pruning | +| `prunedPairs` | `number` | Pairs removed by constraint-based initial pruning | +| `coveredPairs` | `number` | Pairs successfully covered in generated rows | +| `progress` | `number` | Coverage ratio: `coveredPairs / (totalPairs - prunedPairs)` | +| `rowCount` | `number` | Number of generated rows | +| `uncoveredPairs` | `UncoveredPair[]` | Pairs that could not be covered (with related constraint indices) | +| `completions` | `Record>` | How many times each factor-value was filled by close() | + +```typescript +const ctrl = new Controller(factors, { constraints }); +const rows = ctrl.make(); + +console.log(ctrl.stats); +// { +// totalPairs: 3849, +// prunedPairs: 403, +// coveredPairs: 3446, +// progress: 1, +// rowCount: 64, +// uncoveredPairs: [], +// completions: { +// TaxMode: { Inclusive: 38, Exclusive: 5 }, +// Browser: { Chrome: 38, Safari: 4 }, +// ... +// } +// } +``` + +### Reading the Statistics + +- **`progress < 1`** means some feasible pairs were not covered. Check `uncoveredPairs` for details. +- **High `completions` count** for a factor means it is heavily constrained (close() fills it, not greedy). +- **`prunedPairs`** reflects how many pair combinations are impossible due to constraints. + `totalPairs - prunedPairs` gives the number of feasible pairs. + +## Coverage Guarantee + +covertable guarantees **N-wise coverage for all feasible pairs**: + +``` +feasible pairs = totalPairs - prunedPairs + +if progress = 1.0: + → All feasible pairs are covered in the output rows + → No constraint violations in any row + +if progress < 1.0: + → make() throws NeverMatch with diagnostic info + → Controller.stats.uncoveredPairs lists what couldn't be covered +``` + +:::info +The `make()` convenience function throws `NeverMatch` when coverage is incomplete. +Use `Controller.make()` directly if you want to handle incomplete coverage without exceptions. +::: + +## Constraint Types + +| Type | Example | Description | +|------|---------|-------------| +| `eq` | `{ operator: 'eq', field: 'A', value: 1 }` | Equality with literal | +| `eq` (target) | `{ operator: 'eq', field: 'A', target: 'B' }` | Equality with another field | +| `ne` | `{ operator: 'ne', field: 'A', value: 1 }` | Inequality | +| `gt`, `lt`, `gte`, `lte` | `{ operator: 'gt', field: 'A', value: 5 }` | Comparison operators | +| `in` | `{ operator: 'in', field: 'A', values: [1,2,3] }` | Set membership | +| `not` | `{ operator: 'not', condition: ... }` | Logical negation | +| `and` | `{ operator: 'and', conditions: [...] }` | Logical AND (all must hold) | +| `or` | `{ operator: 'or', conditions: [...] }` | Logical OR (at least one) | +| `custom` | `{ operator: 'custom', keys: ['A','B'], evaluate: fn }` | Escape hatch | + +### Expressing IF-THEN + +PICT-style `IF [A] = x THEN [B] = y` is expressed as: + +```typescript +// IF A THEN B ≡ NOT A OR B +{ operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 'x' }, // NOT A + { operator: 'eq', field: 'B', value: 'y' }, // B +]} +``` + +### Custom Comparer + +Override comparison behavior for specific operators: + +```typescript +const comparer = { + eq: (a, b) => String(a).toLowerCase() === String(b).toLowerCase(), +}; + +const ctrl = new Controller(factors, { constraints, comparer }); +``` diff --git a/docs/contents/development/python.mdx b/docs/contents/development/python.mdx new file mode 100644 index 0000000..a7eb225 --- /dev/null +++ b/docs/contents/development/python.mdx @@ -0,0 +1,29 @@ +--- +sidebar_position: 2 +title: Python +--- + +# Python Development + +The Python implementation lives in `python/`. It provides the same pairwise generation algorithm as the TypeScript version. + +## Setup + +```bash +cd python +pip install -e . +pip install -r dev_requirements.txt +``` + +## Testing + +```bash +pytest +``` + +## Build & Publish + +```bash +python -m build +twine upload dist/* +``` diff --git a/docs/contents/development/typescript.mdx b/docs/contents/development/typescript.mdx new file mode 100644 index 0000000..188a988 --- /dev/null +++ b/docs/contents/development/typescript.mdx @@ -0,0 +1,41 @@ +--- +sidebar_position: 1 +title: TypeScript +--- + +# TypeScript Development + +The TypeScript implementation lives in `typescript/`. It uses [pnpm](https://pnpm.io/) as the package manager and [Vite](https://vitejs.dev/) (library mode) for building. + +## Setup + +```bash +cd typescript +pnpm install +``` + +## Testing + +```bash +pnpm test +``` + +## Build + +```bash +pnpm build +``` + +This produces dual ESM and CJS outputs in `dist/`, along with rolled-up TypeScript declaration files. Two entry points are emitted: + +- `covertable` — the core `make` / `makeAsync` API. +- `covertable/pict` — the `PictModel` class and `weightsByValue` helper, in a separate chunk so consumers who do not need PICT support do not pay for it. + +## Publish + +```bash +# pnpm login +pnpm build +pnpm version patch +pnpm publish +``` diff --git a/docs/contents/history/index.mdx b/docs/contents/history/index.mdx new file mode 100644 index 0000000..571e6b7 --- /dev/null +++ b/docs/contents/history/index.mdx @@ -0,0 +1,14 @@ +--- +sidebar_position: 1 +title: History +--- + +# History + +Release notes for each major version of covertable. + +- [v3.x](./v3) — Current major release with declarative constraints, forward checking, and full PICT compatibility +- [v2.x](./v2) — Added PictConstraintsLexer, performance improvements, makeAsync +- [v1.x](./v1) — Initial release + +For upgrade instructions, see the [Migration Guide](./migration). diff --git a/docs/contents/history/migration.mdx b/docs/contents/history/migration.mdx new file mode 100644 index 0000000..90552e2 --- /dev/null +++ b/docs/contents/history/migration.mdx @@ -0,0 +1,148 @@ +--- +sidebar_position: 5 +title: Migration Guide +--- + +# Migration Guide + +## v2 → v3 + +### Renamed options + +| v2 | v3 | Notes | +|----|------|-------| +| `length` | `strength` | Semantics unchanged | +| `seed` | `salt` | Freed `seed` for PICT-style seeding (now `presets`) | + +```typescript +// v2 +make(factors, { length: 3, seed: 42 }); + +// v3 +make(factors, { strength: 3, salt: 42 }); +``` + +### Default export removed + +```typescript +// v2 +import make from "covertable"; + +// v3 +import { make } from "covertable"; +``` + +### `preFilter` / `postFilter` → `constraints` + +`preFilter` and `postFilter` accepted opaque functions. v3 replaces them with declarative `constraints` that the engine can analyze for three-valued logic and forward checking. + +```typescript +// v2 — opaque function +make(factors, { + preFilter: (row) => !(row.machine === "iPhone" && row.os !== "iOS"), +}); + +// v3 — declarative constraint (IF machine=iPhone THEN os=iOS) +make(factors, { + constraints: [ + { operator: 'or', conditions: [ + { operator: 'ne', field: 'machine', value: 'iPhone' }, + { operator: 'eq', field: 'os', value: 'iOS' }, + ]}, + ], +}); +``` + +:::info[Why declarative?] +Declarative constraints allow the engine to: +- Evaluate under three-valued (Kleene) logic — `null` when a field is not yet set +- Prune infeasible pairs before generation (initial pruning) +- Propagate constraint chains via forward checking +- Detect unsolvable combinations early instead of silently dropping rows + +See [Constraint Logic](/constraint-logic) for details. +::: + +### Replacing `postFilter` + +`postFilter` removed rows **after** generation, which meant coverage was not guaranteed. In v3 there is no direct equivalent — use `constraints` instead whenever possible, as they maintain coverage. + +If you still need to drop rows after generation (accepting the coverage loss), simply filter the result: + +```typescript +// v2 +make(factors, { + postFilter: (row) => !(row.os === "iOS" && row.browser !== "Safari"), +}); + +// v3 — filter after generation +const ctrl = new Controller(factors); +const rows = ctrl.make().filter( + (row) => !(row.os === "iOS" && row.browser !== "Safari") +); + +// Note: ctrl.stats still reflects the pre-filter state. +// The filtered rows may no longer satisfy full pairwise coverage. +``` + +:::warning +Post-filtering removes rows without compensating for lost pair coverage. Prefer declarative `constraints` which guide generation to avoid those rows in the first place. +::: + +### `PictConstraintsLexer` → `PictModel` + +```typescript +// v2 +import { PictConstraintsLexer } from "covertable"; + +// v3 +import { PictModel } from "covertable/pict"; +const model = new PictModel(pictText); +const rows = model.make(); +``` + +`PictModel` handles the full PICT model format: parameters, sub-models, constraints, weights, aliases, and invalid values. + +### `PictModel.errors` → `PictModel.issues` + +```typescript +// v2 +model.errors; // string[] + +// v3 +model.issues; // PictModelIssue[] +// Each issue has: severity, source, index, line, message +``` + +### New: `Controller.stats` + +v3 exposes generation statistics via `Controller`: + +```typescript +import { Controller } from "covertable"; + +const ctrl = new Controller(factors, options); +const rows = ctrl.make(); +console.log(ctrl.stats.progress); // 1 = 100% coverage +console.log(ctrl.stats.prunedPairs); // pairs removed by constraints +console.log(ctrl.stats.uncoveredPairs); // [] when fully covered +``` + +The `make()` convenience function throws `NeverMatch` if coverage is incomplete. Use `Controller.make()` directly to handle this without exceptions. + +## v1 → v2 + +### `sorter` split into `sorter` + `criterion` + +```typescript +// v1 +make(factors, { sorter: "greedy" }); + +// v2 +import { sorters, criteria } from "covertable"; +make(factors, { sorter: sorters.hash, criterion: criteria.greedy }); +``` + +### Sequential sorter removed + +The sequential sorter was dropped in v2 due to the potential for huge numbers of combinations. Use `sorters.hash` or `sorters.random` instead. diff --git a/docs/contents/history/v1.mdx b/docs/contents/history/v1.mdx new file mode 100644 index 0000000..7746320 --- /dev/null +++ b/docs/contents/history/v1.mdx @@ -0,0 +1,15 @@ +--- +sidebar_position: 4 +title: v1.x +--- + +# v1.x + +## 1.1.x + +- The greedy sorter was improved in both implementations. + - Speed has been increased. + +## 1.0.x + +- First release. diff --git a/docs/contents/history/v2.mdx b/docs/contents/history/v2.mdx new file mode 100644 index 0000000..8ef489e --- /dev/null +++ b/docs/contents/history/v2.mdx @@ -0,0 +1,36 @@ +--- +sidebar_position: 3 +title: v2.x +--- + +# v2.x + +## 2.4.x + +- Fixed an issue where preFilter was evaluating and excluding incomplete elements. +- Type names are now unified with the `Type` suffix. + +## 2.3.x + +- `PictConstraintsLexer` was added. ([#37](https://github.com/walkframe/covertable/pull/37)) + - A lexer designed to parse PICT constraints. + - Parses constraints written in the PICT format, enabling the evaluation of complex conditions. + - The parsed constraints are used in the `make` function to dynamically filter generated combinations. + +## 2.2.x + +- Speed is increased by expressing combinations of elements as a product of prime numbers. +- Added `SuggestRowType` to infer the row type. + +## 2.1.x + +- Speed up processing speed by pre-sorting target pairs. +- Added `makeAsync` function to generate combinations sequentially. + +## 2.0.x + +- The `sorter` option was split into `sorter` and `criterion`. + - e.g., greedy → hash sorter + greedy criterion. +- The `greedy` method is much faster than before. +- The `greedy` method now includes a `tolerance` option to balance speed and results. +- The sequential sorter was dropped due to the potential for huge numbers of combinations. diff --git a/docs/contents/history/v3.mdx b/docs/contents/history/v3.mdx new file mode 100644 index 0000000..47d223a --- /dev/null +++ b/docs/contents/history/v3.mdx @@ -0,0 +1,43 @@ +--- +sidebar_position: 2 +title: v3.x +--- + +# v3.x + +Major release with breaking changes, declarative constraints, and full PICT-format model support. + +## Breaking Changes + +- The `length` option has been renamed to `strength`. +- The `seed` option (used by `sorters.hash`) has been renamed to `salt`. +- The default export has been removed. Use `import { make } from "covertable"` instead of `import make from "covertable"`. +- `PictConstraintsLexer` is no longer exported. Use the new [`PictModel`](/advanced/pict) class instead. +- `PictModel.errors` (`string[]`) has been replaced with `PictModel.issues` (`PictModelIssue[]`). Each issue carries `severity`, `source`, `index`, `line`, and `message`. +- `preFilter` and `postFilter` have been replaced by declarative `constraints`. See [Constraint Logic](/constraint-logic) and [Migration Guide](./migration). + +## New Features + +- **Declarative constraints** — The new `constraints` option accepts `Condition[]` objects evaluated under Kleene three-valued logic. Replaces opaque `preFilter` functions with structured, analyzable constraint trees. +- **Forward checking** — Constraint propagation prunes infeasible pairs before and during generation. Detects constraint chain conflicts (e.g. `Language=de` → `Region=EU` → `Currency IN {EUR,GBP}`). +- **Peer propagation** — Extends forward checking to handle multi-value domain bottlenecks. +- **Controller.stats** — Generation statistics including `totalPairs`, `prunedPairs`, `coveredPairs`, `progress`, `rowCount`, `uncoveredPairs`, and `completions`. +- **`PictModel`** — Parses a complete PICT-format model (parameters, sub-models, constraints, invalid values, weights) and generates rows directly. Exported from `covertable/pict`. +- **Sub-models** — The `subModels` option (and PICT `{ A, B } @ N` syntax) lets you apply a different N-wise strength to a specific group of factors. +- **Weights** — The `weights` option (and PICT `value (N)` syntax) biases value selection during the row-completion phase. +- **Presets** — The `presets` option lets you specify rows that must appear in the output. Equivalent to PICT's `/e:file` seeding feature. +- **Invalid values** — PICT's `~value` syntax marks values as negative-test inputs. At most one invalid value per row. Output includes `~` prefix. +- **Aliases** — PICT's `value | alias` syntax lets you refer to a value by multiple names in constraints. +- **Unconditional constraints** — PICT-style invariants without an `IF` clause (e.g. `[A] <> [B];`). +- **`caseInsensitive` option** — `PictModel` matches PICT's default case-insensitive behavior. +- **`weightsByValue` helper** — Convert value-keyed weights into index-keyed form. +- **Custom comparer** — Override comparison operators for constraint evaluation. +- **Rescue phase** — Remaining uncovered pairs are retried individually after greedy + close. +- **NeverMatch with diagnostics** — When `make()` can't cover all pairs, it throws `NeverMatch` with `uncoveredPairs` detailing which pairs failed and which constraints are involved. + +## Tooling + +- Build system migrated from webpack to Vite (library mode, dual ESM/CJS output). +- Package manager switched to pnpm. +- TypeScript upgraded to 5.x. +- Interactive [Compatible PICT](/tools/pict) online tool with Web Worker support. diff --git a/docs/contents/index.mdx b/docs/contents/index.mdx new file mode 100644 index 0000000..e8f5fee --- /dev/null +++ b/docs/contents/index.mdx @@ -0,0 +1,152 @@ +--- +slug: / +sidebar_position: 1 +title: Getting Started +--- + +# covertable + +
+ npm version + CI + codecov + GitHub stars +
+ +**covertable** is a powerful tool for generating pairwise (and N-wise) combinations of input factors, designed for both **Node.js** and **browser** environments. It makes it easy to create comprehensive test cases that cover all factor interactions while keeping the number of test cases minimal. + +:::tip[What is Pairwise Testing?] +Pairwise testing is a combinatorial testing technique that generates test cases covering all possible pairs of input parameters. Instead of testing every combination (which can be enormous), pairwise testing ensures that every pair of factor values appears in at least one test case, dramatically reducing the number of required tests while maintaining high defect detection rates. +::: + +## Installation + +```bash +npm install covertable --save +``` + +## Quick Start + +### Array format + +Pass an array of factor arrays to get results as arrays: + +```typescript +import { make } from "covertable"; + +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; + +const rows = make([machine, os, browser]); +console.log(rows); +``` + +**Output:** +```javascript +[ + [ 'Pixel', 'iOS', 'Chrome' ], + [ 'ZenFone', 'iOS', 'FireFox' ], + [ 'Pixel', 'Android', 'Safari' ], + [ 'Galaxy', 'Android', 'Chrome' ], + [ 'XPERIA', 'Android', 'FireFox' ], + [ 'Pixel', 'iOS', 'FireFox' ], + [ 'iPhone', 'iOS', 'Safari' ], + [ 'Galaxy', 'iOS', 'Safari' ], + [ 'XPERIA', 'iOS', 'Chrome' ], + [ 'ZenFone', 'Android', 'Chrome' ], + [ 'Galaxy', 'iOS', 'FireFox' ], + [ 'iPhone', 'Android', 'Chrome' ], + [ 'iPhone', 'iOS', 'FireFox' ], + [ 'ZenFone', 'iOS', 'Safari' ], + [ 'XPERIA', 'iOS', 'Safari' ] +] +``` + +### Object format + +Pass an object of named factors to get results as objects: + +```typescript +import { make } from "covertable"; + +const rows = make({ + machine: ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"], + os: ["iOS", "Android"], + browser: ["FireFox", "Chrome", "Safari"], +}); + +console.log(rows); +// [ +// { machine: 'Pixel', os: 'iOS', browser: 'Chrome' }, +// { machine: 'ZenFone', os: 'iOS', browser: 'FireFox' }, +// ... +// ] +``` + +:::info +When factors are given as an **object**, each result row will also be an object with the same keys. +::: + +## Controller and Statistics + +The `make` function is a convenient shortcut. For access to generation statistics, use `Controller` directly: + +```typescript +import { Controller } from "covertable"; + +const factors = { machine, os, browser }; +const ctrl = new Controller(factors, { constraints: [...] }); +const rows = ctrl.make(); + +console.log(ctrl.stats); +// { +// totalPairs: 30, // all pairs before pruning +// prunedPairs: 4, // removed by constraint propagation +// coveredPairs: 26, // pairs covered in output rows +// progress: 1, // coverage ratio (1 = 100%) +// rowCount: 8, // number of generated rows +// uncoveredPairs: [], // pairs that couldn't be covered +// completions: { ... } // values filled by backtracking +// } +``` + +See [Constraint Logic](/constraint-logic#statistics) for full details on each field. + +## Async Generation + +Use `makeAsync` to generate rows one at a time via a generator: + +```typescript +import { makeAsync } from "covertable"; + +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; + +for (const row of makeAsync([machine, os, browser])) { + console.log(row); +} +``` + +## Requirements + +ES2015 or later. The following features are used: + +- [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) +- [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) +- [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) +- [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) +- [Object.keys](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) +- [Object.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) + +## Next Steps + +- Learn about [**Advanced Usage**](./advanced) including constraints, sorters, criteria, sub-models, and weights +- Use the [**PictModel**](./advanced/pict) to parse and run full PICT-format models (parameters + constraints + sub-models + invalid values + weights) +- Try the [**Compatible PICT**](/tools/pict) tool +- Check the [**History**](./history/) for release notes and [**Migration Guide**](./history/migration) + +:::caution[Migrating from v2] +v3 introduces breaking changes including renamed options, declarative constraints replacing `preFilter`/`postFilter`, and a new `PictModel` class. See the [**Migration Guide**](./history/migration) for full details. +::: diff --git a/docs/contents/tools/generate.worker.ts b/docs/contents/tools/generate.worker.ts new file mode 100644 index 0000000..ea7d9ec --- /dev/null +++ b/docs/contents/tools/generate.worker.ts @@ -0,0 +1,72 @@ +import { sorters, criteria } from "covertable"; +import { PictModel } from "covertable/pict"; + +interface GenerateRequest { + input: string; + strength: number; + criterion: "greedy" | "simple"; + sorter: "random" | "hash"; + caseSensitive: boolean; +} + +const ctx = self as unknown as Worker; + +ctx.onmessage = (e: MessageEvent) => { + const { input, strength, criterion, sorter, caseSensitive } = e.data; + + try { + const m = new PictModel(input, { caseInsensitive: !caseSensitive }); + const keys = Object.keys(m.parameters); + + ctx.postMessage({ type: "parsed", keys, issues: m.issues }); + ctx.postMessage({ type: "status", message: "Preparing..." }); + + const makeOpts = { + sorter: sorter === "random" ? sorters.random : sorters.hash, + criterion: criterion === "greedy" ? criteria.greedy : criteria.simple, + strength, + }; + + const iter = m.makeAsync(makeOpts); + + // After first next() call, the constructor has run (pairs built, pruned). + ctx.postMessage({ type: "status", message: null }); + ctx.postMessage({ type: "progress", rows: [], progress: m.progress }); + + const rows: any[] = []; + const genStart = Date.now(); + + const step = () => { + const deadline = Date.now() + 100; + while (Date.now() < deadline) { + const { value, done } = iter.next(); + if (done) { + ctx.postMessage({ + type: "done", + rows, + progress: 1, + stats: m.stats, + }); + return; + } + rows.push(value); + } + const p = m.progress; + const elapsed = Date.now() - genStart; + const eta = p > 0.01 ? Math.round((elapsed / p) * (1 - p) / 1000) : null; + ctx.postMessage({ + type: "progress", + rows: rows.slice(), + progress: p, + eta, + }); + setTimeout(step, 0); + }; + step(); + } catch (err: any) { + ctx.postMessage({ + type: "error", + message: err?.message ?? String(err), + }); + } +}; diff --git a/docs/contents/tools/pict-online.mdx b/docs/contents/tools/pict-online.mdx new file mode 100644 index 0000000..1d0e59a --- /dev/null +++ b/docs/contents/tools/pict-online.mdx @@ -0,0 +1,92 @@ +--- +sidebar_position: 1 +slug: /tools/pict +title: "Compatible PICT" +--- + +import PictDemo from './pict'; + +# Compatible PICT Online + +A browser-based pairwise test case generator fully compatible with [Microsoft PICT](https://github.com/microsoft/pict) model format. +Write your model, click Generate, and get optimized test combinations instantly — no installation required. + +:::info[Privacy] +All processing runs entirely in your browser. No data is sent to any server. +::: + + + +--- + +## How it works + +`PictModel` parses a PICT-format model into parameters, sub-models, and constraint filters, and lets you generate rows directly from it: + +```typescript +import { PictModel } from "covertable/pict"; + +const model = new PictModel(` +machine: iPhone, Pixel, XPERIA, ZenFone, Galaxy +os: iOS, Android +browser: FireFox, Chrome, Safari + +IF [machine] = "iPhone" THEN [os] = "iOS"; +IF [os] = "iOS" THEN [machine] = "iPhone"; +`); + +const rows = model.make(); +``` + +If you only want to apply constraints to factors you already have in code, you can pass `model.filter` directly to `make` as a `preFilter`: + +```typescript +import { make } from "covertable"; +import { PictModel } from "covertable/pict"; + +const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; +const os = ["iOS", "Android"]; +const browser = ["FireFox", "Chrome", "Safari"]; + +const model = new PictModel(` +machine: iPhone, Pixel, XPERIA, ZenFone, Galaxy +os: iOS, Android +browser: FireFox, Chrome, Safari + +IF [machine] = "iPhone" THEN [os] = "iOS"; +IF [os] = "iOS" THEN [machine] = "iPhone"; +`); + +make({ machine, os, browser }, { + preFilter: model.filter, +}); +``` + +## Supported Syntax + +`PictModel` supports the full PICT model file format. See the [PictModel reference](/advanced/pict) for the complete table. + +### Constraints + +| Syntax | Example | Description | +|--------|---------|-------------| +| `IF ... THEN ...` | `IF [os] = "iOS" THEN [machine] = "iPhone"` | Conditional constraint | +| `IF ... THEN ... ELSE ...` | `IF [os] = "iOS" THEN [machine] = "iPhone" ELSE [machine] <> "iPhone"` | With else branch | +| **Unconditional** | `[machine] <> [os];` | Always-applied invariant (no `IF`) | +| `=` / `<>` | `[os] = "iOS"` / `[os] <> "Android"` | Equality / Inequality | +| `>` / `<` / `>=` / `<=` | `[price] > 100` | Numeric comparisons | +| `AND` / `OR` / `NOT` | `[os] = "iOS" AND [browser] = "Safari"` | Logical operators with parentheses | +| `LIKE` | `[machine] LIKE "i*"` | Pattern matching with `*` and `?` | +| `IN` | `[os] IN {"iOS", "Android"}` | Set membership | + +### Parameters + +| Syntax | Example | Description | +|--------|---------|-------------| +| **Basic** | `Type: A, B, C` | Standard parameter declaration | +| **Quoted** | `Msg: "hello, world"` | Required for values with commas | +| **Aliases** | `OS: Windows \| Win, Linux` | Multiple names for the same value | +| **Invalid (`~`)** | `Type: A, ~Bad` | Negative-test value (at most one per row) | +| **Weight** | `Browser: Chrome (10), Firefox` | Bias value selection during completion | +| **Reference** | `B: , extra` | Inherit values from another parameter | +| **Sub-model** | `{ A, B, C } @ 3` | Apply different N-wise strength to a group | diff --git a/docs/contents/tools/pict.tsx b/docs/contents/tools/pict.tsx new file mode 100644 index 0000000..35807d6 --- /dev/null +++ b/docs/contents/tools/pict.tsx @@ -0,0 +1,1766 @@ +import React, { useEffect, useMemo, useRef, useState } from "react"; +import BrowserOnly from "@docusaurus/BrowserOnly"; +import { useColorMode } from "@docusaurus/theme-common"; +import CodeMirror, { type ReactCodeMirrorRef } from "@uiw/react-codemirror"; +import { EditorView, Decoration, type DecorationSet, ViewPlugin, type ViewUpdate } from "@codemirror/view"; +import { StateEffect, StateField, RangeSetBuilder } from "@codemirror/state"; +import { oneDark } from "@codemirror/theme-one-dark"; +import { PictModel, type PictModelIssue } from "covertable/pict"; +import type { ControllerStats } from "covertable"; + +// --------------------------------------------------------------------------- +// Error-line decoration +// --------------------------------------------------------------------------- + +const setErrorLines = StateEffect.define(); + +const errorLineField = StateField.define({ + create() { + return Decoration.none; + }, + update(deco, tr) { + deco = deco.map(tr.changes); + for (const e of tr.effects) { + if (e.is(setErrorLines)) { + const lineNumbers = e.value; + const totalLines = tr.state.doc.lines; + const decorations = lineNumbers + .filter((n) => n >= 1 && n <= totalLines) + .sort((a, b) => a - b) + .map((n) => + Decoration.line({ class: "cm-error-line" }).range( + tr.state.doc.line(n).from + ) + ); + deco = Decoration.set(decorations); + } + } + return deco; + }, + provide: (f) => EditorView.decorations.from(f), +}); + +const errorLineTheme = EditorView.baseTheme({ + ".cm-error-line": { + backgroundColor: "rgba(255, 80, 80, 0.18)", + boxShadow: "inset 3px 0 0 rgba(255, 80, 80, 0.9)", + }, +}); + +// --------------------------------------------------------------------------- +// PICT syntax highlighting +// --------------------------------------------------------------------------- + +const pictMark = { + comment: Decoration.mark({ class: "cm-pict-comment" }), + keyword: Decoration.mark({ class: "cm-pict-keyword" }), + field: Decoration.mark({ class: "cm-pict-field" }), + fieldUnknown: Decoration.mark({ class: "cm-pict-field-unknown" }), + string: Decoration.mark({ class: "cm-pict-string" }), + set: Decoration.mark({ class: "cm-pict-set" }), + brace: Decoration.mark({ class: "cm-pict-brace" }), + negative: Decoration.mark({ class: "cm-pict-negative" }), + weight: Decoration.mark({ class: "cm-pict-weight" }), + paramName: Decoration.mark({ class: "cm-pict-param-name" }), + paramValue: Decoration.mark({ class: "cm-pict-param-value" }), + operator: Decoration.mark({ class: "cm-pict-operator" }), + subModel: Decoration.mark({ class: "cm-pict-sub-model" }), +}; + +const KEYWORDS_RE = /\b(IF|THEN|ELSE|AND|OR|NOT|IN|LIKE)\b/gi; + +function buildPictDecorations(view: EditorView): DecorationSet { + const tokens: { from: number; to: number; mark: Decoration }[] = []; + + // Collect all parameter names from the document + const knownParams = new Set(); + for (let i = 1; i <= view.state.doc.lines; i++) { + const lineText = view.state.doc.line(i).text.trim(); + if (lineText.startsWith("#") || lineText === "") continue; + if (/^\s*(IF|THEN|ELSE)\b/i.test(lineText)) continue; + if (/^\s*\{/.test(lineText)) continue; + const cm = lineText.match(/^([^:]+):/); + if (cm) knownParams.add(cm[1].trim()); + } + + for (const { from: lineFrom, to: lineTo } of view.visibleRanges) { + for (let pos = lineFrom; pos < lineTo; ) { + const line = view.state.doc.lineAt(pos); + const text = line.text; + const base = line.from; + + // Comment line + if (text.trimStart().startsWith("#")) { + tokens.push({ from: base, to: base + text.length, mark: pictMark.comment }); + pos = line.to + 1; + continue; + } + + // Sub-model line: { key1, key2 } @ N + if (/^\s*\{[^}]*\}\s*@\s*\d+/.test(text)) { + tokens.push({ from: base, to: base + text.length, mark: pictMark.subModel }); + pos = line.to + 1; + continue; + } + + // Parameter line: "Name: val1, val2" + const paramMatch = text.match(/^([^:]+):/); + if (paramMatch && !text.match(/^\s*(IF|THEN|ELSE)\b/i)) { + tokens.push({ from: base, to: base + paramMatch[1].length, mark: pictMark.paramName }); + + // Collect negative and weight ranges first (they take priority) + let m: RegExpExecArray | null; + const overrides: { from: number; to: number }[] = []; + + const negRe = /~("(?:[^"\\]|\\.)*"|[^,()|\s]+)/g; + while ((m = negRe.exec(text)) !== null) { + const f = base + m.index, t = base + m.index + m[0].length; + tokens.push({ from: f, to: t, mark: pictMark.negative }); + overrides.push({ from: f, to: t }); + } + + const wRe = /\((\d+)\)/g; + while ((m = wRe.exec(text)) !== null) { + const f = base + m.index, t = base + m.index + m[0].length; + tokens.push({ from: f, to: t, mark: pictMark.weight }); + overrides.push({ from: f, to: t }); + } + + // Each comma-separated value after the colon (skip ranges covered by overrides) + const afterColon = paramMatch[0].length; + const valRe = /([^,]+)/g; + const valStr = text.slice(afterColon); + while ((m = valRe.exec(valStr)) !== null) { + const vTrimStart = m.index + afterColon + (m[1].length - m[1].trimStart().length); + const vTrimEnd = m.index + afterColon + m[1].trimEnd().length; + if (vTrimEnd <= vTrimStart) continue; + const absFrom = base + vTrimStart, absTo = base + vTrimEnd; + const hasOverride = overrides.some(o => o.from < absTo && o.to > absFrom); + if (!hasOverride) { + tokens.push({ from: absFrom, to: absTo, mark: pictMark.paramValue }); + } + } + + pos = line.to + 1; + continue; + } + + // Constraint line — collect all tokens + let m: RegExpExecArray | null; + + // Field references [Name] + const fieldRe = /\[([^\]]*)\]/g; + while ((m = fieldRe.exec(text)) !== null) { + const fieldName = m[1].trim(); + const mark = knownParams.has(fieldName) ? pictMark.field : pictMark.fieldUnknown; + tokens.push({ from: base + m.index, to: base + m.index + m[0].length, mark }); + } + + // Strings "..." + const strRe = /"(?:[^"\\]|\\.)*"/g; + while ((m = strRe.exec(text)) !== null) { + tokens.push({ from: base + m.index, to: base + m.index + m[0].length, mark: pictMark.string }); + } + + // Sets {val, val} — highlight braces separately + const setRe = /\{([^}]*)\}/g; + while ((m = setRe.exec(text)) !== null) { + const start = base + m.index; + tokens.push({ from: start, to: start + 1, mark: pictMark.brace }); + if (m[1].length > 0) { + tokens.push({ from: start + 1, to: start + 1 + m[1].length, mark: pictMark.set }); + } + tokens.push({ from: start + m[0].length - 1, to: start + m[0].length, mark: pictMark.brace }); + } + + // Keywords + KEYWORDS_RE.lastIndex = 0; + while ((m = KEYWORDS_RE.exec(text)) !== null) { + tokens.push({ from: base + m.index, to: base + m.index + m[0].length, mark: pictMark.keyword }); + } + + pos = line.to + 1; + } + } + + // Sort by start position, then by length (longer first for overlaps) + tokens.sort((a, b) => a.from - b.from || b.to - a.to); + + // Deduplicate overlapping ranges — keep the first (highest priority) + const builder = new RangeSetBuilder(); + let lastTo = 0; + for (const t of tokens) { + if (t.from >= lastTo) { + builder.add(t.from, t.to, t.mark); + lastTo = t.to; + } + } + return builder.finish(); +} + +const pictHighlight = ViewPlugin.fromClass( + class { + decorations: DecorationSet; + constructor(view: EditorView) { + this.decorations = buildPictDecorations(view); + } + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + this.decorations = buildPictDecorations(update.view); + } + } + }, + { decorations: (v) => v.decorations } +); + +const pictHighlightTheme = EditorView.baseTheme({ + ".cm-pict-comment": { color: "#6a9955", fontStyle: "italic" }, + ".cm-pict-keyword": { color: "#c586c0", fontWeight: "bold" }, + ".cm-pict-field": { color: "#4ec9b0", fontWeight: "bold" }, + ".cm-pict-field-unknown": { fontStyle: "italic", textDecoration: "line-through", opacity: "0.6" }, + ".cm-pict-string": { color: "#ce9178" }, + ".cm-pict-set": { color: "#ce9178" }, + ".cm-pict-brace": { color: "#d4d4d4", fontWeight: "bold" }, + ".cm-pict-negative": { color: "#f44747", textDecoration: "underline" }, + ".cm-pict-weight": { color: "#b5cea8" }, + ".cm-pict-param-name": { color: "#4ec9b0", fontWeight: "bold" }, + ".cm-pict-param-value": { color: "#9cdcfe" }, + ".cm-pict-operator": { color: "#d4d4d4" }, + ".cm-pict-sub-model": { color: "#dcdcaa" }, +}); + +// --------------------------------------------------------------------------- +// Built-in samples +// --------------------------------------------------------------------------- + +interface Sample { + label: string; + value: string; +} + +const SAMPLES: Sample[] = [ + { + label: "Storage volume (PICT classic example)", + value: `# The classic PICT example from Microsoft's documentation. +Type: Single, Span, Stripe, Mirror, RAID-5 +Size: 10, 100, 500, 1000, 5000, 10000, 40000 +Format method: Quick, Slow +File system: FAT, FAT32, NTFS +Cluster size: 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 +Compression: On, Off + +IF [File system] = "FAT" THEN [Size] <= 4096; +IF [File system] = "FAT32" THEN [Size] <= 32000; +`, + }, + { + label: "Negative testing with ~", + value: `# At most one ~negative value per row, so each error case is exercised +# in isolation while the other parameters stay valid. +Age: 20, 30, 40, ~-1, ~999 +Country: Japan, USA, ~"Mars" +Plan: Free, Pro, ~"Unknown" +`, + }, + { + label: "Aliases and weights", + value: `# "|" defines aliases (use any name in constraints, generate the canonical one). +# "(N)" biases value selection during the row-completion phase. +OS: Windows | Win | MS, Linux | GNU/Linux, "Mac OS" | Mac +Browser: Chrome (10), Firefox, Safari (3) +Region: US, EU, JP + +IF [OS] = "MS" THEN [Browser] <> "Safari"; +`, + }, +]; + +// --------------------------------------------------------------------------- +// Default model & helpers +// --------------------------------------------------------------------------- + +const STORAGE_KEY = "covertable-pict-input"; +const DEFAULT_INPUT = SAMPLES[0].value; + +function loadSavedInput(): string { + try { + const saved = sessionStorage.getItem(STORAGE_KEY); + if (saved !== null) return saved; + } catch { /* SSR or disabled storage */ } + return DEFAULT_INPUT; +} + +function copyToClipboard(text: string) { + if (typeof navigator !== "undefined" && navigator.clipboard) { + navigator.clipboard.writeText(text).catch(() => { + /* ignore */ + }); + } +} + +function rowsToTsv(rows: any[], keys: string[]): string { + const header = keys.join("\t"); + const body = rows.map((r) => keys.map((k) => String(r[k])).join("\t")).join("\n"); + return header + "\n" + body; +} + +function totalCombinations(parameters: Record): number { + return Object.values(parameters).reduce((acc, vs) => acc * vs.length, 1); +} + +// --------------------------------------------------------------------------- +// Component +// --------------------------------------------------------------------------- + +export default function PictDemo() { + return ( + Loading PICT demo…}> + {() => } + + ); +} + +function PictDemoInner() { + const { colorMode } = useColorMode(); + const isDark = colorMode === "dark"; + + const [input, setInputRaw] = useState(loadSavedInput); + const setInput = (value: string) => { + setInputRaw(value); + try { sessionStorage.setItem(STORAGE_KEY, value); } catch { /* ignore */ } + }; + const savedInput = loadSavedInput(); + const initialSample = SAMPLES.find((s) => s.value === savedInput); + const [activeSample, setActiveSample] = useState(initialSample?.label ?? null); + const [generatedFor, setGeneratedFor] = useState(null); + const [generatedKeys, setGeneratedKeys] = useState([]); + const [model, setModel] = useState(() => new PictModel("")); + const [rows, setRows] = useState([]); + const [outputView, setOutputView] = useState<"table" | "tsv" | "json">("table"); + const [copyTooltip, setCopyTooltip] = useState(false); + const [isGenerating, setIsGenerating] = useState(false); + const [progress, setProgress] = useState(0); + const [statusMessage, setStatusMessage] = useState(null); + const [eta, setEta] = useState(null); + const [elapsedMs, setElapsedMs] = useState(null); + const generateStartRef = useRef(0); + + // Tick elapsed time while generating + useEffect(() => { + if (!isGenerating) return; + const id = setInterval(() => { + setElapsedMs(Date.now() - generateStartRef.current); + }, 100); + return () => clearInterval(id); + }, [isGenerating]); + const [editorMode, setEditorMode] = useState<"split" | "expand" | "full">("split"); + const [outputFull, setOutputFull] = useState(false); + const [generatedStats, setGeneratedStats] = useState(null); + const [showOptions, setShowOptions] = useState(false); + const optionsRef = useRef(null); + + // Close options popover on outside click + useEffect(() => { + if (!showOptions) return; + const handler = (e: MouseEvent) => { + if (optionsRef.current && !optionsRef.current.contains(e.target as Node)) { + setShowOptions(false); + } + }; + document.addEventListener("mousedown", handler); + return () => document.removeEventListener("mousedown", handler); + }, [showOptions]); + const [optStrength, setOptStrength] = useState(2); + const [optCaseSensitive, setOptCaseSensitive] = useState(false); + const [optCriterion, setOptCriterion] = useState<"greedy" | "simple">("greedy"); + const [optSorter, setOptSorter] = useState<"random" | "hash">("random"); + const cmRef = useRef(null); + const workerRef = useRef(null); + + const extensions = useMemo(() => { + const base = [errorLineField, errorLineTheme, pictHighlight, pictHighlightTheme]; + return isDark ? [...base, oneDark] : base; + }, [isDark]); + + // Re-parse on input change so issues/preview reflect the current text. + // Row generation happens only when the user clicks Generate. + useEffect(() => { + setModel(new PictModel(input, { caseInsensitive: !optCaseSensitive })); + // Clear the active sample if the user has edited it away + const matched = SAMPLES.find((s) => s.value === input); + setActiveSample(matched ? matched.label : null); + }, [input, optCaseSensitive]); + + const handleGenerate = () => { + if (isGenerating) { + // Cancel: terminate the worker + workerRef.current?.terminate(); + workerRef.current = null; + setIsGenerating(false); + setStatusMessage(null); + setEta(null); + if (editorMode === "expand") setEditorMode("split"); + return; + } + + setIsGenerating(true); + setProgress(0); + setRows([]); + setGeneratedFor(input); + setGeneratedStats(null); + setElapsedMs(null); + generateStartRef.current = Date.now(); + + const worker = new Worker( + new URL("./generate.worker.ts", import.meta.url) + ); + workerRef.current = worker; + + worker.onmessage = (e) => { + const msg = e.data; + switch (msg.type) { + case "parsed": + setGeneratedKeys(msg.keys); + setModel(new PictModel(input, { caseInsensitive: !optCaseSensitive })); + break; + case "status": + setStatusMessage(msg.message); + break; + case "progress": + setStatusMessage(null); + setRows(msg.rows); + setProgress(msg.progress); + setEta(msg.eta ?? null); + break; + case "done": + setStatusMessage(null); + setEta(null); + setElapsedMs(Date.now() - generateStartRef.current); + setRows(msg.rows); + setProgress(1); + setGeneratedStats(msg.stats); + setIsGenerating(false); + workerRef.current = null; + if (editorMode === "expand") setEditorMode("split"); + break; + case "error": + setStatusMessage(null); + setIsGenerating(false); + workerRef.current = null; + if (editorMode === "expand") setEditorMode("split"); + break; + } + }; + + worker.onerror = () => { + setIsGenerating(false); + workerRef.current = null; + }; + + worker.postMessage({ + input, + strength: optStrength, + criterion: optCriterion, + sorter: optSorter, + caseSensitive: optCaseSensitive, + }); + }; + + // Clean up worker on unmount + useEffect(() => { + return () => { workerRef.current?.terminate(); }; + }, []); + + // Escape key exits expand/full mode + useEffect(() => { + if (editorMode === "split" && !outputFull) return; + const handler = (e: KeyboardEvent) => { + if (e.key === "Escape") { + setEditorMode("split"); + setOutputFull(false); + } + }; + window.addEventListener("keydown", handler); + return () => window.removeEventListener("keydown", handler); + }, [editorMode, outputFull]); + + const isDirty = generatedFor !== input; + const hasErrors = model.issues.some((i) => i.severity === "error"); + + // Push error lines to CodeMirror whenever issues change + useEffect(() => { + const view = cmRef.current?.view; + if (!view) return; + const lines = Array.from( + new Set( + model.issues.filter((i) => i.severity === "error").map((i) => i.line) + ) + ); + view.dispatch({ effects: setErrorLines.of(lines) }); + }, [model]); + + const factorEntries = Object.entries(model.parameters); + const factorKeys = factorEntries.map(([k]) => k); + + // Stats + const total = totalCombinations(model.parameters); + const reduction = + total > 0 ? Math.round((1 - rows.length / total) * 100) : 0; + + // Aliases (computed from model — but PictModel doesn't expose them, so we + // skip showing aliases section unless we add a getter. For now: derive from + // negatives/weights/subModels which ARE exposed.) + const negativeEntries = Array.from(model.negatives.entries()); + const weightEntries = Object.entries(model.weights); + + const handleCopy = (text: string) => { + copyToClipboard(text); + setCopyTooltip(true); + window.setTimeout(() => setCopyTooltip(false), 1500); + }; + + return ( +
+ + + {/* Samples (collapsible) */} +
+ Samples +
+ {SAMPLES.map((s) => ( + + ))} + +
+
+ +
+ {/* LEFT: editor + parsed metadata */} +
+
+

PICT model

+ +
+ + {showOptions && ( +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ )} +
+ +
+
+ + {editorMode === "full" ? ( + + ) : ( + + )} +
+ + {model.issues.length > 0 && } + + {/* Parsed metadata */} +
+

Parsed factors ({factorKeys.length})

+ {factorKeys.length === 0 ? ( +

No parameters parsed yet.

+ ) : ( + + + + + + + + + {factorEntries.map(([key, values]) => ( + + + + + ))} + +
FactorValues
+ {key} + {values.join(", ")}
+ )} + + {model.subModels.length > 0 && ( + <> +

Sub-models ({model.subModels.length})

+ + + + + + + + + {model.subModels.map((sm, i) => ( + + + + + ))} + +
KeysStrength
{sm.keys.join(", ")}{sm.strength}
+ + )} + + {negativeEntries.length > 0 && ( + <> +

Negative values

+ + + + + + + + + {negativeEntries.map(([key, set]) => ( + + + + + ))} + +
FactorValues
+ {key} + {Array.from(set).join(", ")}
+ + )} + + {weightEntries.length > 0 && ( + <> +

Weights

+ + + + + + + + + {weightEntries.map(([key, weights]: [string, any]) => { + const values = model.parameters[key] ?? []; + return ( + + + + + ); + })} + +
FactorValue → Weight
+ {key} + + {Object.entries(weights as Record).map( + ([idx, w], i, arr) => ( + + {String(values[Number(idx)] ?? idx)}={w} + {i < arr.length - 1 ? ", " : ""} + + ) + )} +
+ + )} + + {model.constraints.length > 0 && ( + <> +

Constraints ({model.constraints.length})

+

+ {model.constraints.filter((c) => c != null).length} compiled,{" "} + {model.constraints.filter((c) => c == null).length} failed +

+ + )} +
+
+ + {/* RIGHT: output */} +
+
+

Combinations{isDirty && *}

+
+ setOutputView("table")}> + Table + + setOutputView("tsv")}> + TSV + + setOutputView("json")}> + JSON + +
+
+ +
+ {generatedKeys.length === 0 ? ( +

+ Click Generate to produce combinations. +

+ ) : outputView === "table" ? ( +
+ + + + + {generatedKeys.map((key) => ( + + ))} + + + + {rows.map((row, i) => ( + + + {generatedKeys.map((key) => ( + + ))} + + ))} + +
#{key}
{i + 1}{String(row[key])}
+
+ ) : outputView === "tsv" ? ( +
{rowsToTsv(rows, generatedKeys)}
+ ) : ( +
{JSON.stringify(rows, null, 2)}
+ )} + {outputFull ? ( + + ) : generatedKeys.length > 0 && ( + + )} +
+ + {/* Progress bar (visible while generating) */} + {isGenerating && ( +
+
+
+ + {statusMessage + ? statusMessage + : `Generating… ${rows.length} rows (${Math.round(Math.sqrt(progress) * 100)}%)${eta !== null && eta > 0 ? ` — ~${eta}s left` : ""}`} + +
+ + ? + + Preparing… Building pair combinations and pruning infeasible pairs via constraint propagation. Can take a few seconds for large models or higher strengths.

+ Generating… Greedy row construction in progress. The percentage reflects pairs consumed or pruned out of total. +
+
+
+ )} + + {/* Copy / Download */} + {rows.length > 0 && ( +
+ + +
+ )} + + {/* Stats below the grid */} + {generatedKeys.length > 0 && ( +
+
+ + + 0 ? `${reduction}%` : "—"} + sub={total > 0 ? `vs ${total >= 1e6 ? total.toExponential(1) : total.toLocaleString()} total` : undefined} + /> + +
+ {generatedStats && ( +
+ + + + = 1 ? "success" : "warning"} + /> +
+ )} + {generatedStats && generatedStats.completions && Object.keys(generatedStats.completions).length > 0 && ( +
+ Completions (factors filled by backtracking) +
+ {Object.entries(generatedStats.completions) + .map(([k, v]) => [k, Object.values(v).reduce((a, b) => a + b, 0)] as [string, number]) + .sort((a, b) => b[1] - a[1]) + .map(([factor, count]) => ( +
+ + + + {factor} + {count} +
+ ))} +
+
+ )} +
+ )} +
+
+
+ ); +} + +// --------------------------------------------------------------------------- +// Sub-components +// --------------------------------------------------------------------------- + +function Stat({ + label, + value, + sub, + variant, +}: { + label: string; + value: number | string; + sub?: string; + variant?: "success" | "warning"; +}) { + return ( +
+
{value}
+
{label}
+ {sub &&
{sub}
} +
+ ); +} + +function SegmentButton({ + active, + onClick, + children, +}: { + active: boolean; + onClick: () => void; + children: React.ReactNode; +}) { + return ( + + ); +} + +function IssueList({ issues }: { issues: PictModelIssue[] }) { + return ( +
+ {issues.length} issue(s): +
    + {issues.map((issue, i) => ( +
  • + + [{issue.source}#{issue.index} line {issue.line}] + {" "} + {issue.message} +
  • + ))} +
+
+ ); +} + +// --------------------------------------------------------------------------- +// Styles +// --------------------------------------------------------------------------- + +function DemoStyles() { + return ( + + ); +} diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts new file mode 100644 index 0000000..4963b46 --- /dev/null +++ b/docs/docusaurus.config.ts @@ -0,0 +1,143 @@ +import {themes as prismThemes} from 'prism-react-renderer'; +import type {Config} from '@docusaurus/types'; +import type * as Preset from '@docusaurus/preset-classic'; +import path from 'path'; + +const config: Config = { + title: 'covertable', + tagline: 'A flexible pairwise testing tool for generating covering arrays', + favicon: 'img/favicon.ico', + + future: { + v4: true, + }, + + markdown: { + mermaid: true, + }, + themes: ['@docusaurus/theme-mermaid'], + + url: 'https://covertable.walkframe.com', + baseUrl: '/', + + organizationName: 'walkframe', + projectName: 'covertable', + + onBrokenLinks: 'throw', + + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + plugins: [ + function covertablePlugin() { + return { + name: 'covertable-webpack-plugin', + configureWebpack() { + return { + resolve: { + alias: { + 'covertable/pict': path.resolve(__dirname, '../typescript/src/pict/index.ts'), + covertable: path.resolve(__dirname, '../typescript/src/index.ts'), + }, + }, + }; + }, + }; + }, + ], + + presets: [ + [ + 'classic', + { + docs: { + path: 'contents', + sidebarPath: './sidebars.ts', + routeBasePath: '/', + editUrl: + 'https://github.com/walkframe/covertable/tree/master/docs/', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + image: 'img/covertable-social-card.png', + colorMode: { + respectPrefersColorScheme: true, + }, + navbar: { + title: 'covertable', + items: [ + { + href: 'https://www.npmjs.com/package/covertable', + label: 'npm', + position: 'right', + }, + { + href: 'https://pypi.org/project/covertable/', + label: 'PyPI', + position: 'right', + }, + { + href: 'https://github.com/walkframe/covertable', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Getting Started', + to: '/', + }, + { + label: 'Advanced Usage', + to: '/advanced', + }, + { + label: 'Compatible PICT', + to: '/tools/pict', + }, + ], + }, + { + title: 'Links', + items: [ + { + label: 'GitHub', + href: 'https://github.com/walkframe/covertable', + }, + { + label: 'npm', + href: 'https://www.npmjs.com/package/covertable', + }, + { + label: 'PyPI', + href: 'https://pypi.org/project/covertable/', + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} walkframe. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + additionalLanguages: ['bash', 'typescript', 'javascript'], + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000..e401859 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,64 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@codemirror/state": "^6.6.0", + "@codemirror/theme-one-dark": "^6.1.3", + "@codemirror/view": "^6.41.0", + "@docusaurus/core": "3.10.0", + "@docusaurus/faster": "3.10.0", + "@docusaurus/preset-classic": "3.10.0", + "@docusaurus/theme-common": "^3.10.0", + "@docusaurus/theme-mermaid": "^3.10.0", + "@mdx-js/react": "^3.0.0", + "@uiw/react-codemirror": "^4.25.9", + "clsx": "^2.0.0", + "mermaid": "^11.14.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.10.0", + "@docusaurus/tsconfig": "3.10.0", + "@docusaurus/types": "3.10.0", + "@types/react": "^19.0.0", + "ts-loader": "^9.5.7", + "typescript": "~6.0.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0" + }, + "pnpm": { + "onlyBuiltDependencies": [ + "@swc/core", + "core-js" + ] + }, + "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319" +} diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 0000000..61672dc --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,13495 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@codemirror/state': + specifier: ^6.6.0 + version: 6.6.0 + '@codemirror/theme-one-dark': + specifier: ^6.1.3 + version: 6.1.3 + '@codemirror/view': + specifier: ^6.41.0 + version: 6.41.0 + '@docusaurus/core': + specifier: 3.10.0 + version: 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/faster': + specifier: 3.10.0 + version: 3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + '@docusaurus/preset-classic': + specifier: 3.10.0 + version: 3.10.0(@algolia/client-search@5.50.1)(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2) + '@docusaurus/theme-common': + specifier: ^3.10.0 + version: 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/theme-mermaid': + specifier: ^3.10.0 + version: 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@mdx-js/react': + specifier: ^3.0.0 + version: 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@uiw/react-codemirror': + specifier: ^4.25.9 + version: 4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.41.0)(codemirror@6.0.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + clsx: + specifier: ^2.0.0 + version: 2.1.1 + mermaid: + specifier: ^11.14.0 + version: 11.14.0 + prism-react-renderer: + specifier: ^2.3.0 + version: 2.4.1(react@19.2.5) + react: + specifier: ^19.0.0 + version: 19.2.5 + react-dom: + specifier: ^19.0.0 + version: 19.2.5(react@19.2.5) + devDependencies: + '@docusaurus/module-type-aliases': + specifier: 3.10.0 + version: 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/tsconfig': + specifier: 3.10.0 + version: 3.10.0 + '@docusaurus/types': + specifier: 3.10.0 + version: 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@types/react': + specifier: ^19.0.0 + version: 19.2.14 + ts-loader: + specifier: ^9.5.7 + version: 9.5.7(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24)) + typescript: + specifier: ~6.0.2 + version: 6.0.2 + +packages: + + '@algolia/abtesting@1.16.1': + resolution: {integrity: sha512-Xxk4l00pYI+jE0PNw8y0MvsQWh5278WRtZQav8/BMMi3HKi2xmeuqe11WJ3y8/6nuBHdv39w76OpJb09TMfAVQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/autocomplete-core@1.19.2': + resolution: {integrity: sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==} + + '@algolia/autocomplete-core@1.19.8': + resolution: {integrity: sha512-3YEorYg44niXcm7gkft3nXYItHd44e8tmh4D33CTszPgP0QWkaLEaFywiNyJBo7UL/mqObA/G9RYuU7R8tN1IA==} + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2': + resolution: {integrity: sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-plugin-algolia-insights@1.19.8': + resolution: {integrity: sha512-ZvJWO8ZZJDpc1LNM2TTBdmQsZBLMR4rU5iNR2OYvEeFBiaf/0ESnRSSLQbryarJY4SVxtoz6A2ZtDMNM+iQEAA==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-shared@1.19.2': + resolution: {integrity: sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.19.8': + resolution: {integrity: sha512-h5hf2t8ejF6vlOgvLaZzQbWs5SyH2z4PAWygNAvvD/2RI29hdQ54ldUGwqVuj9Srs+n8XUKTPUqb7fvhBhQrnQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.50.1': + resolution: {integrity: sha512-4peZlPXMwTOey9q1rQKMdCnwZb/E95/1e+7KujXpLLSh0FawJzg//U2NM+r4AiJy4+naT2MTBhj0K30yshnVTA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.50.1': + resolution: {integrity: sha512-i+aWHHG8NZvGFHtPeMZkxL2Loc6Fm7iaRo15lYSMx8gFL+at9vgdWxhka7mD1fqxkrxXsQstUBCIsSY8FvkEOw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.50.1': + resolution: {integrity: sha512-Hw52Fwapyk/7hMSV/fI4+s3H9MGZEUcRh4VphyXLAk2oLYdndVUkc6KBi0zwHSzwPAr+ZBwFPe2x6naUt9mZGw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.50.1': + resolution: {integrity: sha512-Bn/wtwhJ7p1OD/6pY+Zzn+zlu2N/SJnH46md/PAbvqIzmjVuwjNwD4y0vV5Ov8naeukXdd7UU9v550+v8+mtlg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.50.1': + resolution: {integrity: sha512-0V4Tu0RWR8YxkgI9EPVOZHGE4K5pEIhkLNN0CTkP/rnPsqaaSQpNMYW3/mGWdiKOWbX0iVmwLB9QESk3H0jS5g==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.50.1': + resolution: {integrity: sha512-jofcWNYMXJDDr87Z2eivlWY6o71Zn7F7aOvQCXSDAo9QTlyf7BhXEsZymLUvF0O1yU9Q9wvrjAWn8uVHYnAvgw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.50.1': + resolution: {integrity: sha512-OteRb8WubcmEvU0YlMJwCXs3Q6xrdkb0v50/qZBJP1TF0CvujFZQM++9BjEkTER/Jr9wbPHvjSFKnbMta0b4dQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/events@4.0.1': + resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} + + '@algolia/ingestion@1.50.1': + resolution: {integrity: sha512-0GmfSgDQK6oiIVXnJvGxtNFOfosBspRTR7csCOYCTL1P8QtxX2vDCIKwTM7xdSAEbJaZ43QlWg25q0Qdsndz8Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.50.1': + resolution: {integrity: sha512-ySuigKEe4YjYV3si8NVk9BHQpFj/1B+ON7DhhvTvbrZJseHQQloxzq0yHwKmznSdlO6C956fx4pcfOKkZClsyg==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.50.1': + resolution: {integrity: sha512-Cp8T/B0gVmjFlzzp6eP47hwKh5FGyeqQp1N48/ANDdvdiQkPqLyFHQVDwLBH0LddfIPQE+yqmZIgmKc82haF4A==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.50.1': + resolution: {integrity: sha512-XKdGGLikfrlK66ZSXh/vWcXZZ8Vg3byDFbJD8pwEvN1FoBRGxhxya476IY2ohoTymLa4qB5LBRlIa+2TLHx3Uw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.50.1': + resolution: {integrity: sha512-mBAU6WyVsDwhHyGM+nodt1/oebHxgvuLlOAoMGbj/1i6LygDHZWDgL1t5JEs37x9Aywv7ZGhqbM1GsfZ54sU6g==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.50.1': + resolution: {integrity: sha512-qmo1LXrNKLHvJE6mdQbLnsZAoZvj7VyF2ft4xmbSGWI2WWm87fx/CjUX4kEExt4y0a6T6nEts6ofpUfH5TEE1A==} + engines: {node: '>= 14.0.0'} + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-constant-elements@7.27.1': + resolution: {integrity: sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.29.2': + resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + + '@chevrotain/cst-dts-gen@12.0.0': + resolution: {integrity: sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg==} + + '@chevrotain/gast@12.0.0': + resolution: {integrity: sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ==} + + '@chevrotain/regexp-to-ast@12.0.0': + resolution: {integrity: sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA==} + + '@chevrotain/types@12.0.0': + resolution: {integrity: sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA==} + + '@chevrotain/utils@12.0.0': + resolution: {integrity: sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA==} + + '@codemirror/autocomplete@6.20.1': + resolution: {integrity: sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==} + + '@codemirror/commands@6.10.3': + resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==} + + '@codemirror/language@6.12.3': + resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==} + + '@codemirror/lint@6.9.5': + resolution: {integrity: sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==} + + '@codemirror/search@6.6.0': + resolution: {integrity: sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw==} + + '@codemirror/state@6.6.0': + resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==} + + '@codemirror/theme-one-dark@6.1.3': + resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==} + + '@codemirror/view@6.41.0': + resolution: {integrity: sha512-6H/qadXsVuDY219Yljhohglve8xf4B8xJkVOEWfA5uiYKiTFppjqsvsfR5iPA0RbvRBoOyTZpbLIxe9+0UR8xA==} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@csstools/cascade-layer-name-parser@2.0.5': + resolution: {integrity: sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@csstools/media-query-list-parser@4.0.3': + resolution: {integrity: sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/postcss-alpha-function@1.0.1': + resolution: {integrity: sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-cascade-layers@5.0.2': + resolution: {integrity: sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1': + resolution: {integrity: sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function@4.0.12': + resolution: {integrity: sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-function@3.0.12': + resolution: {integrity: sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2': + resolution: {integrity: sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-content-alt-text@2.0.8': + resolution: {integrity: sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-contrast-color-function@2.0.12': + resolution: {integrity: sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-exponential-functions@2.0.9': + resolution: {integrity: sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-font-format-keywords@4.0.0': + resolution: {integrity: sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gamut-mapping@2.0.11': + resolution: {integrity: sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gradients-interpolation-method@5.0.12': + resolution: {integrity: sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-hwb-function@4.0.12': + resolution: {integrity: sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-ic-unit@4.0.4': + resolution: {integrity: sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-initial@2.0.1': + resolution: {integrity: sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-is-pseudo-class@5.0.3': + resolution: {integrity: sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-light-dark-function@2.0.11': + resolution: {integrity: sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-float-and-clear@3.0.0': + resolution: {integrity: sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overflow@2.0.0': + resolution: {integrity: sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0': + resolution: {integrity: sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-resize@3.0.0': + resolution: {integrity: sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-viewport-units@3.0.4': + resolution: {integrity: sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-minmax@2.0.9': + resolution: {integrity: sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5': + resolution: {integrity: sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-nested-calc@4.0.0': + resolution: {integrity: sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-normalize-display-values@4.0.1': + resolution: {integrity: sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-oklab-function@4.0.12': + resolution: {integrity: sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-position-area-property@1.0.0': + resolution: {integrity: sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-progressive-custom-properties@4.2.1': + resolution: {integrity: sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-property-rule-prelude-list@1.0.0': + resolution: {integrity: sha512-IxuQjUXq19fobgmSSvUDO7fVwijDJaZMvWQugxfEUxmjBeDCVaDuMpsZ31MsTm5xbnhA+ElDi0+rQ7sQQGisFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-random-function@2.0.1': + resolution: {integrity: sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-relative-color-syntax@3.0.12': + resolution: {integrity: sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-scope-pseudo-class@4.0.1': + resolution: {integrity: sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-sign-functions@1.1.4': + resolution: {integrity: sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-stepped-value-functions@4.0.9': + resolution: {integrity: sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1': + resolution: {integrity: sha512-GneqQWefjM//f4hJ/Kbox0C6f2T7+pi4/fqTqOFGTL3EjnvOReTqO1qUQ30CaUjkwjYq9qZ41hzarrAxCc4gow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-system-ui-font-family@1.0.0': + resolution: {integrity: sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-text-decoration-shorthand@4.0.3': + resolution: {integrity: sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-trigonometric-functions@4.0.9': + resolution: {integrity: sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-unset-value@4.0.0': + resolution: {integrity: sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/selector-resolve-nested@3.1.0': + resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/selector-specificity@5.0.0': + resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/utilities@2.0.0': + resolution: {integrity: sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@docsearch/core@4.6.2': + resolution: {integrity: sha512-/S0e6Dj7Zcm8m9Rru49YEX49dhU11be68c+S/BCyN8zQsTTgkKzXlhRbVL5mV6lOLC2+ZRRryaTdcm070Ug2oA==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + + '@docsearch/css@4.6.2': + resolution: {integrity: sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ==} + + '@docsearch/react@4.6.2': + resolution: {integrity: sha512-/BbtGFtqVOGwZx0dw/UfhN/0/DmMQYnulY4iv0tPRhC2JCXv0ka/+izwt3Jzo1ZxXS/2eMvv9zHsBJOK1I9f/w==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@docusaurus/babel@3.10.0': + resolution: {integrity: sha512-mqCJhCZNZUDg0zgDEaPTM4DnRsisa24HdqTy/qn/MQlbwhTb4WVaZg6ZyX6yIVKqTz8fS1hBMgM+98z+BeJJDg==} + engines: {node: '>=20.0'} + + '@docusaurus/bundler@3.10.0': + resolution: {integrity: sha512-iONUGZGgp+lAkw/cJZH6irONcF4p8+278IsdRlq8lYhxGjkoNUs0w7F4gVXBYSNChq5KG5/JleTSsdJySShxow==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/faster': '*' + peerDependenciesMeta: + '@docusaurus/faster': + optional: true + + '@docusaurus/core@3.10.0': + resolution: {integrity: sha512-mgLdQsO8xppnQZc3LPi+Mf+PkPeyxJeIx11AXAq/14fsaMefInQiMEZUUmrc7J+956G/f7MwE7tn8KZgi3iRcA==} + engines: {node: '>=20.0'} + hasBin: true + peerDependencies: + '@docusaurus/faster': '*' + '@mdx-js/react': ^3.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@docusaurus/faster': + optional: true + + '@docusaurus/cssnano-preset@3.10.0': + resolution: {integrity: sha512-qzSshTO1DB3TYW+dPUal5KHM7XPc5YQfzF3Kdb2NDACJUyGbNcFtw3tGkCJlYwhNCRKbZcmwraKUS1i5dcHdGg==} + engines: {node: '>=20.0'} + + '@docusaurus/faster@3.10.0': + resolution: {integrity: sha512-GNPtVH14ISjHfSwnHu3KiFGf86ICmJSQDeSv/QaanpBgiZGOtgZaslnC5q8WiguxM1EVkwcGxPuD8BXF4eggKw==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/types': '*' + + '@docusaurus/logger@3.10.0': + resolution: {integrity: sha512-9jrZzFuBH1LDRlZ7cznAhCLmAZ3HSDqgwdrSSZdGHq9SPUOQgXXu8mnxe2ZRB9NS1PCpMTIOVUqDtZPIhMafZg==} + engines: {node: '>=20.0'} + + '@docusaurus/mdx-loader@3.10.0': + resolution: {integrity: sha512-mQQV97080AH4PYNs087l202NMDqRopZA4mg5W76ZZyTFrmWhJ3mHg+8A+drJVENxw5/Q+wHMHLgsx+9z1nEs0A==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/module-type-aliases@3.10.0': + resolution: {integrity: sha512-/1O0Zg8w3DFrYX/I6Fbss7OJrtZw1QoyjDhegiFNHVi9A9Y0gQ3jUAytVxF6ywpAWpLyLxch8nN8H/V3XfzdJQ==} + peerDependencies: + react: '*' + react-dom: '*' + + '@docusaurus/plugin-content-blog@3.10.0': + resolution: {integrity: sha512-RuTz68DhB7CL96QO5UsFbciD7GPYq6QV+YMfF9V0+N4ZgLhJIBgpVAr8GobrKF6NRe5cyWWETU5z5T834piG9g==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-docs@3.10.0': + resolution: {integrity: sha512-9BjHhf15ct8Z7TThTC0xRndKDVvMKmVsAGAN7W9FpNRzfMdScOGcXtLmcCWtJGvAezjOJIm6CxOYCy3Io5+RnQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-pages@3.10.0': + resolution: {integrity: sha512-5amX8kEJI+nIGtuLVjYk59Y5utEJ3CHETFOPEE4cooIRLA4xM4iBsA6zFgu4ljcopeYwvBzFEWf5g2I6Yb9SkA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-css-cascade-layers@3.10.0': + resolution: {integrity: sha512-6q1vtt5FJcg5osgkHeM1euErECNqEZ5Z1j69yiNx2luEBIso+nxCkS9nqj8w+MK5X7rvKEToGhFfOFWncs51pQ==} + engines: {node: '>=20.0'} + + '@docusaurus/plugin-debug@3.10.0': + resolution: {integrity: sha512-XcljKN+G+nmmK69uQA1d9BlYU3ZftG3T3zpK8/7Hf/wrOlV7TA4Ampdrdwkg0jElKdKAoSnPhCO0/U3bQGsVQQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-analytics@3.10.0': + resolution: {integrity: sha512-hTEoodatpBZnUat5nFExbuTGA1lhWGy7vZGuTew5Q3QDtGKFpSJLYmZJhdTjvCFwv1+qQ67hgAVlKdJOB8TXow==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-gtag@3.10.0': + resolution: {integrity: sha512-iB/Zzjv/eelJRbdULZqzWCbgMgJ7ht4ONVjXtN3+BI/muil6S87gQ1OJyPwlXD+ELdKkitC7bWv5eJdYOZLhrQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-tag-manager@3.10.0': + resolution: {integrity: sha512-FEjZxqKgLHa+Wez/EgKxRwvArNCWIScfyEQD95rot7jkxp6nonjI5XIbGfO/iYhM5Qinwe8aIEQHP2KZtpqVuA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-sitemap@3.10.0': + resolution: {integrity: sha512-DVTSLjB97hIjmayGnGcBfognCeI7ZuUKgEnU7Oz81JYqXtVg94mVTthDjq3QHTylYNeCUbkaW8VF0FDLcc8pPw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-svgr@3.10.0': + resolution: {integrity: sha512-lNljBESaETZqVBMPqkrGchr+UPT1eZzEPLmJhz8I76BxbjqgsUnRvrq6lQJ9sYjgmgX52KB7kkgczqd2yzoswQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/preset-classic@3.10.0': + resolution: {integrity: sha512-kw/Ye02Hc6xP1OdTswy8yxQEHg0fdPpyWAQRxr5b2x3h7LlG2Zgbb5BDFROnXDDMpUxB7YejlocJIE5HIEfpNA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/react-loadable@6.0.0': + resolution: {integrity: sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==} + peerDependencies: + react: '*' + + '@docusaurus/theme-classic@3.10.0': + resolution: {integrity: sha512-9msCAsRdN+UG+RwPwCFb0uKy4tGoPh5YfBozXeGUtIeAgsMdn6f3G/oY861luZ3t8S2ET8S9Y/1GnpJAGWytww==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-common@3.10.0': + resolution: {integrity: sha512-Dkp1YXKn16ByCJAdIjbDIOpVb4Z66MsVD694/ilX1vAAHaVEMrVsf/NPd9VgreyFx08rJ9GqV1MtzsbTcU73Kg==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-mermaid@3.10.0': + resolution: {integrity: sha512-Y2xrlwhIJ80oOZIO3PXL6A7J869splfcMI87E3NKpYsy3zJxOyV+BP1QMtGi59ajKgU868HPuyyn6J+6BZGOBg==} + engines: {node: '>=20.0'} + peerDependencies: + '@mermaid-js/layout-elk': ^0.1.9 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@mermaid-js/layout-elk': + optional: true + + '@docusaurus/theme-search-algolia@3.10.0': + resolution: {integrity: sha512-f5FPKI08e3JRG63vR/o4qeuUVHUHzFzM0nnF+AkB67soAZgNsKJRf2qmUZvlQkGwlV+QFkKe4D0ANMh1jToU3g==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-translations@3.10.0': + resolution: {integrity: sha512-L9IbFLwTc5+XdgH45iQYufLn0SVZd6BUNelDbKIFlH+E4hhjuj/XHWAFMX/w2K59rfy8wak9McOaei7BSUfRPA==} + engines: {node: '>=20.0'} + + '@docusaurus/tsconfig@3.10.0': + resolution: {integrity: sha512-TXdC3WXuPrdQAexLvjUJfnYf3YKEgEqAs5nK0Q88pRBCW7t7oN4ILvWYb3A5Z1wlSXyXGWW/mCUmLEhdWsjnDQ==} + + '@docusaurus/types@3.10.0': + resolution: {integrity: sha512-F0dOt3FOoO20rRaFK7whGFQZ3ggyrWEdQc/c8/UiRuzhtg4y1w9FspXH5zpCT07uMnJKBPGh+qNazbNlCQqvSw==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/utils-common@3.10.0': + resolution: {integrity: sha512-JyL7sb9QVDgYvudIS81Dv0lsWm7le0vGZSDwsztxWam1SPBqrnkvBy9UYL/amh6pbybkyYTd3CMTkO24oMlCSw==} + engines: {node: '>=20.0'} + + '@docusaurus/utils-validation@3.10.0': + resolution: {integrity: sha512-c+6n2+ZPOJtWWc8Bb/EYdpSDfjYEScdCu9fB/SNjOmSCf1IdVnGf2T53o0tsz0gDRtCL90tifTL0JE/oMuP1Mw==} + engines: {node: '>=20.0'} + + '@docusaurus/utils@3.10.0': + resolution: {integrity: sha512-T3B0WTigsIthe0D4LQa2k+7bJY+c3WS+Wq2JhcznOSpn1lSN64yNtHQXboCj3QnUs1EuAZszQG1SHKu5w5ZrlA==} + engines: {node: '>=20.0'} + + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/base64@17.67.0': + resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@17.67.0': + resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@17.67.0': + resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-core@4.57.1': + resolution: {integrity: sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-fsa@4.57.1': + resolution: {integrity: sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-builtins@4.57.1': + resolution: {integrity: sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-to-fsa@4.57.1': + resolution: {integrity: sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-utils@4.57.1': + resolution: {integrity: sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node@4.57.1': + resolution: {integrity: sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-print@4.57.1': + resolution: {integrity: sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-snapshot@4.57.1': + resolution: {integrity: sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@17.67.0': + resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@17.67.0': + resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@17.67.0': + resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@lezer/common@1.5.2': + resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==} + + '@lezer/highlight@1.2.3': + resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==} + + '@lezer/lr@1.4.8': + resolution: {integrity: sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==} + + '@marijn/find-cluster-break@1.0.2': + resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@mermaid-js/parser@1.1.0': + resolution: {integrity: sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw==} + + '@module-federation/error-codes@0.22.0': + resolution: {integrity: sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==} + + '@module-federation/runtime-core@0.22.0': + resolution: {integrity: sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==} + + '@module-federation/runtime-tools@0.22.0': + resolution: {integrity: sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==} + + '@module-federation/runtime@0.22.0': + resolution: {integrity: sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==} + + '@module-federation/sdk@0.22.0': + resolution: {integrity: sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==} + + '@module-federation/webpack-bundler-runtime@0.22.0': + resolution: {integrity: sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==} + + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@peculiar/asn1-cms@2.6.1': + resolution: {integrity: sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==} + + '@peculiar/asn1-csr@2.6.1': + resolution: {integrity: sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==} + + '@peculiar/asn1-ecc@2.6.1': + resolution: {integrity: sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==} + + '@peculiar/asn1-pfx@2.6.1': + resolution: {integrity: sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==} + + '@peculiar/asn1-pkcs8@2.6.1': + resolution: {integrity: sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==} + + '@peculiar/asn1-pkcs9@2.6.1': + resolution: {integrity: sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==} + + '@peculiar/asn1-rsa@2.6.1': + resolution: {integrity: sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==} + + '@peculiar/asn1-schema@2.6.0': + resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} + + '@peculiar/asn1-x509-attr@2.6.1': + resolution: {integrity: sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==} + + '@peculiar/asn1-x509@2.6.1': + resolution: {integrity: sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==} + + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} + + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} + engines: {node: '>=12'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@rspack/binding-darwin-arm64@1.7.11': + resolution: {integrity: sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig==} + cpu: [arm64] + os: [darwin] + + '@rspack/binding-darwin-x64@1.7.11': + resolution: {integrity: sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA==} + cpu: [x64] + os: [darwin] + + '@rspack/binding-linux-arm64-gnu@1.7.11': + resolution: {integrity: sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-arm64-musl@1.7.11': + resolution: {integrity: sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rspack/binding-linux-x64-gnu@1.7.11': + resolution: {integrity: sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-x64-musl@1.7.11': + resolution: {integrity: sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rspack/binding-wasm32-wasi@1.7.11': + resolution: {integrity: sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ==} + cpu: [wasm32] + + '@rspack/binding-win32-arm64-msvc@1.7.11': + resolution: {integrity: sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA==} + cpu: [arm64] + os: [win32] + + '@rspack/binding-win32-ia32-msvc@1.7.11': + resolution: {integrity: sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw==} + cpu: [ia32] + os: [win32] + + '@rspack/binding-win32-x64-msvc@1.7.11': + resolution: {integrity: sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q==} + cpu: [x64] + os: [win32] + + '@rspack/binding@1.7.11': + resolution: {integrity: sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q==} + + '@rspack/core@1.7.11': + resolution: {integrity: sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew==} + engines: {node: '>=18.12.0'} + peerDependencies: + '@swc/helpers': '>=0.5.1' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@rspack/lite-tapable@1.1.0': + resolution: {integrity: sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@slorber/react-helmet-async@1.3.0': + resolution: {integrity: sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@slorber/remark-comment@1.0.0': + resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0': + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0': + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0': + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0': + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@8.1.0': + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@8.1.0': + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + + '@svgr/hast-util-to-babel-ast@8.0.0': + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + + '@svgr/plugin-jsx@8.1.0': + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/plugin-svgo@8.1.0': + resolution: {integrity: sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/webpack@8.1.0': + resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} + engines: {node: '>=14'} + + '@swc/core-darwin-arm64@1.15.24': + resolution: {integrity: sha512-uM5ZGfFXjtvtJ+fe448PVBEbn/CSxS3UAyLj3O9xOqKIWy3S6hPTXSPbszxkSsGDYKi+YFhzAsR4r/eXLxEQ0g==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.15.24': + resolution: {integrity: sha512-fMIb/Zfn929pw25VMBhV7Ji2Dl+lCWtUPNdYJQYOke+00E5fcQ9ynxtP8+qhUo/HZc+mYQb1gJxwHM9vty+lXg==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.15.24': + resolution: {integrity: sha512-vOkjsyjjxnoYx3hMEWcGxQrMgnNrRm6WAegBXrN8foHtDAR+zpdhpGF5a4lj1bNPgXAvmysjui8cM1ov/Clkaw==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.15.24': + resolution: {integrity: sha512-h/oNu+upkXJ6Cicnq7YGVj9PkdfarLCdQa8l/FlHYvfv8CEiMaeeTnpLU7gSBH/rGxosM6Qkfa/J9mThGF9CLA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-arm64-musl@1.15.24': + resolution: {integrity: sha512-ZpF/pRe1guk6sKzQI9D1jAORtjTdNlyeXn9GDz8ophof/w2WhojRblvSDJaGe7rJjcPN8AaOkhwdRUh7q8oYIg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@swc/core-linux-ppc64-gnu@1.15.24': + resolution: {integrity: sha512-QZEsZfisHTSJlmyChgDFNmKPb3W6Lhbfo/O76HhIngfEdnQNmukS38/VSe1feho+xkV5A5hETyCbx3sALBZKAQ==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-s390x-gnu@1.15.24': + resolution: {integrity: sha512-DLdJKVsJgglqQrJBuoUYNmzm3leI7kUZhLbZGHv42onfKsGf6JDS3+bzCUQfte/XOqDjh/tmmn1DR/CF/tCJFw==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-gnu@1.15.24': + resolution: {integrity: sha512-IpLYfposPA/XLxYOKpRfeccl1p5dDa3+okZDHHTchBkXEaVCnq5MADPmIWwIYj1tudt7hORsEHccG5no6IUQRw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-musl@1.15.24': + resolution: {integrity: sha512-JHy3fMSc0t/EPWgo74+OK5TGr51aElnzqfUPaiRf2qJ/BfX5CUCfMiWVBuhI7qmVMBnk1jTRnL/xZnOSHDPLYg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@swc/core-win32-arm64-msvc@1.15.24': + resolution: {integrity: sha512-Txj+qUH1z2bUd1P3JvwByfjKFti3cptlAxhWgmunBUUxy/IW3CXLZ6l6Gk4liANadKkU71nIU1X30Z5vpMT3BA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.15.24': + resolution: {integrity: sha512-15D/nl3XwrhFpMv+MADFOiVwv3FvH9j8c6Rf8EXBT3Q5LoMh8YnDnSgPYqw1JzPnksvsBX6QPXLiPqmcR/Z4qQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.15.24': + resolution: {integrity: sha512-PR0PlTlPra2JbaDphrOAzm6s0v9rA0F17YzB+XbWD95B4g2cWcZY9LAeTa4xll70VLw9Jr7xBrlohqlQmelMFQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.15.24': + resolution: {integrity: sha512-5Hj8aNasue7yusUt8LGCUe/AjM7RMAce8ZoyDyiFwx7Al+GbYKL+yE7g4sJk8vEr1dKIkTRARkNIJENc4CjkBQ==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/html-darwin-arm64@1.15.24': + resolution: {integrity: sha512-2yH5kkeBM6mcSajWdIvh482HZDthvWM+SkH17CAzmgDgP2WGZ3IpdeIQxdV8Jj9kRdJaI0VqdXGT0qRRt6zw4A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/html-darwin-x64@1.15.24': + resolution: {integrity: sha512-1k4Wl1eExT9yal3fX6MGcrpWOvYo+f7jnzw+ksg+8ifpYqpcrcy6Rv6cB78SgXzZJRpx8zBY1luk+zYyoDlrWA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/html-linux-arm-gnueabihf@1.15.24': + resolution: {integrity: sha512-XbqWgyBE6tukUs+0zwzW+Xo3N/P6SoiJJ44QfB3RCb5Naz/1vwJbNgn9erFDgoq7CChmCooFuMfNnmh/E/Orsg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/html-linux-arm64-gnu@1.15.24': + resolution: {integrity: sha512-GqJgkJHTlLM0tzJHX0tmU0ZAU4rIfMYZ2yJwCBwnFaLw4NacpimyWnWGJxH83SViVZ33DfLD2LG/dHN8xDAmRA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@swc/html-linux-arm64-musl@1.15.24': + resolution: {integrity: sha512-+7Xw69Y4p/LwhudMJZOQ++mKeXWTnh3vpNv5Ar+X1x8kfPBHKRXI3sRKf5JqE0oJqJXTgFP5xByzmO/KBee3sQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@swc/html-linux-ppc64-gnu@1.15.24': + resolution: {integrity: sha512-ZKxckgQkOY2a54jiCnIBs5TkMNx7zvuKbe1WsM/WV0BiTfMfw5iMmtCKAIuYCz/PJRXVK0dY4VH3DS7jabBvwg==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@swc/html-linux-s390x-gnu@1.15.24': + resolution: {integrity: sha512-y0WBjqDZALqOzasxrEOlgHq6SX34nAE4+0MATufmSoFEdiQIBYkm9m4C8XQNCNHv52ERCu/EPGK3Q8RfXaBLhQ==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@swc/html-linux-x64-gnu@1.15.24': + resolution: {integrity: sha512-U//u302yBSgh6vFfJmrw17Xm7k9a17m/E3AcHK4w12CZOFtsKHQnxE3i9uFWhNbW5F70w2A9QENml5b0Us8XMg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@swc/html-linux-x64-musl@1.15.24': + resolution: {integrity: sha512-U9gsAQCPiCROWKhLhSnW4JzkkOY6X4q0ZP/nA6UeKoahDdw4E8onPujtRSivt4ZxwdJKfAnsxeJY07V9YLZu9Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@swc/html-win32-arm64-msvc@1.15.24': + resolution: {integrity: sha512-AETh78z9ig4e1eAlx8a02BnIS5iNIJ7C43swQsxMraSDZvZuBxnvEXHqnt94jRlw7fzmJRRpJdVcInQ21u/xGA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/html-win32-ia32-msvc@1.15.24': + resolution: {integrity: sha512-ymJkEATvFF1+So41/SkulPBoRzRXP6HxUGfvdSJ29qeYejxWMrIWyjDE1+vAalo4IAR0cWFE2Ef2A2Qeg8QbGA==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/html-win32-x64-msvc@1.15.24': + resolution: {integrity: sha512-l+Gv0+jcSaDILljpEMC8pQE+ubRoZcft+woUgKTTlJQEFS+MgxKKLQjNCXx3hzhuru5/Yo8x71Ng/aVT7PwprA==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/html@1.15.24': + resolution: {integrity: sha512-2kWRCU09lBBg3bZLz8Kc37azQ6sBwiV1P7VDvqwKEJC2CtREe5y1XgLLd78kqSpFli52hZ6l3CNPDqkaX6ceAg==} + engines: {node: '>=14'} + + '@swc/types@0.1.26': + resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + + '@types/gtag.js@0.0.20': + resolution: {integrity: sha512-wwAbk3SA2QeU67unN7zPxjEHmPmlXwZXZvQEpbEUQuMCRGgKyE1m6XDuTUA9b6pCGb/GqJmdfMOY5LuDjJSbbg==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + + '@types/prismjs@1.26.6': + resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} + + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-router-config@5.0.11': + resolution: {integrity: sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==} + + '@types/react-router-dom@5.3.3': + resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} + + '@types/react-router@5.1.20': + resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@uiw/codemirror-extensions-basic-setup@4.25.9': + resolution: {integrity: sha512-QFAqr+pu6lDmNpAlecODcF49TlsrZ0bj15zPzfhiqSDl+Um3EsDLFLppixC7kFLn+rdDM2LTvVjn5CPvefpRgw==} + peerDependencies: + '@codemirror/autocomplete': '>=6.0.0' + '@codemirror/commands': '>=6.0.0' + '@codemirror/language': '>=6.0.0' + '@codemirror/lint': '>=6.0.0' + '@codemirror/search': '>=6.0.0' + '@codemirror/state': '>=6.0.0' + '@codemirror/view': '>=6.0.0' + + '@uiw/react-codemirror@4.25.9': + resolution: {integrity: sha512-HftqCBUYShAOH0pGi1CHP8vfm5L8fQ3+0j0VI6lQD6QpK+UBu3J7nxfEN5O/BXMilMNf9ZyFJRvRcuMMOLHMng==} + peerDependencies: + '@babel/runtime': '>=7.11.0' + '@codemirror/state': '>=6.0.0' + '@codemirror/theme-one-dark': '>=6.0.0' + '@codemirror/view': '>=6.0.0' + codemirror: '>=6.0.0' + react: '>=17.0.0' + react-dom: '>=17.0.0' + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + algoliasearch-helper@3.28.1: + resolution: {integrity: sha512-6iXpbkkrAI5HFpCWXlNmIDSBuoN/U1XnEvb2yJAoWfqrZ+DrybI7MQ5P5mthFaprmocq+zbi6HxnR28xnZAYBw==} + peerDependencies: + algoliasearch: '>= 3.1 < 6' + + algoliasearch@5.50.1: + resolution: {integrity: sha512-/bwdue1/8LWELn/DBalGRfuLsXBLXULJo/yOeavJtDu8rBwxIzC6/Rz9Jg19S21VkJvRuZO1k8CZXBMS73mYbA==} + engines: {node: '>= 14.0.0'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + asn1js@3.0.7: + resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} + engines: {node: '>=12.0.0'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + + babel-plugin-dynamic-import-node@2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} + + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.10.17: + resolution: {integrity: sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@6.2.1: + resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} + engines: {node: '>=14.16'} + + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chevrotain-allstar@0.4.1: + resolution: {integrity: sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA==} + peerDependencies: + chevrotain: ^12.0.0 + + chevrotain@12.0.0: + resolution: {integrity: sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ==} + engines: {node: '>=22.0.0'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + codemirror@6.0.2: + resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combine-promises@1.2.0: + resolution: {integrity: sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==} + engines: {node: '>=10'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@6.0.0: + resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} + engines: {node: '>=12'} + + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@0.5.2: + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} + engines: {node: '>= 0.6'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + copy-text-to-clipboard@3.2.2: + resolution: {integrity: sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==} + engines: {node: '>=12'} + + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.1.0 + + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + + core-js@3.49.0: + resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + + css-blank-pseudo@7.0.1: + resolution: {integrity: sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-declaration-sorter@7.4.0: + resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-has-pseudo@7.0.3: + resolution: {integrity: sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-loader@6.11.0: + resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + css-minimizer-webpack-plugin@5.0.1: + resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + + css-prefers-color-scheme@10.0.0: + resolution: {integrity: sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssdb@8.8.0: + resolution: {integrity: sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-advanced@6.1.2: + resolution: {integrity: sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-preset-default@6.1.2: + resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@4.0.2: + resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@6.1.2: + resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.33.2: + resolution: {integrity: sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} + + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.4.0: + resolution: {integrity: sha512-nolgK9JcaUXMSmW+j1yaSvaEaoXYHwWyGJlkoCTghc97KgGDDSnpoU/PlEnw63Ah+TGKFOyY+X5LnxaWbCSfXg==} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.334: + resolution: {integrity: sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + emoticon@4.1.0: + resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eta@2.2.0: + resolution: {integrity: sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==} + engines: {node: '>=6.0.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + feed@4.2.2: + resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} + engines: {node: '>=0.4.0'} + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-loader@6.2.0: + resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + github-slugger@1.5.0: + resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + history@4.10.1: + resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-minifier-terser@7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-webpack-plugin@5.6.6: + resolution: {integrity: sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==} + engines: {node: '>=10.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infima@0.2.0-alpha.45: + resolution: {integrity: sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==} + engines: {node: '>=12'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + engines: {node: '>=16'} + + is-npm@6.1.0: + resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + katex@0.16.45: + resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + langium@4.2.2: + resolution: {integrity: sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@2.0.0: + resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@4.57.1: + resolution: {integrity: sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==} + peerDependencies: + tslib: '2' + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + mermaid@11.14.0: + resolution: {integrity: sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.33.0: + resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.18: + resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + mini-css-extract-plugin@2.10.2: + resolution: {integrity: sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} + engines: {node: '>=14.16'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + null-loader@4.0.1: + resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} + + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + postcss-attribute-case-insensitive@7.0.1: + resolution: {integrity: sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-calc@9.0.1: + resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.2.2 + + postcss-clamp@4.1.0: + resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} + engines: {node: '>=7.6.0'} + peerDependencies: + postcss: ^8.4.6 + + postcss-color-functional-notation@7.0.12: + resolution: {integrity: sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-hex-alpha@10.0.0: + resolution: {integrity: sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-rebeccapurple@10.0.0: + resolution: {integrity: sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-colormin@6.1.0: + resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@6.1.0: + resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-custom-media@11.0.6: + resolution: {integrity: sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-properties@14.0.6: + resolution: {integrity: sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-selectors@8.0.5: + resolution: {integrity: sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-dir-pseudo-class@9.0.1: + resolution: {integrity: sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-discard-comments@6.0.2: + resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@6.0.3: + resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@6.0.3: + resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@6.0.2: + resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-unused@6.0.5: + resolution: {integrity: sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-double-position-gradients@6.0.4: + resolution: {integrity: sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-visible@10.0.1: + resolution: {integrity: sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-within@9.0.1: + resolution: {integrity: sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-font-variant@5.0.0: + resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} + peerDependencies: + postcss: ^8.1.0 + + postcss-gap-properties@6.0.0: + resolution: {integrity: sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-image-set-function@7.0.0: + resolution: {integrity: sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-lab-function@7.0.12: + resolution: {integrity: sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-loader@7.3.4: + resolution: {integrity: sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==} + engines: {node: '>= 14.15.0'} + peerDependencies: + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + + postcss-logical@8.1.0: + resolution: {integrity: sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-merge-idents@6.0.3: + resolution: {integrity: sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-longhand@6.0.5: + resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@6.1.1: + resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@6.1.0: + resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@6.0.3: + resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@6.1.0: + resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@6.0.4: + resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nesting@13.0.2: + resolution: {integrity: sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-normalize-charset@6.0.2: + resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@6.0.2: + resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@6.0.2: + resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@6.0.2: + resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@6.0.2: + resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@6.0.2: + resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@6.1.0: + resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@6.0.2: + resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@6.0.2: + resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-opacity-percentage@3.0.0: + resolution: {integrity: sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-ordered-values@6.0.2: + resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-overflow-shorthand@6.0.0: + resolution: {integrity: sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-page-break@3.0.4: + resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} + peerDependencies: + postcss: ^8 + + postcss-place@10.0.0: + resolution: {integrity: sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-preset-env@10.6.1: + resolution: {integrity: sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-pseudo-class-any-link@10.0.1: + resolution: {integrity: sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-reduce-idents@6.0.3: + resolution: {integrity: sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@6.1.0: + resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@6.0.2: + resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-replace-overflow-wrap@4.0.0: + resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} + peerDependencies: + postcss: ^8.0.3 + + postcss-selector-not@8.0.1: + resolution: {integrity: sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-sort-media-queries@5.2.0: + resolution: {integrity: sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.4.23 + + postcss-svgo@6.0.3: + resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} + engines: {node: ^14 || ^16 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@6.0.4: + resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss-zindex@6.0.2: + resolution: {integrity: sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + engines: {node: ^10 || ^12 || >=14} + + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-time@1.1.0: + resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} + engines: {node: '>=4'} + + prism-react-renderer@2.4.1: + resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} + peerDependencies: + react: '>=16.0.0' + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@3.3.0: + resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} + engines: {node: '>=12.20'} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.0: + resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} + engines: {node: '>= 0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@19.2.5: + resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} + peerDependencies: + react: ^19.2.5 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-json-view-lite@2.5.0: + resolution: {integrity: sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==} + engines: {node: '>=18'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + react-loadable-ssr-addon-v5-slorber@1.0.3: + resolution: {integrity: sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + react-loadable: '*' + webpack: '>=4.41.1 || 5.x' + + react-router-config@5.1.1: + resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} + peerDependencies: + react: '>=15' + react-router: '>=5' + + react-router-dom@5.3.4: + resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==} + peerDependencies: + react: '>=15' + + react-router@5.3.4: + resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==} + peerDependencies: + react: '>=15' + + react@19.2.5: + resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.1: + resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + hasBin: true + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-emoji@4.0.1: + resolution: {integrity: sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pathname@3.0.0: + resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} + engines: {node: '>=12.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + schema-dts@1.1.5: + resolution: {integrity: sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} + + semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-handler@6.1.7: + resolution: {integrity: sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==} + + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@7.1.3: + resolution: {integrity: sha512-tAjEd+wt/YwnEbfNB2ht51ybBJxbEWwe5ki/Z//Wh0rpBFTCUSj46GnxUKEWzhfuJTsee8x3lybHxFgUMig2hw==} + engines: {node: '>=12.0.0', npm: '>=5.6.0'} + hasBin: true + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + sort-css-media-queries@2.2.0: + resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} + engines: {node: '>= 6.3.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + srcset@4.0.0: + resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} + engines: {node: '>=12'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-mod@4.1.3: + resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + stylehacks@6.1.1: + resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + svgo@3.3.3: + resolution: {integrity: sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==} + engines: {node: '>=14.0.0'} + hasBin: true + + swc-loader@0.2.7: + resolution: {integrity: sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==} + peerDependencies: + '@swc/core': ^1.2.147 + webpack: '>=2' + + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.4.0: + resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.46.1: + resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + engines: {node: '>=10'} + hasBin: true + + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ts-loader@9.5.7: + resolution: {integrity: sha512-/ZNrKgA3K3PtpMYOC71EeMWIloGw3IYEa5/t1cyz2r5/PyUwTXGzYJvcD3kfUvmhlfpz1rhV8B2O6IVTQ0avsg==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typescript@6.0.2: + resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-loader@4.1.1: + resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + file-loader: '*' + webpack: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + file-loader: + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + value-equal@1.0.1: + resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + webpack-bundle-analyzer@4.10.2: + resolution: {integrity: sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==} + engines: {node: '>= 10.13.0'} + hasBin: true + + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-dev-server@5.2.3: + resolution: {integrity: sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@3.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + engines: {node: '>=10.13.0'} + + webpack@5.106.1: + resolution: {integrity: sha512-EW8af29ak8Oaf4T8k8YsajjrDBDYgnKZ5er6ljWFJsXABfTNowQfvHLftwcepVgdz+IoLSdEAbBiM9DFXoll9w==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + webpackbar@6.0.1: + resolution: {integrity: sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + webpack: 3 || 4 || 5 + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@algolia/abtesting@1.16.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-core@1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-plugin-algolia-insights@1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)': + dependencies: + '@algolia/client-search': 5.50.1 + algoliasearch: 5.50.1 + + '@algolia/autocomplete-shared@1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)': + dependencies: + '@algolia/client-search': 5.50.1 + algoliasearch: 5.50.1 + + '@algolia/client-abtesting@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-analytics@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-common@5.50.1': {} + + '@algolia/client-insights@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-personalization@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-query-suggestions@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-search@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/events@4.0.1': {} + + '@algolia/ingestion@1.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/monitoring@1.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/recommend@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/requester-browser-xhr@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + + '@algolia/requester-fetch@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + + '@algolia/requester-node-http@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.1.1 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3 + lodash.debounce: 4.0.8 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-env@7.29.2(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 + esutils: 2.0.3 + + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@braintree/sanitize-url@7.1.2': {} + + '@chevrotain/cst-dts-gen@12.0.0': + dependencies: + '@chevrotain/gast': 12.0.0 + '@chevrotain/types': 12.0.0 + + '@chevrotain/gast@12.0.0': + dependencies: + '@chevrotain/types': 12.0.0 + + '@chevrotain/regexp-to-ast@12.0.0': {} + + '@chevrotain/types@12.0.0': {} + + '@chevrotain/utils@12.0.0': {} + + '@codemirror/autocomplete@6.20.1': + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + '@lezer/common': 1.5.2 + + '@codemirror/commands@6.10.3': + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + '@lezer/common': 1.5.2 + + '@codemirror/language@6.12.3': + dependencies: + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.8 + style-mod: 4.1.3 + + '@codemirror/lint@6.9.5': + dependencies: + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + crelt: 1.0.6 + + '@codemirror/search@6.6.0': + dependencies: + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + crelt: 1.0.6 + + '@codemirror/state@6.6.0': + dependencies: + '@marijn/find-cluster-break': 1.0.2 + + '@codemirror/theme-one-dark@6.1.3': + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + '@lezer/highlight': 1.2.3 + + '@codemirror/view@6.41.0': + dependencies: + '@codemirror/state': 6.6.0 + crelt: 1.0.6 + style-mod: 4.1.3 + w3c-keyname: 2.2.8 + + '@colors/colors@1.5.0': + optional: true + + '@csstools/cascade-layer-name-parser@2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/postcss-alpha-function@1.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.9)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-color-function@4.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-color-mix-function@3.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-content-alt-text@2.0.8(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-contrast-color-function@2.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-exponential-functions@2.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.9)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-gamut-mapping@2.0.11(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-gradients-interpolation-method@5.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-hwb-function@4.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-ic-unit@4.0.4(postcss@8.5.9)': + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-initial@2.0.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.9)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-logical-viewport-units@3.0.4(postcss@8.5.9)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-media-minmax@2.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.9 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.9 + + '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.9)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-normalize-display-values@4.0.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-oklab-function@4.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-position-area-property@1.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-property-rule-prelude-list@1.0.0(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-random-function@2.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-relative-color-syntax@3.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-sign-functions@1.1.4(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-stepped-value-functions@4.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-system-ui-font-family@1.0.0(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.9)': + dependencies: + '@csstools/color-helpers': 5.1.0 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-trigonometric-functions@4.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-unset-value@4.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/utilities@2.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@discoveryjs/json-ext@0.5.7': {} + + '@docsearch/core@4.6.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + optionalDependencies: + '@types/react': 19.2.14 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + '@docsearch/css@4.6.2': {} + + '@docsearch/react@4.6.2(@algolia/client-search@5.50.1)(@types/react@19.2.14)(algoliasearch@5.50.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@docsearch/core': 4.6.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docsearch/css': 4.6.2 + optionalDependencies: + '@types/react': 19.2.14 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@docusaurus/babel@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 + '@babel/traverse': 7.29.0 + '@docusaurus/logger': 3.10.0 + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + babel-plugin-dynamic-import-node: 2.3.3 + fs-extra: 11.3.4 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/bundler@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@babel/core': 7.29.0 + '@docusaurus/babel': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/cssnano-preset': 3.10.0 + '@docusaurus/logger': 3.10.0 + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.106.1(@swc/core@1.15.24)) + clean-css: 5.3.3 + copy-webpack-plugin: 11.0.0(webpack@5.106.1(@swc/core@1.15.24)) + css-loader: 6.11.0(@rspack/core@1.7.11)(webpack@5.106.1(@swc/core@1.15.24)) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.106.1(@swc/core@1.15.24)) + cssnano: 6.1.2(postcss@8.5.9) + file-loader: 6.2.0(webpack@5.106.1(@swc/core@1.15.24)) + html-minifier-terser: 7.2.0 + mini-css-extract-plugin: 2.10.2(webpack@5.106.1(@swc/core@1.15.24)) + null-loader: 4.0.1(webpack@5.106.1(@swc/core@1.15.24)) + postcss: 8.5.9 + postcss-loader: 7.3.4(postcss@8.5.9)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24)) + postcss-preset-env: 10.6.1(postcss@8.5.9) + terser-webpack-plugin: 5.4.0(@swc/core@1.15.24)(webpack@5.106.1(@swc/core@1.15.24)) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.1(@swc/core@1.15.24)))(webpack@5.106.1(@swc/core@1.15.24)) + webpack: 5.106.1(@swc/core@1.15.24) + webpackbar: 6.0.1(webpack@5.106.1(@swc/core@1.15.24)) + optionalDependencies: + '@docusaurus/faster': 3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + transitivePeerDependencies: + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - csso + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - webpack-cli + + '@docusaurus/core@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/babel': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/bundler': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/logger': 3.10.0 + '@docusaurus/mdx-loader': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + boxen: 6.2.1 + chalk: 4.1.2 + chokidar: 3.6.0 + cli-table3: 0.6.5 + combine-promises: 1.2.0 + commander: 5.1.0 + core-js: 3.49.0 + detect-port: 1.6.1 + escape-html: 1.0.3 + eta: 2.2.0 + eval: 0.1.8 + execa: 5.1.1 + fs-extra: 11.3.4 + html-tags: 3.3.1 + html-webpack-plugin: 5.6.6(@rspack/core@1.7.11)(webpack@5.106.1(@swc/core@1.15.24)) + leven: 3.1.0 + lodash: 4.18.1 + open: 8.4.2 + p-map: 4.0.0 + prompts: 2.4.2 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' + react-loadable-ssr-addon-v5-slorber: 1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.5))(webpack@5.106.1(@swc/core@1.15.24)) + react-router: 5.3.4(react@19.2.5) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.5))(react@19.2.5) + react-router-dom: 5.3.4(react@19.2.5) + semver: 7.7.4 + serve-handler: 6.1.7 + tinypool: 1.1.1 + tslib: 2.8.1 + update-notifier: 6.0.2 + webpack: 5.106.1(@swc/core@1.15.24) + webpack-bundle-analyzer: 4.10.2 + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24)) + webpack-merge: 6.0.1 + optionalDependencies: + '@docusaurus/faster': 3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + transitivePeerDependencies: + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/cssnano-preset@3.10.0': + dependencies: + cssnano-preset-advanced: 6.1.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-sort-media-queries: 5.2.0(postcss@8.5.9) + tslib: 2.8.1 + + '@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': + dependencies: + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@rspack/core': 1.7.11 + '@swc/core': 1.15.24 + '@swc/html': 1.15.24 + browserslist: 4.28.2 + lightningcss: 1.32.0 + semver: 7.7.4 + swc-loader: 0.2.7(@swc/core@1.15.24)(webpack@5.106.1(@swc/core@1.15.24)) + tslib: 2.8.1 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@swc/helpers' + - esbuild + - uglify-js + - webpack-cli + + '@docusaurus/logger@3.10.0': + dependencies: + chalk: 4.1.2 + tslib: 2.8.1 + + '@docusaurus/mdx-loader@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@docusaurus/logger': 3.10.0 + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@mdx-js/mdx': 3.1.1 + '@slorber/remark-comment': 1.0.0 + escape-html: 1.0.3 + estree-util-value-to-estree: 3.5.0 + file-loader: 6.2.0(webpack@5.106.1(@swc/core@1.15.24)) + fs-extra: 11.3.4 + image-size: 2.0.2 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + rehype-raw: 7.0.0 + remark-directive: 3.0.1 + remark-emoji: 4.0.1 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + stringify-object: 3.3.0 + tslib: 2.8.1 + unified: 11.0.5 + unist-util-visit: 5.1.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.1(@swc/core@1.15.24)))(webpack@5.106.1(@swc/core@1.15.24)) + vfile: 6.0.3 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/module-type-aliases@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router-config': 5.0.11 + '@types/react-router-dom': 5.3.3 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/plugin-content-blog@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/logger': 3.10.0 + '@docusaurus/mdx-loader': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/plugin-content-docs': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + cheerio: 1.0.0-rc.12 + combine-promises: 1.2.0 + feed: 4.2.2 + fs-extra: 11.3.4 + lodash: 4.18.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + schema-dts: 1.1.5 + srcset: 4.0.0 + tslib: 2.8.1 + unist-util-visit: 5.1.0 + utility-types: 3.11.0 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/logger': 3.10.0 + '@docusaurus/mdx-loader': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/module-type-aliases': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@types/react-router-config': 5.0.11 + combine-promises: 1.2.0 + fs-extra: 11.3.4 + js-yaml: 4.1.1 + lodash: 4.18.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + schema-dts: 1.1.5 + tslib: 2.8.1 + utility-types: 3.11.0 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-pages@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/mdx-loader': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + fs-extra: 11.3.4 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-css-cascade-layers@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-debug@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + fs-extra: 11.3.4 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-json-view-lite: 2.5.0(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-analytics@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-gtag@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@types/gtag.js': 0.0.20 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-tag-manager@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-sitemap@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/logger': 3.10.0 + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + fs-extra: 11.3.4 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + sitemap: 7.1.3 + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-svgr@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@svgr/core': 8.1.0(typescript@6.0.2) + '@svgr/webpack': 8.1.0(typescript@6.0.2) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/preset-classic@3.10.0(@algolia/client-search@5.50.1)(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-content-blog': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-content-docs': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-content-pages': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-css-cascade-layers': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-debug': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-google-analytics': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-google-gtag': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-google-tag-manager': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-sitemap': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-svgr': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/theme-classic': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/theme-search-algolia': 3.10.0(@algolia/client-search@5.50.1)(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + transitivePeerDependencies: + - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/react-loadable@6.0.0(react@19.2.5)': + dependencies: + '@types/react': 19.2.14 + react: 19.2.5 + + '@docusaurus/theme-classic@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/logger': 3.10.0 + '@docusaurus/mdx-loader': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/module-type-aliases': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/plugin-content-blog': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-content-docs': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/plugin-content-pages': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/theme-translations': 3.10.0 + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + clsx: 2.1.1 + copy-text-to-clipboard: 3.2.2 + infima: 0.2.0-alpha.45 + lodash: 4.18.1 + nprogress: 0.2.0 + postcss: 8.5.9 + prism-react-renderer: 2.4.1(react@19.2.5) + prismjs: 1.30.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-router-dom: 5.3.4(react@19.2.5) + rtlcss: 4.3.0 + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-common@3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@docusaurus/mdx-loader': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/module-type-aliases': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/plugin-content-docs': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router-config': 5.0.11 + clsx: 2.1.1 + parse-numeric-range: 1.3.0 + prism-react-renderer: 2.4.1(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/theme-mermaid@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/module-type-aliases': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + mermaid: 11.14.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@docusaurus/plugin-content-docs' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-search-algolia@3.10.0(@algolia/client-search@5.50.1)(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2)': + dependencies: + '@algolia/autocomplete-core': 1.19.8(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@docsearch/react': 4.6.2(@algolia/client-search@5.50.1)(@types/react@19.2.14)(algoliasearch@5.50.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3) + '@docusaurus/core': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/logger': 3.10.0 + '@docusaurus/plugin-content-docs': 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/theme-translations': 3.10.0 + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-validation': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + algoliasearch: 5.50.1 + algoliasearch-helper: 3.28.1(algoliasearch@5.50.1) + clsx: 2.1.1 + eta: 2.2.0 + fs-extra: 11.3.4 + lodash: 4.18.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-translations@3.10.0': + dependencies: + fs-extra: 11.3.4 + tslib: 2.8.1 + + '@docusaurus/tsconfig@3.10.0': {} + + '@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@mdx-js/mdx': 3.1.1 + '@types/history': 4.7.11 + '@types/mdast': 4.0.4 + '@types/react': 19.2.14 + commander: 5.1.0 + joi: 17.13.3 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' + utility-types: 3.11.0 + webpack: 5.106.1(@swc/core@1.15.24) + webpack-merge: 5.10.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-common@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-validation@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@docusaurus/logger': 3.10.0 + '@docusaurus/utils': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + fs-extra: 11.3.4 + joi: 17.13.3 + js-yaml: 4.1.1 + lodash: 4.18.1 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@docusaurus/logger': 3.10.0 + '@docusaurus/types': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils-common': 3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + escape-string-regexp: 4.0.0 + execa: 5.1.1 + file-loader: 6.2.0(webpack@5.106.1(@swc/core@1.15.24)) + fs-extra: 11.3.4 + github-slugger: 1.5.0 + globby: 11.1.0 + gray-matter: 4.0.3 + jiti: 1.21.7 + js-yaml: 4.1.1 + lodash: 4.18.1 + micromatch: 4.0.8 + p-queue: 6.6.2 + prompts: 2.4.2 + resolve-pathname: 3.0.0 + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.1(@swc/core@1.15.24)))(webpack@5.106.1(@swc/core@1.15.24)) + utility-types: 3.11.0 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.2 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 25.6.0 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.57.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@lezer/common@1.5.2': {} + + '@lezer/highlight@1.2.3': + dependencies: + '@lezer/common': 1.5.2 + + '@lezer/lr@1.4.8': + dependencies: + '@lezer/common': 1.5.2 + + '@marijn/find-cluster-break@1.0.2': {} + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.16.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.16.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.14 + react: 19.2.5 + + '@mermaid-js/parser@1.1.0': + dependencies: + langium: 4.2.2 + + '@module-federation/error-codes@0.22.0': {} + + '@module-federation/runtime-core@0.22.0': + dependencies: + '@module-federation/error-codes': 0.22.0 + '@module-federation/sdk': 0.22.0 + + '@module-federation/runtime-tools@0.22.0': + dependencies: + '@module-federation/runtime': 0.22.0 + '@module-federation/webpack-bundler-runtime': 0.22.0 + + '@module-federation/runtime@0.22.0': + dependencies: + '@module-federation/error-codes': 0.22.0 + '@module-federation/runtime-core': 0.22.0 + '@module-federation/sdk': 0.22.0 + + '@module-federation/sdk@0.22.0': {} + + '@module-federation/webpack-bundler-runtime@0.22.0': + dependencies: + '@module-federation/runtime': 0.22.0 + '@module-federation/sdk': 0.22.0 + + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@noble/hashes@1.4.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@peculiar/asn1-cms@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.6.1': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.6.1': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pfx': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.6.0': + dependencies: + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-csr': 2.6.1 + '@peculiar/asn1-ecc': 2.6.1 + '@peculiar/asn1-pkcs9': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@3.0.2': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@polka/url@1.0.0-next.29': {} + + '@rspack/binding-darwin-arm64@1.7.11': + optional: true + + '@rspack/binding-darwin-x64@1.7.11': + optional: true + + '@rspack/binding-linux-arm64-gnu@1.7.11': + optional: true + + '@rspack/binding-linux-arm64-musl@1.7.11': + optional: true + + '@rspack/binding-linux-x64-gnu@1.7.11': + optional: true + + '@rspack/binding-linux-x64-musl@1.7.11': + optional: true + + '@rspack/binding-wasm32-wasi@1.7.11': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + + '@rspack/binding-win32-arm64-msvc@1.7.11': + optional: true + + '@rspack/binding-win32-ia32-msvc@1.7.11': + optional: true + + '@rspack/binding-win32-x64-msvc@1.7.11': + optional: true + + '@rspack/binding@1.7.11': + optionalDependencies: + '@rspack/binding-darwin-arm64': 1.7.11 + '@rspack/binding-darwin-x64': 1.7.11 + '@rspack/binding-linux-arm64-gnu': 1.7.11 + '@rspack/binding-linux-arm64-musl': 1.7.11 + '@rspack/binding-linux-x64-gnu': 1.7.11 + '@rspack/binding-linux-x64-musl': 1.7.11 + '@rspack/binding-wasm32-wasi': 1.7.11 + '@rspack/binding-win32-arm64-msvc': 1.7.11 + '@rspack/binding-win32-ia32-msvc': 1.7.11 + '@rspack/binding-win32-x64-msvc': 1.7.11 + + '@rspack/core@1.7.11': + dependencies: + '@module-federation/runtime-tools': 0.22.0 + '@rspack/binding': 1.7.11 + '@rspack/lite-tapable': 1.1.0 + + '@rspack/lite-tapable@1.1.0': {} + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sinclair/typebox@0.27.10': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@5.6.0': {} + + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + invariant: 2.2.4 + prop-types: 15.8.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + + '@slorber/remark-comment@1.0.0': + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0) + + '@svgr/core@8.1.0(typescript@6.0.2)': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@6.0.2) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@svgr/hast-util-to-babel-ast@8.0.0': + dependencies: + '@babel/types': 7.29.0 + entities: 4.5.0 + + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@6.0.2))': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + '@svgr/core': 8.1.0(typescript@6.0.2) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@6.0.2))(typescript@6.0.2)': + dependencies: + '@svgr/core': 8.1.0(typescript@6.0.2) + cosmiconfig: 8.3.6(typescript@6.0.2) + deepmerge: 4.3.1 + svgo: 3.3.3 + transitivePeerDependencies: + - typescript + + '@svgr/webpack@8.1.0(typescript@6.0.2)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@svgr/core': 8.1.0(typescript@6.0.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.2)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.2))(typescript@6.0.2) + transitivePeerDependencies: + - supports-color + - typescript + + '@swc/core-darwin-arm64@1.15.24': + optional: true + + '@swc/core-darwin-x64@1.15.24': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.24': + optional: true + + '@swc/core-linux-arm64-gnu@1.15.24': + optional: true + + '@swc/core-linux-arm64-musl@1.15.24': + optional: true + + '@swc/core-linux-ppc64-gnu@1.15.24': + optional: true + + '@swc/core-linux-s390x-gnu@1.15.24': + optional: true + + '@swc/core-linux-x64-gnu@1.15.24': + optional: true + + '@swc/core-linux-x64-musl@1.15.24': + optional: true + + '@swc/core-win32-arm64-msvc@1.15.24': + optional: true + + '@swc/core-win32-ia32-msvc@1.15.24': + optional: true + + '@swc/core-win32-x64-msvc@1.15.24': + optional: true + + '@swc/core@1.15.24': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.26 + optionalDependencies: + '@swc/core-darwin-arm64': 1.15.24 + '@swc/core-darwin-x64': 1.15.24 + '@swc/core-linux-arm-gnueabihf': 1.15.24 + '@swc/core-linux-arm64-gnu': 1.15.24 + '@swc/core-linux-arm64-musl': 1.15.24 + '@swc/core-linux-ppc64-gnu': 1.15.24 + '@swc/core-linux-s390x-gnu': 1.15.24 + '@swc/core-linux-x64-gnu': 1.15.24 + '@swc/core-linux-x64-musl': 1.15.24 + '@swc/core-win32-arm64-msvc': 1.15.24 + '@swc/core-win32-ia32-msvc': 1.15.24 + '@swc/core-win32-x64-msvc': 1.15.24 + + '@swc/counter@0.1.3': {} + + '@swc/html-darwin-arm64@1.15.24': + optional: true + + '@swc/html-darwin-x64@1.15.24': + optional: true + + '@swc/html-linux-arm-gnueabihf@1.15.24': + optional: true + + '@swc/html-linux-arm64-gnu@1.15.24': + optional: true + + '@swc/html-linux-arm64-musl@1.15.24': + optional: true + + '@swc/html-linux-ppc64-gnu@1.15.24': + optional: true + + '@swc/html-linux-s390x-gnu@1.15.24': + optional: true + + '@swc/html-linux-x64-gnu@1.15.24': + optional: true + + '@swc/html-linux-x64-musl@1.15.24': + optional: true + + '@swc/html-win32-arm64-msvc@1.15.24': + optional: true + + '@swc/html-win32-ia32-msvc@1.15.24': + optional: true + + '@swc/html-win32-x64-msvc@1.15.24': + optional: true + + '@swc/html@1.15.24': + dependencies: + '@swc/counter': 0.1.3 + optionalDependencies: + '@swc/html-darwin-arm64': 1.15.24 + '@swc/html-darwin-x64': 1.15.24 + '@swc/html-linux-arm-gnueabihf': 1.15.24 + '@swc/html-linux-arm64-gnu': 1.15.24 + '@swc/html-linux-arm64-musl': 1.15.24 + '@swc/html-linux-ppc64-gnu': 1.15.24 + '@swc/html-linux-s390x-gnu': 1.15.24 + '@swc/html-linux-x64-gnu': 1.15.24 + '@swc/html-linux-x64-musl': 1.15.24 + '@swc/html-win32-arm64-msvc': 1.15.24 + '@swc/html-win32-ia32-msvc': 1.15.24 + '@swc/html-win32-x64-msvc': 1.15.24 + + '@swc/types@0.1.26': + dependencies: + '@swc/counter': 0.1.3 + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 25.6.0 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 25.6.0 + + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 4.19.8 + '@types/node': 25.6.0 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 25.6.0 + + '@types/d3-array@3.2.2': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 25.6.0 + '@types/qs': 6.15.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.0 + '@types/serve-static': 1.15.10 + + '@types/geojson@7946.0.16': {} + + '@types/gtag.js@0.0.20': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/history@4.7.11': {} + + '@types/html-minifier-terser@6.1.0': {} + + '@types/http-cache-semantics@4.2.0': {} + + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 25.6.0 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/mime@1.3.5': {} + + '@types/ms@2.1.0': {} + + '@types/node@17.0.45': {} + + '@types/node@25.6.0': + dependencies: + undici-types: 7.19.2 + + '@types/prismjs@1.26.6': {} + + '@types/qs@6.15.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-router-config@5.0.11': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router': 5.1.20 + + '@types/react-router-dom@5.3.3': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router': 5.1.20 + + '@types/react-router@5.1.20': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/retry@0.12.2': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 17.0.45 + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 25.6.0 + + '@types/send@1.2.1': + dependencies: + '@types/node': 25.6.0 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 25.6.0 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 25.6.0 + + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.6.0 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@uiw/codemirror-extensions-basic-setup@4.25.9(@codemirror/autocomplete@6.20.1)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/view@6.41.0)': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/commands': 6.10.3 + '@codemirror/language': 6.12.3 + '@codemirror/lint': 6.9.5 + '@codemirror/search': 6.6.0 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + + '@uiw/react-codemirror@4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.41.0)(codemirror@6.0.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + '@codemirror/commands': 6.10.3 + '@codemirror/state': 6.6.0 + '@codemirror/theme-one-dark': 6.1.3 + '@codemirror/view': 6.41.0 + '@uiw/codemirror-extensions-basic-setup': 4.25.9(@codemirror/autocomplete@6.20.1)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/view@6.41.0) + codemirror: 6.0.2 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + transitivePeerDependencies: + - '@codemirror/autocomplete' + - '@codemirror/language' + - '@codemirror/lint' + - '@codemirror/search' + + '@ungap/structured-clone@1.3.0': {} + + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-import-phases@1.0.4(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-walk@8.3.5: + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + address@1.2.2: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv-formats@2.1.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv-keywords@3.5.2(ajv@6.14.0): + dependencies: + ajv: 6.14.0 + + ajv-keywords@5.1.0(ajv@8.18.0): + dependencies: + ajv: 8.18.0 + fast-deep-equal: 3.1.3 + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algoliasearch-helper@3.28.1(algoliasearch@5.50.1): + dependencies: + '@algolia/events': 4.0.1 + algoliasearch: 5.50.1 + + algoliasearch@5.50.1: + dependencies: + '@algolia/abtesting': 1.16.1 + '@algolia/client-abtesting': 5.50.1 + '@algolia/client-analytics': 5.50.1 + '@algolia/client-common': 5.50.1 + '@algolia/client-insights': 5.50.1 + '@algolia/client-personalization': 5.50.1 + '@algolia/client-query-suggestions': 5.50.1 + '@algolia/client-search': 5.50.1 + '@algolia/ingestion': 1.50.1 + '@algolia/monitoring': 1.50.1 + '@algolia/recommend': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-html-community@0.0.8: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + array-union@2.1.0: {} + + asn1js@3.0.7: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + + astring@1.9.0: {} + + autoprefixer@10.4.27(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001787 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 4.0.0 + schema-utils: 4.3.3 + webpack: 5.106.1(@swc/core@1.15.24) + + babel-plugin-dynamic-import-node@2.3.3: + dependencies: + object.assign: 4.1.7 + + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.10.17: {} + + batch@0.6.1: {} + + big.js@5.2.2: {} + + binary-extensions@2.3.0: {} + + body-parser@1.20.4: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bonjour-service@1.3.0: + dependencies: + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + + boolbase@1.0.0: {} + + boxen@6.2.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + boxen@7.1.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.17 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.334 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + bytes@3.0.0: {} + + bytes@3.1.2: {} + + bytestreamjs@2.0.1: {} + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.2.0 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.1.1 + responselike: 3.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.8.1 + + camelcase@6.3.0: {} + + camelcase@7.0.1: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001787 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001787: {} + + ccount@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + htmlparser2: 8.0.2 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + + chevrotain-allstar@0.4.1(chevrotain@12.0.0): + dependencies: + chevrotain: 12.0.0 + lodash-es: 4.18.1 + + chevrotain@12.0.0: + dependencies: + '@chevrotain/cst-dts-gen': 12.0.0 + '@chevrotain/gast': 12.0.0 + '@chevrotain/regexp-to-ast': 12.0.0 + '@chevrotain/types': 12.0.0 + '@chevrotain/utils': 12.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chrome-trace-event@1.0.4: {} + + ci-info@3.9.0: {} + + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + + clean-stack@2.2.0: {} + + cli-boxes@3.0.0: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + clsx@2.1.1: {} + + codemirror@6.0.2: + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/commands': 6.10.3 + '@codemirror/language': 6.12.3 + '@codemirror/lint': 6.9.5 + '@codemirror/search': 6.6.0 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.0 + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colord@2.9.3: {} + + colorette@2.0.20: {} + + combine-promises@1.2.0: {} + + comma-separated-tokens@2.0.3: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@5.1.0: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + common-path-prefix@3.0.0: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@6.0.0: + dependencies: + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 + + connect-history-api-fallback@2.0.0: {} + + consola@3.4.2: {} + + content-disposition@0.5.2: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + copy-text-to-clipboard@3.2.2: {} + + copy-webpack-plugin@11.0.0(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.106.1(@swc/core@1.15.24) + + core-js-compat@3.49.0: + dependencies: + browserslist: 4.28.2 + + core-js@3.49.0: {} + + core-util-is@1.0.3: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + cosmiconfig@8.3.6(typescript@6.0.2): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 6.0.2 + + crelt@1.0.6: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + css-blank-pseudo@7.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + css-declaration-sorter@7.4.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + css-has-pseudo@7.0.3(postcss@8.5.9): + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + css-loader@6.11.0(@rspack/core@1.7.11)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.9) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.9) + postcss-modules-scope: 3.2.1(postcss@8.5.9) + postcss-modules-values: 4.0.0(postcss@8.5.9) + postcss-value-parser: 4.2.0 + semver: 7.7.4 + optionalDependencies: + '@rspack/core': 1.7.11 + webpack: 5.106.1(@swc/core@1.15.24) + + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 6.1.2(postcss@8.5.9) + jest-worker: 29.7.0 + postcss: 8.5.9 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.106.1(@swc/core@1.15.24) + optionalDependencies: + clean-css: 5.3.3 + + css-prefers-color-scheme@10.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + cssdb@8.8.0: {} + + cssesc@3.0.0: {} + + cssnano-preset-advanced@6.1.2(postcss@8.5.9): + dependencies: + autoprefixer: 10.4.27(postcss@8.5.9) + browserslist: 4.28.2 + cssnano-preset-default: 6.1.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-discard-unused: 6.0.5(postcss@8.5.9) + postcss-merge-idents: 6.0.3(postcss@8.5.9) + postcss-reduce-idents: 6.0.3(postcss@8.5.9) + postcss-zindex: 6.0.2(postcss@8.5.9) + + cssnano-preset-default@6.1.2(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + css-declaration-sorter: 7.4.0(postcss@8.5.9) + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-calc: 9.0.1(postcss@8.5.9) + postcss-colormin: 6.1.0(postcss@8.5.9) + postcss-convert-values: 6.1.0(postcss@8.5.9) + postcss-discard-comments: 6.0.2(postcss@8.5.9) + postcss-discard-duplicates: 6.0.3(postcss@8.5.9) + postcss-discard-empty: 6.0.3(postcss@8.5.9) + postcss-discard-overridden: 6.0.2(postcss@8.5.9) + postcss-merge-longhand: 6.0.5(postcss@8.5.9) + postcss-merge-rules: 6.1.1(postcss@8.5.9) + postcss-minify-font-values: 6.1.0(postcss@8.5.9) + postcss-minify-gradients: 6.0.3(postcss@8.5.9) + postcss-minify-params: 6.1.0(postcss@8.5.9) + postcss-minify-selectors: 6.0.4(postcss@8.5.9) + postcss-normalize-charset: 6.0.2(postcss@8.5.9) + postcss-normalize-display-values: 6.0.2(postcss@8.5.9) + postcss-normalize-positions: 6.0.2(postcss@8.5.9) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.9) + postcss-normalize-string: 6.0.2(postcss@8.5.9) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.9) + postcss-normalize-unicode: 6.1.0(postcss@8.5.9) + postcss-normalize-url: 6.0.2(postcss@8.5.9) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.9) + postcss-ordered-values: 6.0.2(postcss@8.5.9) + postcss-reduce-initial: 6.1.0(postcss@8.5.9) + postcss-reduce-transforms: 6.0.2(postcss@8.5.9) + postcss-svgo: 6.0.3(postcss@8.5.9) + postcss-unique-selectors: 6.0.4(postcss@8.5.9) + + cssnano-utils@4.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + cssnano@6.1.2(postcss@8.5.9): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.5.9) + lilconfig: 3.1.3 + postcss: 8.5.9 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.2.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.2): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.33.2 + + cytoscape-fcose@2.2.0(cytoscape@3.33.2): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.33.2 + + cytoscape@3.33.2: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.18.1 + + dayjs@1.11.20: {} + + debounce@1.2.1: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + + depd@1.1.2: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destroy@1.2.0: {} + + detect-libc@2.1.2: {} + + detect-node@2.1.0: {} + + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dns-packet@5.6.1: + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.4.0: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.334: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojilib@2.4.0: {} + + emojis-list@3.0.0: {} + + emoticon@4.1.0: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.2 + + entities@2.2.0: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.0.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.16.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + escalade@3.2.0: {} + + escape-goat@4.0.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esprima@4.0.1: {} + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + eta@2.2.0: {} + + etag@1.8.1: {} + + eval@0.1.8: + dependencies: + '@types/node': 25.6.0 + require-like: 0.1.2 + + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-uri@3.1.0: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fault@2.0.1: + dependencies: + format: 0.2.2 + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + feed@4.2.2: + dependencies: + xml-js: 1.6.11 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-loader@6.2.0(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.1(@swc/core@1.15.24) + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@4.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + flat@5.0.2: {} + + follow-redirects@1.15.11: {} + + form-data-encoder@2.1.4: {} + + format@0.2.2: {} + + forwarded@0.2.0: {} + + fraction.js@5.3.4: {} + + fresh@0.5.2: {} + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-own-enumerable-property-symbols@3.0.2: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + github-slugger@1.5.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob-to-regexp@0.4.1: {} + + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + + gopd@1.2.0: {} + + got@12.6.1: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + hachure-fill@0.5.2: {} + + handle-thing@2.0.1: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-yarn@3.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + he@1.2.0: {} + + history@4.10.1: + dependencies: + '@babel/runtime': 7.29.2 + loose-envify: 1.4.0 + resolve-pathname: 3.0.0 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + value-equal: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + + html-escaper@2.0.2: {} + + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.46.1 + + html-minifier-terser@7.2.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 10.0.1 + entities: 4.5.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.46.1 + + html-tags@3.3.1: {} + + html-void-elements@3.0.0: {} + + html-webpack-plugin@5.6.6(@rspack/core@1.7.11)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.18.1 + pretty-error: 4.0.0 + tapable: 2.3.2 + optionalDependencies: + '@rspack/core': 1.7.11 + webpack: 5.106.1(@swc/core@1.15.24) + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + + http-cache-semantics@4.2.0: {} + + http-deceiver@1.2.7: {} + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-middleware@2.0.9(@types/express@4.17.25): + dependencies: + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + human-signals@2.1.0: {} + + hyperdyperid@1.2.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@5.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + ignore@5.3.2: {} + + image-size@2.0.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-lazy@4.0.0: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + infima@0.2.0-alpha.45: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@2.0.0: {} + + inline-style-parser@0.2.7: {} + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.3.0: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@0.4.0: + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + + is-network-error@1.3.1: {} + + is-npm@6.1.0: {} + + is-number@7.0.0: {} + + is-obj@1.0.1: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@3.0.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-regexp@1.0.0: {} + + is-stream@2.0.1: {} + + is-typedarray@1.0.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + is-yarn-global@0.4.1: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 25.6.0 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.2 + + jest-worker@27.5.1: + dependencies: + '@types/node': 25.6.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 25.6.0 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jiti@1.21.7: {} + + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + katex@0.16.45: + dependencies: + commander: 8.3.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + khroma@2.1.0: {} + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + langium@4.2.2: + dependencies: + '@chevrotain/regexp-to-ast': 12.0.0 + chevrotain: 12.0.0 + chevrotain-allstar: 0.4.1(chevrotain@12.0.0) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + + launch-editor@2.13.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + leven@3.1.0: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + loader-runner@4.3.1: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash-es@4.18.1: {} + + lodash.debounce@4.0.8: {} + + lodash.memoize@4.1.2: {} + + lodash.uniq@4.5.0: {} + + lodash@4.18.1: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + + lowercase-keys@3.0.0: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + markdown-extensions@2.0.0: {} + + markdown-table@2.0.0: + dependencies: + repeat-string: 1.6.1 + + markdown-table@3.0.4: {} + + marked@16.4.2: {} + + math-intrinsics@1.1.0: {} + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + media-typer@0.3.0: {} + + memfs@4.57.1(tslib@2.8.1): + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + mermaid@11.14.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.0 + '@mermaid-js/parser': 1.1.0 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.33.2 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.2) + cytoscape-fcose: 2.2.0(cytoscape@3.33.2) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.20 + dompurify: 3.4.0 + katex: 0.16.45 + khroma: 2.1.0 + lodash-es: 4.18.1 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + + methods@1.1.2: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@1.1.0: {} + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@1.1.0: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.33.0: {} + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.18: + dependencies: + mime-db: 1.33.0 + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@3.1.0: {} + + mimic-response@4.0.0: {} + + mini-css-extract-plugin@2.10.2(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + schema-utils: 4.3.3 + tapable: 2.3.2 + webpack: 5.106.1(@swc/core@1.15.24) + + minimalistic-assert@1.0.1: {} + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + minimist@1.2.8: {} + + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + mrmime@2.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + + nanoid@3.3.11: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + + node-emoji@2.2.0: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-releases@2.0.37: {} + + normalize-path@3.0.0: {} + + normalize-url@8.1.1: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + null-loader@4.0.1(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.1(@swc/core@1.15.24) + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + obuf@1.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@10.2.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + opener@1.5.2: {} + + p-cancelable@3.0.0: {} + + p-finally@1.0.0: {} + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.3.1 + retry: 0.13.1 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.1.1 + registry-url: 6.0.1 + semver: 7.7.4 + + package-manager-detector@1.6.0: {} + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-numeric-range@1.3.0: {} + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + parseurl@1.3.3: {} + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + path-data-parser@0.1.0: {} + + path-exists@5.0.0: {} + + path-is-inside@1.0.2: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.13: {} + + path-to-regexp@1.9.0: + dependencies: + isarray: 0.0.1 + + path-to-regexp@3.3.0: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + pkg-dir@7.0.0: + dependencies: + find-up: 6.3.0 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkijs@3.4.0: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.7 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + postcss-attribute-case-insensitive@7.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-calc@9.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-clamp@4.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-color-functional-notation@7.0.12(postcss@8.5.9): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + postcss-color-hex-alpha@10.0.0(postcss@8.5.9): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-color-rebeccapurple@10.0.0(postcss@8.5.9): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-colormin@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-convert-values@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-custom-media@11.0.6(postcss@8.5.9): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.9 + + postcss-custom-properties@14.0.6(postcss@8.5.9): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-custom-selectors@8.0.5(postcss@8.5.9): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-dir-pseudo-class@9.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-discard-comments@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-duplicates@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-empty@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-overridden@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-unused@6.0.5(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-double-position-gradients@6.0.4(postcss@8.5.9): + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-focus-visible@10.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-focus-within@9.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-font-variant@5.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-gap-properties@6.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-image-set-function@7.0.0(postcss@8.5.9): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-lab-function@7.0.12(postcss@8.5.9): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + postcss-loader@7.3.4(postcss@8.5.9)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + cosmiconfig: 8.3.6(typescript@6.0.2) + jiti: 1.21.7 + postcss: 8.5.9 + semver: 7.7.4 + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - typescript + + postcss-logical@8.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-merge-idents@6.0.3(postcss@8.5.9): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-merge-longhand@6.0.5(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + stylehacks: 6.1.1(postcss@8.5.9) + + postcss-merge-rules@6.1.1(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@6.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@6.0.3(postcss@8.5.9): + dependencies: + colord: 2.9.3 + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-minify-params@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@6.0.4(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-modules-extract-imports@3.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.9): + dependencies: + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-modules-values@4.0.0(postcss@8.5.9): + dependencies: + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + + postcss-nesting@13.0.2(postcss@8.5.9): + dependencies: + '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.1) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-normalize-charset@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-normalize-display-values@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-opacity-percentage@3.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-ordered-values@6.0.2(postcss@8.5.9): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-overflow-shorthand@6.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-page-break@3.0.4(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-place@10.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-preset-env@10.6.1(postcss@8.5.9): + dependencies: + '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.9) + '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.9) + '@csstools/postcss-color-function': 4.0.12(postcss@8.5.9) + '@csstools/postcss-color-function-display-p3-linear': 1.0.1(postcss@8.5.9) + '@csstools/postcss-color-mix-function': 3.0.12(postcss@8.5.9) + '@csstools/postcss-color-mix-variadic-function-arguments': 1.0.2(postcss@8.5.9) + '@csstools/postcss-content-alt-text': 2.0.8(postcss@8.5.9) + '@csstools/postcss-contrast-color-function': 2.0.12(postcss@8.5.9) + '@csstools/postcss-exponential-functions': 2.0.9(postcss@8.5.9) + '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.9) + '@csstools/postcss-gamut-mapping': 2.0.11(postcss@8.5.9) + '@csstools/postcss-gradients-interpolation-method': 5.0.12(postcss@8.5.9) + '@csstools/postcss-hwb-function': 4.0.12(postcss@8.5.9) + '@csstools/postcss-ic-unit': 4.0.4(postcss@8.5.9) + '@csstools/postcss-initial': 2.0.1(postcss@8.5.9) + '@csstools/postcss-is-pseudo-class': 5.0.3(postcss@8.5.9) + '@csstools/postcss-light-dark-function': 2.0.11(postcss@8.5.9) + '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.9) + '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.9) + '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.9) + '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.9) + '@csstools/postcss-logical-viewport-units': 3.0.4(postcss@8.5.9) + '@csstools/postcss-media-minmax': 2.0.9(postcss@8.5.9) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.5(postcss@8.5.9) + '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.9) + '@csstools/postcss-normalize-display-values': 4.0.1(postcss@8.5.9) + '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.9) + '@csstools/postcss-position-area-property': 1.0.0(postcss@8.5.9) + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/postcss-property-rule-prelude-list': 1.0.0(postcss@8.5.9) + '@csstools/postcss-random-function': 2.0.1(postcss@8.5.9) + '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.9) + '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.9) + '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.9) + '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.9) + '@csstools/postcss-syntax-descriptor-syntax-production': 1.0.1(postcss@8.5.9) + '@csstools/postcss-system-ui-font-family': 1.0.0(postcss@8.5.9) + '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.9) + '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.9) + '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.9) + autoprefixer: 10.4.27(postcss@8.5.9) + browserslist: 4.28.2 + css-blank-pseudo: 7.0.1(postcss@8.5.9) + css-has-pseudo: 7.0.3(postcss@8.5.9) + css-prefers-color-scheme: 10.0.0(postcss@8.5.9) + cssdb: 8.8.0 + postcss: 8.5.9 + postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.9) + postcss-clamp: 4.1.0(postcss@8.5.9) + postcss-color-functional-notation: 7.0.12(postcss@8.5.9) + postcss-color-hex-alpha: 10.0.0(postcss@8.5.9) + postcss-color-rebeccapurple: 10.0.0(postcss@8.5.9) + postcss-custom-media: 11.0.6(postcss@8.5.9) + postcss-custom-properties: 14.0.6(postcss@8.5.9) + postcss-custom-selectors: 8.0.5(postcss@8.5.9) + postcss-dir-pseudo-class: 9.0.1(postcss@8.5.9) + postcss-double-position-gradients: 6.0.4(postcss@8.5.9) + postcss-focus-visible: 10.0.1(postcss@8.5.9) + postcss-focus-within: 9.0.1(postcss@8.5.9) + postcss-font-variant: 5.0.0(postcss@8.5.9) + postcss-gap-properties: 6.0.0(postcss@8.5.9) + postcss-image-set-function: 7.0.0(postcss@8.5.9) + postcss-lab-function: 7.0.12(postcss@8.5.9) + postcss-logical: 8.1.0(postcss@8.5.9) + postcss-nesting: 13.0.2(postcss@8.5.9) + postcss-opacity-percentage: 3.0.0(postcss@8.5.9) + postcss-overflow-shorthand: 6.0.0(postcss@8.5.9) + postcss-page-break: 3.0.4(postcss@8.5.9) + postcss-place: 10.0.0(postcss@8.5.9) + postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.9) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.9) + postcss-selector-not: 8.0.1(postcss@8.5.9) + + postcss-pseudo-class-any-link@10.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-reduce-idents@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.9 + + postcss-reduce-transforms@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-selector-not@8.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-sort-media-queries@5.2.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + sort-css-media-queries: 2.2.0 + + postcss-svgo@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + svgo: 3.3.3 + + postcss-unique-selectors@6.0.4(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + + postcss-zindex@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss@8.5.9: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + pretty-error@4.0.0: + dependencies: + lodash: 4.18.1 + renderkid: 3.0.0 + + pretty-time@1.1.0: {} + + prism-react-renderer@2.4.1(react@19.2.5): + dependencies: + '@types/prismjs': 1.26.6 + clsx: 2.1.1 + react: 19.2.5 + + prismjs@1.30.0: {} + + process-nextick-args@2.0.1: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@7.1.0: {} + + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + pupa@3.3.0: + dependencies: + escape-goat: 4.0.0 + + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.0: {} + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-dom@19.2.5(react@19.2.5): + dependencies: + react: 19.2.5 + scheduler: 0.27.0 + + react-fast-compare@3.2.2: {} + + react-is@16.13.1: {} + + react-json-view-lite@2.5.0(react@19.2.5): + dependencies: + react: 19.2.5 + + react-loadable-ssr-addon-v5-slorber@1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.5))(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@babel/runtime': 7.29.2 + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' + webpack: 5.106.1(@swc/core@1.15.24) + + react-router-config@5.1.1(react-router@5.3.4(react@19.2.5))(react@19.2.5): + dependencies: + '@babel/runtime': 7.29.2 + react: 19.2.5 + react-router: 5.3.4(react@19.2.5) + + react-router-dom@5.3.4(react@19.2.5): + dependencies: + '@babel/runtime': 7.29.2 + history: 4.10.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 19.2.5 + react-router: 5.3.4(react@19.2.5) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react-router@5.3.4(react@19.2.5): + dependencies: + '@babel/runtime': 7.29.2 + history: 4.10.1 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + path-to-regexp: 1.9.0 + prop-types: 15.8.1 + react: 19.2.5 + react-is: 16.13.1 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react@19.2.5: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + reflect-metadata@0.2.2: {} + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + registry-auth-token@5.1.1: + dependencies: + '@pnpm/npm-conf': 3.0.2 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + regjsgen@0.8.0: {} + + regjsparser@0.13.1: + dependencies: + jsesc: 3.1.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + relateurl@0.2.7: {} + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-emoji@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + emoticon: 4.1.0 + mdast-util-find-and-replace: 3.0.2 + node-emoji: 2.2.0 + unified: 11.0.5 + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.18.1 + strip-ansi: 6.0.1 + + repeat-string@1.6.1: {} + + require-from-string@2.0.2: {} + + require-like@0.1.2: {} + + requires-port@1.0.0: {} + + resolve-alpn@1.2.1: {} + + resolve-from@4.0.0: {} + + resolve-pathname@3.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + + retry@0.13.1: {} + + reusify@1.1.0: {} + + robust-predicates@3.0.3: {} + + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + rtlcss@4.3.0: + dependencies: + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.5.9 + strip-json-comments: 3.1.1 + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rw@1.3.3: {} + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + sax@1.6.0: {} + + scheduler@0.27.0: {} + + schema-dts@1.1.5: {} + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) + + search-insights@2.17.3: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + select-hose@2.0.0: {} + + selfsigned@5.5.0: + dependencies: + '@peculiar/x509': 1.14.3 + pkijs: 3.4.0 + + semver-diff@4.0.0: + dependencies: + semver: 7.7.4 + + semver@6.3.1: {} + + semver@7.7.4: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-handler@6.1.7: + dependencies: + bytes: 3.0.0 + content-disposition: 0.5.2 + mime-types: 2.1.18 + minimatch: 3.1.5 + path-is-inside: 1.0.2 + path-to-regexp: 3.3.0 + range-parser: 1.2.0 + + serve-index@1.9.2: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.8.1 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + sitemap@7.1.3: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.6.0 + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@3.0.0: {} + + slash@4.0.0: {} + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + + sort-css-media-queries@2.2.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + + sprintf-js@1.0.3: {} + + srcset@4.0.0: {} + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + style-mod@4.1.3: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + stylehacks@6.1.1(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + stylis@4.3.6: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-parser@2.0.4: {} + + svgo@3.3.3: + dependencies: + commander: 7.2.0 + css-select: 5.2.2 + css-tree: 2.3.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.0 + + swc-loader@0.2.7(@swc/core@1.15.24)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@swc/core': 1.15.24 + '@swc/counter': 0.1.3 + webpack: 5.106.1(@swc/core@1.15.24) + + tapable@2.3.2: {} + + terser-webpack-plugin@5.4.0(@swc/core@1.15.24)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.46.1 + webpack: 5.106.1(@swc/core@1.15.24) + optionalDependencies: + '@swc/core': 1.15.24 + + terser@5.46.1: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + thingies@2.6.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + thunky@1.1.0: {} + + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + + tinyexec@1.1.1: {} + + tinypool@1.1.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + totalist@3.0.1: {} + + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-dedent@2.2.0: {} + + ts-loader@9.5.7(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.20.1 + micromatch: 4.0.8 + semver: 7.7.4 + source-map: 0.7.6 + typescript: 6.0.2 + webpack: 5.106.1(@swc/core@1.15.24) + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + + type-fest@0.21.3: {} + + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typescript@6.0.2: {} + + ufo@1.6.3: {} + + undici-types@7.19.2: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-emoji-modifier-base@1.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-notifier@6.0.2: + dependencies: + boxen: 7.1.1 + chalk: 5.6.2 + configstore: 6.0.0 + has-yarn: 3.0.0 + import-lazy: 4.0.0 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + is-npm: 6.1.0 + is-yarn-global: 0.4.1 + latest-version: 7.0.0 + pupa: 3.3.0 + semver: 7.7.4 + semver-diff: 4.0.0 + xdg-basedir: 5.1.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.1(@swc/core@1.15.24)))(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + loader-utils: 2.0.4 + mime-types: 2.1.35 + schema-utils: 3.3.0 + webpack: 5.106.1(@swc/core@1.15.24) + optionalDependencies: + file-loader: 6.2.0(webpack@5.106.1(@swc/core@1.15.24)) + + util-deprecate@1.0.2: {} + + utila@0.4.0: {} + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + + uuid@11.1.0: {} + + uuid@8.3.2: {} + + value-equal@1.0.1: {} + + vary@1.1.2: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.1.0: {} + + w3c-keyname@2.2.8: {} + + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + web-namespaces@2.0.1: {} + + webpack-bundle-analyzer@4.10.2: + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.16.0 + acorn-walk: 8.3.5 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + colorette: 2.0.20 + memfs: 4.57.1(tslib@2.8.1) + mime-types: 3.0.2 + on-finished: 2.4.1 + range-parser: 1.2.1 + schema-utils: 4.3.3 + optionalDependencies: + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - tslib + + webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.8 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + express: 4.22.1 + graceful-fs: 4.2.11 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.3.0 + launch-editor: 2.13.2 + open: 10.2.0 + p-retry: 6.2.1 + schema-utils: 4.3.3 + selfsigned: 5.5.0 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24)) + ws: 8.20.0 + optionalDependencies: + webpack: 5.106.1(@swc/core@1.15.24) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - tslib + - utf-8-validate + + webpack-merge@5.10.0: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.3.4: {} + + webpack@5.106.1(@swc/core@1.15.24): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.20.1 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.2 + terser-webpack-plugin: 5.4.0(@swc/core@1.15.24)(webpack@5.106.1(@swc/core@1.15.24)) + watchpack: 2.5.1 + webpack-sources: 3.3.4 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + webpackbar@6.0.1(webpack@5.106.1(@swc/core@1.15.24)): + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + consola: 3.4.2 + figures: 3.2.0 + markdown-table: 2.0.0 + pretty-time: 1.1.0 + std-env: 3.10.0 + webpack: 5.106.1(@swc/core@1.15.24) + wrap-ansi: 7.0.0 + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + widest-line@4.0.1: + dependencies: + string-width: 5.1.2 + + wildcard@2.0.1: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + ws@7.5.10: {} + + ws@8.20.0: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + + xdg-basedir@5.1.0: {} + + xml-js@1.6.11: + dependencies: + sax: 1.6.0 + + yallist@3.1.1: {} + + yocto-queue@1.2.2: {} + + zwitch@2.0.4: {} diff --git a/docs/sidebars.ts b/docs/sidebars.ts new file mode 100644 index 0000000..d8c116c --- /dev/null +++ b/docs/sidebars.ts @@ -0,0 +1,29 @@ +import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; + +const sidebars: SidebarsConfig = { + docsSidebar: [ + 'index', + { + type: 'category', + label: 'Online Tools', + items: ['tools/pict-online'], + }, + { + type: 'category', + label: 'Advanced', + items: ['advanced/index', 'advanced/options', 'advanced/pict', 'constraint-logic'], + }, + { + type: 'category', + label: 'Development', + items: ['development/typescript', 'development/python'], + }, + { + type: 'category', + label: 'History', + items: ['history/index', 'history/v3', 'history/v2', 'history/v1', 'history/migration'], + }, + ], +}; + +export default sidebars; diff --git a/docs/src/components/HomepageFeatures/index.tsx b/docs/src/components/HomepageFeatures/index.tsx new file mode 100644 index 0000000..c2551fb --- /dev/null +++ b/docs/src/components/HomepageFeatures/index.tsx @@ -0,0 +1,71 @@ +import type {ReactNode} from 'react'; +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +type FeatureItem = { + title: string; + Svg: React.ComponentType>; + description: ReactNode; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Easy to Use', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + description: ( + <> + Docusaurus was designed from the ground up to be easily installed and + used to get your website up and running quickly. + + ), + }, + { + title: 'Focus on What Matters', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + description: ( + <> + Docusaurus lets you focus on your docs, and we'll do the chores. Go + ahead and move your docs into the docs directory. + + ), + }, + { + title: 'Powered by React', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + description: ( + <> + Extend or customize your website layout by reusing React. Docusaurus can + be extended while reusing the same header and footer. + + ), + }, +]; + +function Feature({title, Svg, description}: FeatureItem) { + return ( +
+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures(): ReactNode { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/docs/src/components/HomepageFeatures/styles.module.css b/docs/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 0000000..b248eb2 --- /dev/null +++ b/docs/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css new file mode 100644 index 0000000..a04c0c1 --- /dev/null +++ b/docs/src/css/custom.css @@ -0,0 +1,145 @@ +:root { + --ifm-color-primary: #6366f1; + --ifm-color-primary-dark: #4f46e5; + --ifm-color-primary-darker: #4338ca; + --ifm-color-primary-darkest: #3730a3; + --ifm-color-primary-light: #818cf8; + --ifm-color-primary-lighter: #a5b4fc; + --ifm-color-primary-lightest: #c7d2fe; + --ifm-code-font-size: 95%; + --ifm-font-family-base: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +[data-theme='dark'] { + --ifm-color-primary: #818cf8; + --ifm-color-primary-dark: #6366f1; + --ifm-color-primary-darker: #4f46e5; + --ifm-color-primary-darkest: #4338ca; + --ifm-color-primary-light: #a5b4fc; + --ifm-color-primary-lighter: #c7d2fe; + --ifm-color-primary-lightest: #e0e7ff; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} + +/* Hero section styling */ +.hero--primary { + background: linear-gradient(135deg, #6366f1, #8b5cf6, #a855f7); +} + +[data-theme='dark'] .hero--primary { + background: linear-gradient(135deg, #312e81, #4c1d95, #581c87); +} + +/* Admonition custom styling */ +.admonition { + border-radius: 8px; +} + +/* Code block enhancements */ +.prism-code { + border-radius: 8px; +} + +/* Feature cards */ +.feature-card { + padding: 1.5rem; + border-radius: 12px; + border: 1px solid var(--ifm-color-emphasis-200); + transition: transform 0.2s, box-shadow 0.2s; +} + +.feature-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +[data-theme='dark'] .feature-card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +/* Badge container */ +.badges { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 1rem 0; +} + +.badges a { + display: inline-block; +} + +/* Option table enhancements */ +.option-table { + margin: 1.5rem 0; +} + +.option-table th { + background: var(--ifm-color-emphasis-100); +} + +[data-theme='dark'] .option-table th { + background: var(--ifm-color-emphasis-200); +} + +/* Interactive demo styling */ +.demo-wrapper { + display: flex; + gap: 1rem; + flex-wrap: wrap; +} + +.demo-wrapper > div { + flex: 1; + min-width: 280px; +} + +.demo-table { + border-collapse: collapse; + width: 100%; + font-size: 0.85rem; +} + +.demo-table th, +.demo-table td { + padding: 6px 10px; + border: 1px solid var(--ifm-color-emphasis-300); +} + +.demo-table th { + background: var(--ifm-color-primary); + color: white; +} + +.demo-textarea { + width: 100%; + min-height: 80px; + padding: 10px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 6px; + font-family: var(--ifm-font-family-monospace); + font-size: 0.85rem; + background: var(--ifm-background-color); + color: var(--ifm-font-color-base); + resize: vertical; +} + +.demo-textarea:focus { + outline: none; + border-color: var(--ifm-color-primary); + box-shadow: 0 0 0 2px var(--ifm-color-primary-lightest); +} + +.demo-error { + margin-top: 0.5rem; + padding: 0.5rem; + border-radius: 4px; + font-size: 0.8rem; + background: var(--ifm-color-danger-contrast-background); + color: var(--ifm-color-danger-dark); +} + +[data-theme='dark'] .demo-error { + color: var(--ifm-color-danger-light); +} diff --git a/docs/src/pages/index.module.css b/docs/src/pages/index.module.css new file mode 100644 index 0000000..9f71a5d --- /dev/null +++ b/docs/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/docs/src/pages/markdown-page.mdx b/docs/src/pages/markdown-page.mdx new file mode 100644 index 0000000..9756c5b --- /dev/null +++ b/docs/src/pages/markdown-page.mdx @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/docs/static/.nojekyll b/docs/static/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/static/img/covertable-social-card.png b/docs/static/img/covertable-social-card.png new file mode 100644 index 0000000000000000000000000000000000000000..32041376347767b0fae54c0d866b0f11dc36abea GIT binary patch literal 19132 zcmbWf2RN4f|2KY#N)kd=k;-hyh{(>~85JQTD`f9ILRKUzWhPQdp^#N%%P6Z-vMJeR z^Ss>O-!p#y|L-}T@AI6;(cOLMa$V>78SnRNeXj5e>I(bFn8*kO!agNMSuFyAXc2#u zNq68UW-jOY@Yfy(MLlN%L9lE457AZgQBnedm7pXmt>f|F_cu=iwaG2Qth4LaS9v*d zk7eSyrn4YJa27Nv^%yx9!BeG9V-u_+LF)gw^%yN>|UGIm5+ELkQpx z_^)2`KcBuUfBd%H!q|t?Mpd>O3E#@y7d$HZ`ue87m5Yjq)YaGjo%-zj{?`8dYga41 z64KKLay8QJzP&j@IzRb|b8&f#l}+O0$*Glv@%-A?_5*fycIxj2?>Y*9tfz5WCQWUV z($o7~<~&|eS;>6p(Cqsb|6LQ#Qw2uV>Z+==yBB};+Ry%YXLh)p#8*A2c#b5EBuKNu zK;4^P0=1;?6|3=T{Wy-KAj|X8f zWeyC!ZEy4SOQ=Xbzr40P(2}q*JLx>75W|u%BH})6aQ-&)!tA6Qb#`=vC$;SI@gso~ zPNTP3Z{4}0iR)JZ=8Top)MEPzWmOz+ORY1~P*hwVO)@&?GBNwBpqhe#mz9riu6(9S zhU$GyP1c9yzr~C*zkaQ)ELf6A$KAdA^vM(XD2B}3+%VQ#Wo4c!DlH{*7~RA(rEb5! zoYH?C>$|MQO!0Y6mRTaJ-!g!sLBe@V)yQaIXlQ72V{JH`bGAIDV~kDlpvIIED^+yF zS_xb3$F43~X{shp=D7rW2Z!0`hUHWw_XI2{yef2ltMI(U)1}77I!yKPHI=NlB%RiJ zb(*uac0Vb}P=bzQy~@|B2Xph<%lpG+k7i!r5^2&&BWkT$_K`?xsXH8#>&ug5V{6;r z-+xj@!tCv*yyfGsWWp%;*_8e&T{?MX;DR7Ozt-i;^y$hJVaFsA{`~o)r>7Sh8hTL3 z_ASln8*3!>EqRsG$|@?ks`ozTX>;z|x6jgYe0kZUhH`v|&jHcQjrc9Szu z?caYyW^LZ4sDbZVJvsBa;;O2v)NYFtnwKy4t}V^bc?Cfm4A`ARmOLuodo8&sb zO~I$L_TSCS%u374-6uNUwY2=|$=Anjh&!TGs8MLzx!PQ*R#sL<8nig|S-Ufws~$@O z+gcF2tGB?2lan+3oGY1h?4Mt~G~IsY=A%=ei^>e_yu7@y+sw?^G*8itZf(wN2_I@p z6Zd{!ZRo$X;qK@-_dvvX@z0;|-&Px|e`dZ{(ipvBXJ_C4wbVA{{(YJA=exSP`1$#H z3`$uyW!X0wFPyiwwsxQSuBNWe@mjCvf!P(KvJxe+9XwUzc{kG}d?Q#JZ|8xpo9feCmlF%Fo?0GEqG`L!x}cPEa4fp)7^&0GF5E;ket&&sJe{7$K)1rf@z=M} zuZusspB|A3jl#kY4Q|xhuR&SrF_%?PFjL{Vz@d?bk@9##AX^VR%@QK)w_ci_ZZuHk ztD>w-MdGp0#ILEjL>m)X>lvczxq5`o^frJ)YTglF#b= z`}hh=DVfepwB8dK8yh=#*6snnd2^NTnv;`L$3WJ@hYxddLRlL>+&}C1H!CNne$e4c zyVE0LV&dSNH%Sg2yuZA>TpLE&+uLjZxe(RePuib;vvz5AR`<27p0l&Ffx&~!OcQx| zR62Qcb9R&6QnBfNt4d;%9;3|(9z%2KM2@;nPV+fx_X~@PP~QE1e|gp8ozK-XSQ}>9 z_TV1ola|)y$6KOf$Bs3TYI$dG3}V%fItXi|OBfbes3|Iv5-HKB85%OL47ihV=BWpf zbKVP`xL7v3@XyuK-cDa|Dp+L1+Rn~z?eFh*!MpXZTp5}gLZO(qP`Zs3GCn>I6mgZ6 z%4NEru|1|#C+u|E?$Gs_@2=ObJ?!VEiD?<7qo*H^Y4G2*i<0Feb@q7;~rcxrZ>;B6qLRJ!FFVU({l$8I_{l|@2>GZd>wCHQ> z^50x9d-Y0iRo`n7`&5BaESmnnfm3>gvTAC-u{RS>wAe>63XHX-iVpS8Po;DI9#nDN ztNEq2!G}UW=y9!r*(%XnjV}Tj`T5_@G1A_AKy*FEP)3Hh-8i0M!+*KX>JM?i4~eGt zX(T&3ACY|%`|ngqq(x&>d;5%J(XMir$)h)pDf=zo za!MyMmvGx7yyyKxV@Ljo@`t$-6IM-1SkEuBK4mhcxf1D-QyAT&GzuD0RxFs4rL*x> zxZOT};@^Q&|9>!<<+T!+D(XJ(Ar>L}h8>+2iZ#{6C7-b;4(3lc~U`Q0xd z$`ju5bEd1OC&K90 z#6+=QxhaiInDgo5s_ByciBsWLH*TEj<}kf6qbyhU?2K70-%$y_b&m+|?C^>Tu_hZs zL&FF9)rGr~T5fDyk&%%JY$9Zk>pGc}5C|E9{~3&HXaD(79~!!Ar^OD!g=YtDu2HJ{P{DC z@-V6>@A2dK5K&Rl)29pOh8w)Sy#d?e?w%$P8Y4&RHh%RM?BBn?A?EPu71`c6jW$2I_;h|@fqMdLPrG9;fuI<2gwySt*t4@$!#MbR1fVORp7cLQ5!Hu`l3j07nj9C^A?9)U;FyRe3oZX zJqmBcXFhpy4!y~Fye%OyF*Gdf;K73}9oQxpg5TAN3kn|CB9_I!0rWY!x+YW`iHlc` zwj`nA+!(0(*4U`HxeFZ6LG{$MtE;PkMJp94iARw8RG;JW?BH!?QR?IXH16hv6Oj=S zW3BgOjEe{aDbk$p7Ytw9GPdc(+_`fnlJ3+|?r6N$%flnKOBmB1b?5T*<>ve6 z%M^$=*#ujU{`6JbjeaTuf$Ko%fh8b6>}S)^e7z$1*G*F>0~D&qryo6fgnLOgxpe8$ ziA&EiSP$nF`!Ufa9wrcCqm}A>!9qNmhfq>c4Y(R{M^=%1b*T-*sltvs1X{m+^R2nL zXCxPsR9v4tl$M-)%QCJNZNem!oIv2sDQ$TF-nd>@PcQngWLl6JgEALwgzQl{OCnl% zF52Vgc3zCXzP`R#PGJ`%UXV0F|rV6q~NwIpY%$s8faH*@SV~OIz zM4>yqdE?b^n;8%Xixk(lZ{Nhl#S zsg8~pDoH$sS*-{I_qVtmiXxS65fT zh_?Rp8UdW#~kch0hALbS&=f z2c@c$xCFSPqM{x=c;FyZH@;y1yw|G#uoIgfBc3h67==9N&B)?1@5jZ(8ToI#0yb5+edzj(wc&B#`KxHd z`T4&w2;2w#M;wHK@T6nP+-I)3xd{ob6kp%k-0+d8uJrHz_))8Is9lT&rMJ1h-U2`b z)jc6M4>y5%a+~?Sf#P7)cA_!<{{1`VkVuf0i`fEh!gFEF)61*MZzH8I@vDG&Gi~eBCzakyT6bGZ zn3$L-Sj28o^V;-0L&4WfjL}tARtB5c2FEDuI`^@T1uWYZ7Z%o5|D4dgar}ab$zbde znX&ftEyyQw?aEWx>%T>Z*Fhre7J!% zja{kR7PBLQojUyXVae%{k@%F9Cldy=!9;b;3zrTCu|8CY$zi4OEWTQ&+P3$1iT%Kv z@^YgpAHC`97nt~+yLLS{D5DE^g*ihUm zInSQ8e)=SE@K%4+=Q`d451)Y%Di#e4SbOyA4l@%D5{pXCc$S~Y25I^4;2+#2rrmW{71Kjo;I zWve~ATyRy1+6~?J?{6^{d%zyy>Rh~Uh0COtwl+;#B7XOU--Z|J`h)0nF;A`4he@V6 z3w4q7e9j)rvzg=~jk`9Qgk@xEf%;nIN7BdJ#uuu$HoYGV90TWn_UvSi=YwcjJbdGzVFHTwI~=np^7& z+>)i4neF!qz0lDquozF&6yR(Vc_AU8wg)128-|s>?o>D6amSXL-~(`2pB*Gt+EYw- z;6RAeR$|Mjsrmrh``=$npi0CrTG-pCr=>|)v@+x|0VS&`D>Lz%k$UN()w;M8>zvY_ z#G_7J?uX99sgc&&+?*opm=$;OP)q30^I3KU#qR!oF|>|W-eboef;|h1injD?qM%;N zzY>yLC5fd2+`;dD^E#yBiM0VTk{x7Y=g$ZVW-fte$KzSceX$MOeOdbnrs$i>IWM2_^SjU7Xw&(8$k@vsw8*2E2eAG{IM2 zUw`i0xvr6iRD*+q6AQCcB%R&ecp`A?yVd0vpI+KPV^21L=Eyp;haMar3K@!rgb#x= zQ^EttR*_X9gt2~>^Hbl->7Dsad!HK)4-GloPAgH;*B9mB*yTI-ASfuve{)4)jHj{4 z>yLH(z#YgUkctjEKa26TGVGrd3wS%-^0&EJS&Wz;#bKhi;IL+@9Tv{duDl68$jgdEjsHB?4d~oTXKsWORp>Hmu79Nfi)lST^+n6%<^%ZY(|J`3!R2ibgzP_=c5XErB z+hX8{gD`+deFb?`c=$U3D~|h+^`Z}nP>Wk&=^XvoQ=+V{F7K}um9jetT4O+A;|pCY zD=U1!p2==;sWh*Y1-a&4=EH zv$>wqymTqllM=dB+FrVotWOk}nNy)ZW|7Q#Q~NWDeQ{vXpc;{Frr|_}t58F%ec&7L?(8`V?C+@2u1T1+Ni zTVXB0%lmfyVmu?X?sY}|%a`4!`$giYCpt2T#~RllaggoZyJv=J!+w{bO37Z59gA|I z`$-&8?c9craVRJ#V1dU6#K+T`db9OIcCM|dp-l}L>U>jrVj;oX!~_7J$*Z;a`lne* zz2m{aY{s`M9!d@$%f$%%oSe*rkCBDR-v9Nwr>DrO-4qcK5v{EP{o%tgB1#rmS~oR5 zk2wfWoQ;T#jGU~9*Tt+tl!>=)zUFP^OE%ljbM4mxsfWA}@s1seAEZ@Oe&we7osWS` zcw~k`9|)SS;7$y)XsBn4=5g%Y^G2MJDUZJLNm5TvOc?vQn+2CCOaKHlPF(f_sPW(U zLoe7){^@Xjq-fg4+1Yk66S~$tb#88M@MX+$14RZNw2u!P`3I_B1a~#Bqp3 z^V_T9;*5e=L3lK+qD1q<3oGca6MUPSn{2+euU@{CrhMx&dtMWg(IfK6J3nN94c#8M zOiGBHTksHTJ*Dj9>&v~|H8eeayUhDgUfs8kADuuDC-}g4WW_~1r~Av$fF6=u5Fq9U z;d72TB`GNx=hbk?#k!J=#WxC~EI4#TTadg}<;dx@p|<7|Oa1)@tp|!n^{x{nDZ)M# z7)dV9Z!FJU({k1=G*dD#IHde`d*xA6k5s?9welmbvQm8W5#wm!N}1ZliwPC`tT&6K z7E7#j`~NI10_iC>j^4h1|6ubO1F|%OV`ST-W5RgpYS}P%QWvc|i8OEI8dkT57|TnV z`6~y{xje?U2541oMbjERJq=m`etLdShV7(VDM)=o~Y~zvaysmU%q^K{rYtmTX5M6X=i7FyxqS``M z_Tq=DGc$?A85Wu!qt3*u{jFKpKM3~^1a)K-T%>EjZ*8A1V*$9c=OqblE-si-Ov(gv zm6D|Rc;l;uK%Eg4H+1;INaT)c%E^VSKmAN~UQTWlM2mN6P9G%$63T$@lA)d+qp~W5 z7-)AbEao)^&nj$spLdxB6%_y|X*qXvbR{qxbZ`aedk<(9wDMNhZdKM0$40 z@2ak@V*MxmWl*q>*`<(V4mrOx9hF^@bWbiSq#84*7!K3xAJyx>cm&uSu1nWdQdTrb8`fv#v#>Vo`wJt8Fr#<8oL5pOhIdp2)b#8mM zL`q>)i$uvTk)06`xX*7+=GBS{Y<6(3gwqJA*Q+dxNw=3je_A)M#zFWk%F-qhl>?c%cr9Ln8zli!2vkrSOeJw3gSYX-RQ0)t|@W#(ZxmTUbelMn^*!o&Ws2*xK-ufyDR3p_^Z} zwXmCd{ncyJqSkTJv!{ru0Gh^y2xCrhI&A^*Z!3J&=F;8XULfb1#tyAHBF|0v4+97_-&Y?Ld4hq3qC(AXa!d$tp8hr#S;y z8_~Wx?P;~eh_!Ysn5?4e2@FYdX6WLUNQ0sdo}~~NgXNNZ`MqkOr?c?s(=jP|@K3}% z=Sc)YSIa*q)6c-T;wpc)ha~9MEzgY`fubfK!xFu+$lv^+5lr&oX(iduAAb)F zISAuZJT`}Ru;ZQVEG+)QWgGs%1=o?l&zhj?c?H4D=UgDK^LeR4 z{PAwNXv*_#`{O^~y?by>nC-(1FVQ(;c}E2*Hda=G0EeXH*6N>MBje}az|J#P|0M6f z7|I1)1yxZdMzgE_8oDD;AQ#b&z#p)H2K=B2ZNT^7vVVY5l5khFdi2+?NEU}*J*S%M zM+q`~Ii+i>t3&r3qc*ujv>k*GwQ3v(`JokCjIq4Uokn@ltfRYoA33>fj0p6`5_i*% z(_ixp-c*Vwuf?4e5;C1GB8xwCEutL4LUpyIMIY3BL?Gm(CCm^T!-w!DjY|eR^v(y{v7xl@ zk{ff?Z+8y>lR!(8%^yFESz;8VC9;|LOi9MxnO?dok`NycH!QPZTO$~Hbot7!@0Frs zr1kz|veREnG+3!J-k-4EHR7+Da%PYCkH5daV!`BcFus+AV2CB?@%r6|rlvcVr`1wA zdV3oTqIe}FSbQnZi=;~UGF4I>C7o|MT^*Z5U`cj9>g?pic6bbxl;W^N6t$SgtTAd* zP2AnuWWH-q>pHFp+4U=`@dtz_>-6s@*|TTQyP_|@u?taGxEsTClKq>OeKynmH(vS>IMZJy zqjWC7li^bThYufugMxT#p}hQ@nThf2R$@mxb# zj895>*wA|atj1t@n=>XjatXE_oKUD*RZI>*`S3HOtlXUTV3yMxfI^FIQa=T zqq#%&s3z=oA0HoSX(DBYKPn{;KXrHi(|=mQ$CFMQsjEo@=p|q7hl05@^*NZ+364Df z)MKR+AkDu%7jb&Eg4XagXk=@Fer%Jh5BYv;zt6V*Qnt3Twr;zBmQsAI@8vb53*`26 z^z=Y$5z6%3&&tL|vJf5yz?drTotWaY?Bl1ZN-mnlVIn?u0842HF|p&cj}R0^dC8XC ztgL^r%Gg+{#hny$aQ2ua{d@pSypkV1Vprq&TDNU7`*j-X>)(gAPMr}8XgK-vCmeNR zfs?GPKOpsHTR_{SW@i2dfCFXwZ`#_<;+n=GBqoq|Knf<5@pD(#8M}Vr#eIw;M`+2K zu4XubQ6v`)QIV`bQf*Ha<+L<{E-*jR1bwMK3Tuls-!1r8f0;m9(ajwT(~q)Rllh39 z^&MDZ;8%u8_#0VZ3GAk1fnJFX$8-O0k(szW9iEPS-#*8-c{=)MC~l@nsnEN?tYPM! z-+G~O3qNZ$`~V>jUe!n1`$&ePM=%xolph!}EtO-&7C?vu{i zQh^Kx*n4`=wIdFkaM*>^hUmF-a6}&3cLp3idv*yzaY=u>E`98 zJ5W_wRmC!XEDytCSmrdEcuF6<8VfT&Kc8;^F{OAE$GEt8-0cas{lB43!JEHY<-;ft z*D(AqJ4#PiR}}^tly)$We-VEOzc6Y5Q!zB)7ISlR%aV0ZA3uH|;rr#?JL#%n)=oq# zP)U#cPRQAjWS7(o$7X(h-mbqi5Jd6VF;-SYgKog}K@tdQm7jGO7koas#mHUVYPUW zcOptkn#i|chkT3_dCBk9F9_sLWfL(77g*@`(*$oMNm0B zA2L2ANH3@ecIoQqxGc|_EY`_4vMwA8K^=#{=jZ3Q>|ePjGb_t!q;bDI?K?>Bt|&j) zUBbf$s$9x-pw%G#CwBcKTk>@ZUOw+uLm+wc;reLY8AS4kwnv6=W`^i}B#hGJhlYpq z9$b5#o12uJ{CIX}jRU`sQ2my|Eee$q6%`qoV?si73r!cbl>Fj|QeS45Mn*I69TgS* zicQcN9vj&*Iz3Rm1rL$7^^Cidld_uHwqVmVeM@TD{^>`PNjFBw+lPf6Sn)Q_K__1# zIfXTYwI_z`+wrxXg(erV3A17Kp^Ds&iaH}CbjgKhWECX_Ubp)9tSCt4&|j1_G-kS= z(kmIpWU}Tf*+<9ki@*;9-y}e7=WfM;u z1eNQSv|3i?MSNDbSJDAdN7edOu@TMYSW;*TiZldLH4r& zoU!iWYAXCVKk@NV%TQe;MBr+l6(`u35T2<&p3Go4Xwi}Z33s5x-Uv26Zpzful$wTS z)PT7c?CaAfXRvHc_Ct^NG;&x`i0lALj$qhQCH*%6Cty&@3?yU;>g(&n1V?_#1eF?V zD?3MdyB|NgvNNQ15UbP?G7p4Oh=Jt}gEi=D@Ms;YKnl8H6E;El{Os8ndjzUuamw=6 z{HTgt?pwu^r>9M!I1GKctfdu~oSck-OH4%F77#1CBz)-ht5>ejs4D+))lmd#tHgJb zIXf>vTLm)IVWonLHV@xn=gytb^s#%fhjAJ3T*kfX>wj%*d<<_1%o*U?Bhi>R${0_M z_c?T^b$kI13BQ1VQH6&l@)!`caOvwmefaR2v2jL0fxYoR7y1B%eS7=%+mb&s1Rrrt zQzQ5Q_=yXNB_SaTbMs2ywb%cI5wP;MjTmXFf4v#xE!&cf*O7z*BG=E`BMr zu@Nn!z^}NDpWC0o+kCNK{}VJcclQPZ)dK`V@~x_4Fk}g4yXsQUp_UBM?+6TdD_259 z_@RHHKTqcAha@7x)UJO&&Ya~n_6Io)uIW1x7;Cly*eeOvU)E4Yzxw2}{h0mgvrn<^ zjaz`h%nlkt);~DMSKV|by#lpS*C_7mRT&he}!xM_UkJ%KcR(YPPlM&uf}*;Sv}qk z+8nClKU_spmp~P2PWX2d*j&?HogY8ORoGSDVjvKxDE^6a$5Q8?+sh!!Mav@WKwy7c zSGV0X;zwofVU=RL-|d`7pF-nlvSRF@p>>y1IG^bNgw92Dn{+Lm=FE_X5-Q zpR?t>QmV}Gt($Cg{RqWPjg4H$$cCP!qobStTog9zLvThyJwP7mN%~V)*lG`IYiVVa z2KN~2?)slm_1~f9i;Ii9C=Mwa2P49GK9h<)1N9H@A?s>sYpbfG4R$T?<$(LyvnA;8 zI}UdB_JTj1P<{)Wx~ITM!#HMpMtM)d_y4a$@DUi%tO;5I!FGGaq14CqqSOc8!#z;` zALH`M`+PM;-ZCjKN9TO2F$vH)dgn0=#qJsaTr+4OQW|ozSfUH6A zho=b<^Tdf0$kV_e`qbMCk;2*05iyg(r%z9W)oQxrNXdiYA;vsvI!n+0Bi*#Z;BprNF3xYX1oZgxT08lv$U;yoBg4bXV0vvE0eon(xKJh0U}dSyKtxD`O5eOea9uU^ zT=(0z0Ux89cGsnbAa@LpbzAQo88Hi#3Sc}<9sVy20ZKNzl$D=vc=1_EsM&zND{z5Sb)q=8eC<^%=ioOX8|Bt&2d_e6IU4 zNR6GPzCRD4M-ERzBO?uYdIXjB((`OfUgun`wX~?yn%hic4om(8x|*ANXY`pJBMtZ_ zWc)UuwN;hhiFkf^&I1{Em{E}O67maGFq|;NUcrn6`k@Y&C1HPTyj`h&3L2x~0Z8Lt zm=7GdXlST*RUxXQudfv2Lr2KbHH6aLA%f8Zs zq=e27rFZeSZ}N@^(cy5}EUbQ{o===S8Pzb%eU7=VrL}dcw_pG&>z?cRWo0V}`ir?u zF&xP!TGW8KnY<%zOr}^9S^j z<2=9j=$-8#G=`LIvUjs&z)#e7^$g=F;s?#m&4`RcZRVPInw@P15Q@}UZpP_2DM!mE zXmQ8^|8v44ydy}8m6VL^%L^0Yyh@~2#}P`%b|dG}4-WDHM`IZNqMH6G zV)BuYgzy4O09)|!W748LI6J3cJcGd$<~|p`(0?yCI~#mS;YqWdm6fnb4GDZ)$TV

FfUV_H<##qslGN<(KvM?%S78fs#Tiz~cM`XFzTV&m+u`oc;2AY73x1qBPYGfM(GZ};`}DN#{x)FSNEkAEL! zWqtHAlJfHU^E08kx|-DW%p?N0ZSCy?kk@h0z z?qvSf-w$GJhOnv(J+KkfrR4NbES9EHSN6W>l@b-UQvmOJ%FZ&NsmmmG&ONUvJnpr zn$&$CG}K0p)`Q-ZYyuL01w7-|3DF={Jnz7B!;^n;!vLlGxAuM9f=d;ipMT1t5A@i~ z=J1bVliJWPU#=`B1GmGOp#Jy`3k@ae7PSN75El6&#C54e5OmRIA{k#}znHfqYQ|Eg zo-!z%Mc85fS!d4k=ij~D6uiNS|B(|;6SfVSG4WO?OFX(S0v@yAxQj*GgK+A%!*kDZ zPD{s~7L}5K8?AYE3@kyv$YP)1N=FZ@%%jJSX$mpCYwGQ#Z-4V0bT+=|SVtOcM8w20 z8g7P#(X5?8+F_xC7@Tp>)NNbX9?!F~j-EV8Eea#MM7Ri=_jT!^YXiQKLKjwDTStSsHL2-Y&*n%19BRCqYKOXycdL3TFVV!-}m@)z#z*_Ze9 zDY{^K*AZ?p8%+}lE8=VzOhF<){BYW2{ab_JnfanLH7$gJLlhNG;;hidFRnJZIGGH_;8vK|Z9D7z4->UY zC*=*q)QszYtPm4s|1kx*ziOO!%;j#q4_E5%3pIhf*^@7#s&2E!UUGGPm8Jc*KK|e- zd^nl2YW=%+fhnr-bQX>v&#{&(O0%crRZoQsQH%uX^<$SPt8pkl&B@s%PN+8{1+tUE zuN{|^JS?73`8$nB6RyWi7Go0=X*G`K;Qh6qRXtBKMu;*4)XdL2EiynwvyRie0=+|) zasv8=;5{zN`80K{^Sq{t3Q(MrFYlhUk$R0yv`DDAe1bT+oel?w(nXv@Q_Q{um&p>T zNjc`K|8k0|S|^P4+#wC3Ds>ZCPE=&`+FTd$A~z_bq4>ulOHN7Ax=a2EgoPPk+NAz* zUY=%b_{UYmh{isMb4}l@HTbe~f#+;&z>vCv$MgQCD)ZB{WMIsSzk}L<);oz^TwF3r zY1$wPi~oQz6wg+(3)}lv!?4Nru(HOW3`ls+-|XUd!+i9P-KwOM- z88pne)nj7AlOCaVW`6<9P|xr5N_@cC!`7katxsRyX@D*1Y{qf+Y*LC@GKe1YAoq0k z)iS7~OwNuHbl!^-`^O5uDOVBEDG48<7^^Gi_s@tYqjf)LU74@o&3pLeozGClz*pt9 zhNB#|9R~sw2^$+5Whc#Z$@)6ireBb~$L8Cgc1n2m9EcBSuC>ivdvK2lYPf+rDo=uGTvWt$Ka@NcNx)bIb@39g~%n%@}C^;Z(+U zqiG)%iKDx_f>C?f%a{9|(=P_#w@$To@7#`&7~MK{{P<76;`gtcPJ$Z%9m~bcEi43& zTQ$~>I&DX3S&IC({H)_l&Tvgf1eS>(96MxvN6}@xjk$*Ud@MvJ9=$>m{|cOod*Pn4 z{JUg;*YXRBd~AwYd=CWB4r053Dz$pf%ZY(Q>Zv^?N_7fhk5mO!^~XJ2*bh z+1*w>^;KdKTrAl=&d|Uh6yaYr31u6oJ1}h~_+YhWb1;qt4XJA<)6`IrlmVh2Y0vY6 zpWgLY^P@!Hhw+7bg@3tOpuD9C-C(ll!*Nr^ZwUukNwM3ZvqZ5t&kf0$N|qH;(z>V2 z&(6M$f<}7BKcoVu25^!BfLS_psc>uvQnBC1Y$b#(CroHK)ej+_CdkcQhG2GUKbQuj|{+m#XM!QC8WwBECwhP2UtO9Y0%ijR}JR%cHOHW_2QUI+P^C@p1 zxU+6MI|~d7=lyMz!AsK+wBnuIL@(i^AmO~2{GaWYR-Bs5n^gD1d)pwp=27D|-S0Wt zd?4=%UAXLSibD)y9uD3%Qz$%;36U3Pu4K+RJ-9enyIVt}eLLN_9Rb~UQ0PJ|bu8@2 zZ#a`|p^Nht(CZXGWCH-7JNE_v8^Y6XL-I}>U|)4|bex2RWRVOs2>!QC2`#GqHqPDn zQjC)a@pH`>C*QXLL~u{!?a7>DQ(lwokTx^R4h|+xGml1}M;vaijg*!>5+^tbIKd~z z(vG82uqw^iI{N#4W`9USL&NFqD$j+`D4s@uiz?`!+i^=-aKF{%<@fdVSz&W4>+r_F z35H=KaG5|@2P>3wuqAxx7)rZyXAtRjEQJL(IRL&$yL5;VWS6$T7ho)mL24I87!5OX zblF2TAZmVd_<#<`ifS5;kB#9l(U<0C>vusrlb<$rLbbVaAA7Ma`UN&Hr&>y}@w*^^ zRll_Y@EEkaX@vZPcJ2koy6|PPC;uxld+)!BnOrSPN=zJTiYA9AiguOsGf9t&mV*;y zLkt>l;PPcUa+sJR61y6WEiLJBE1Wp0TIj#Ei8O1%_}m+mgvQ23Ff(Cc;hP~LzMJcM zV>z@Ge=j@|#92rj(#H9gp(sg!2b4I4Xr@u9g*c|r*S8Ge6!HD-fX-)v?B&Z#aJ1tr zfAK|@@9FZ0r zb7u~@93)W(N*!gMD6CA7M~J#!nemG7*Gq<*hb`A%?oMf0ae=GCZ{rR5(jpE@@La8! z`0;~vB?5wHU?5R*%`~$4iLdERG2c`FTw4bH=-wa?&1LCLP{nZzx(khQVgn~bddnfr zjEs(cD|IB+aDay(B^8j8@&%bBXrpU?ep%vZM?pbBZZ7A4KWvC#TV1a>wwlNM$euKn z!}X|K%siJ9i#`lG0O|4JnQ+>zMmuf-Nn}he=ajMa zm4#zRkDhZ0a8$W+L0h{V=coXE@5aSBRAIlfL-9jgyzBi0xt|;3TbvQc>yu+>n_4kt zsDuNT+(>LT3c>A*X7)=X(TnnY;K0sL*R15UwHLN&-Cp?}h~%{X`2Cxio<27-Q`(~i zljMiZ0_O2`y%)GVt0Jj=ykyDcgbcVeJ0~aBo>6CbfDjUw*fFLOWy;6J%CkF3Xx-~) z|NKFE^<#H8`x9x3u!XPo)u?e}=oOy)pw)2REAGVm(+Y zwL&iZ6rcvqO@P#NmJw{>5kc>NWD(PcaSk2W+-GqpJ2cdV)X6ZBqWXf zL3w%CA(3s%0y`;isxrtg+y(SwjAtEp!-wjFW8r53)b*-MGEfR&B0;Efadl;X=!-}2 z_us+~;edd+$A$a<$t)F!dHHefhTKG#~Tl=0{Q@CE}TY?Ym5qp{C@Ikg|LXo3Puka z9;2w+Nl(PT>NoRZRgLr_L1h&l)8cryPI2|^P5{qqWXKVX@#SL41_wL7&hJd`Z|+a{rKj{*S|%#(;}m+dk-s;ECQs zsZOsSSNALlhSu6I2(ljd-+j%BruYG^u}WiIDOM`QtJS`1m-5u*w!c-QSJ`#y*2lws zzw!?!{N^+Y6s8sHu212tf;~X>|FIr?{eh%?ynF6lFEnN7Qzi@zw>A1*WtZTVk z89`wma|s_%%V#78|9mCOzxjPIdBk6*hzMN7|EtB){i}>PApHWDn8Oc(azJEcONMkX zS4$W_Fb4t#91ll92O)Fc?c~omXnuMcGI&PD53s9k!5U%GgarJTG-zTo20}z-Wo2F- z_cLV;@yrXQ9&@Jg0l*ZO=$5uQ0CCd2kdU3U?(CUS|2OAY`L(nDU(d0sb4RS9;Gt^5 z`v zFS4W@Tp@6nYB=IlDom$6d-vY`8x6XPFLi)AiT(wDDix=s-~i!hF0N@Wq#w?gf+}7ax-(XaaTU$Xl-cnm409Wc)yXH{H(03 zTwJ%Ne6k_V{mWOX?;5HCk`Y_@0QDI#MB}bnJkp(P1tyt%m|q6Hencg3VlSF82O$(# zb3N=ZLgPt}MXrIrS=-p~)j~-<_SMV{UtDx{Je3{e**`rI-CFi literal 0 HcmV?d00001 diff --git a/docs/static/img/docusaurus-social-card.jpg b/docs/static/img/docusaurus-social-card.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ffcb448210e1a456cb3588ae8b396a597501f187 GIT binary patch literal 55746 zcmbq(by$^M)9+14OPA6h5)#tgAkrW$rF5rshja^@6p-$cZlt9Iq*J;!NH?5&>+^i? zd%l0pA7}Qy_I1b1tTi)h&HByS>tW_$1;CblCG!e^g989K@B=)|13|!}zl4PJ2n7Wh z1qB@q6%`E~2jemL!Fh^}hYfz85|I!R5RwovP?C~TGO*Io(y{V!aPUb>O6%!)!~Op% zc=!h3pup!KRwBSr0q{6*2sm&L-2e})oA3y5u+IKNa7f6Ak5CX$;b9M9ul{`jn)3(= z0TCG<li6i8=o)3kSrx^3DjJi7W8(8t_%PJ~8lVjC z2VTPD&_&_>060+qq1c&?u#iAbP9wbT2jg5_aX>LlOOXw|dQJ8p&2XYYDc|J+YUT?3|Fxm{f?d*1vFWPGwXt8P3T#_TQB*NSP3+0+ndOe%v- zTZotCfofsS06&ki{<`Cj8{s5jFZc&1dl<{IBW%#V_!JjOm6+#&aRi;8ODL(?0fENIOtiNXjMhdO24CeDB#rNcC*<=TwpueFfx=2=r z-lt`qW^;vEFji%7kO25#YkwjKyZ93WFbbY!Q6-@Jz!9kqj>xgp2VhEYyMJwMYyHZV zG;7!MV>54LS*F?==$6(Z9S zfrEy``J-iu6G?#+q=$58MlrE}+C~G-hEMn#CuNuuVV;8#FHuD_feqmtfw~Ran|V#C zy+f^&q>|d(X{ubCVWs3Ai;Fz>-kAk`yX{^Qj_xV#NEV8oxtfCsq3%uYN0U4+Kcu%j z?Rzr+fnu%QVSgx7Z8;iqDfklVK3tl(C|B5~_ywyQf&|IJgyoV|q( z<1`6^2G=2%pTX$m#~!Q-7f>sA;n6 zsy{fJ>o;yxpRCMtZFb#E)dl;n&K%g;H?#HaC_HvnHuqN*d+9vB7ZNpfqqTsk*(((>8<~)=+HX!*Ss3~|# zShAf@XL@`g)$G$rAA9cU; zk+0v$7Rl=PDs_rN&*@^DQ<3}LIqeDu_8cvBZoZQK#xaB*@qDhG^d_fYSBG@Y_wC5B zy{FTF=4jI`H0PRGXlulcwJ$*KBs^);$y@AfTWB!przp%+gn+%ZU2qD$Eml|2m?K;y zsAx49(J!Aq5lqX4u5Rlh{1hD6V?uI0-0}%=eSBZT$;aWCJrM*G=&(~P~7QxUJFlHF+63{SfFhWU%gt&D(4Z~X54CH?JsJEHzO9{;5# z5f-P_*$Y>=CXYL(i4Vw1)$Y&DwihU}jeLyuS2hQ>zS%^7!rET)y)?ZI;W^c(neZ5; zcYHr@l=i48ImXZ(y)o<7>Av^Nw!8t!KDn{67gef*G5f-&iZ;`G@ej`@uBTkn0_QVc zw|RGr%!y|LdrjWk$H6iyi9+o%)D%pY)DHt@e}~ z-ryeSdskl$jkA%Gje(z=CvGUb4lqb$@>K02q8; zBpGv48m)G3Jz8nD`*7z;ch+s~JId9q{~KmJV4qG#VyhtwGh1U7ZW~XgF&CHVcfjI@4|IAMzt7B{D4ttmRhW76WO-cP6HX>7cPSIon_Pic=YB^cwH;qqm2b=+@OjfH55;lLt@>%R&7MejNBW98rLJXZZQtF zmm<7wrV(U^X%O}rZp($;Nb;(nTO##-Fk_K%y2c4)Yt?EsKDLVz&SyIxmRvPYUf)~A zkMkfE4X%Dz8*f>*I$-5J)wLSdUUaV&xP%U!WXidR7*F!E3|fu1supvKyq>T*84`M& z=Dt)zp4h*&a^3bbAWSy|{$~mRt znU?J9X@W)z1+)2SKH;RDEk{C{F~PxzePOC4k2I22=OxAKZEhYTo#jZLnzJRvL-#I` z%_%U{YhbA5LxSuc7mb|<#t0l8BZHy-cvj?r(|M5YOMU0wJ}PLj6z+91PP@u~sUN(0 zoPkUiqj+}m^;#5WI-p1sl3!d`><`0$1U4*Tus{#@{oJ~C_^ll&fIY{RWHLB)Iw~-5 z_trhoc*;Xx|5u&|7Q=~%>SU9dJXt>XnSP z$}G4aR=bB#EC~i5U_z8$Olb|B1Ec2J6a`$P64P%*8UxnscnAmYxki;vGRSH!M<=El z7AwT}?l;S3Ju)fk9NDaW<~K*9J6DCaimLP@Zry38*StONeVaYg4GMSV1sb;$0#63E znXJh6$=|17p)3iget{zQI-ZcSA4kztpbVusXh9 z97)P(^GVx?9}T_w+?VG}Hu2dxs!PdI;c!Skm{8crbnUpgGsmO6Y~0f~`3af#=;}JO zs+>jl(}Ww@TF9nIIp*io9|Ar+SXKeoJ2p0xqq^dDIUaz_3UMRe!*?g>RKH02EKY^8E=Ov%mKqCKc_O8|58B$F z2nPy$8uP`nq5-GE>)_IseB*$*+;W_EcowmS_|Q%w=6aW(&AB z%OtxG-1&Xrq>E%{bjzK4kBw z>Fssz$u`@4(H4(yPd(wlj>oT~6v>IV?P zZDj-meBV3Xh&lOz7Q@p@Wg;VMtEtz0tWmBTlY%+n#pR{sF{)xA5u*BuDd zu~BvH^44yI-2poCTSulFIMHH|6$HIN2!U|l513rs>o5b7&T060H4stH!Rj6uhJ>*c z|EXULN z@Ms{ehhc57nJbz5tP(eS6gqwNx4;1P!wL~Xzd!0hhz^)}wUrh90P!E%NrcHnd5moayrW^mwAO&F9eVphr}#sl@u5#&@cZG3Pef_5ki2d4No`s`w>3E)~NzQq~(%!wQ~iX zS=!>QgW*;6d%-30eCYi-s{}L5+4xRvjRMVc-|_!cJZOOW|D`V>G$9BAul9zT%D`1W z9M}_f^IBfCT+$nV07$(ZMgM6Q>awY7HarX62K->7rWiZ>Plf%@Tc$X)SUE~YSzKHO zOo@t904vq~)2~8z9N~Y(5ghjQaweijSq9}$13ISo#S19Gyn+S8<}IqydMB*M2Fv(F;m*Z^NjCKA@hf(byh~F_Wz8Y|LB9G zj>CREj|u0+^+~|!q^Z4wYAm~DH8vU0K5hJLx;^WW) zn1WdmfwUxh0&F)Ge zJJ$CZ;Gif2pJe@g3jR{7X$9eG;iwp*gh^4;#?q$usU`sYWi;VGk9zUsuxLCqS?i4> zU*!nKB+RzHh&TF;OaYU1boXkFHseTZ9^7*ClUf6WeOAm2`Zgc?XVxs@; z3fyjS*rbEGB3x27NK$sQDLqTsoYX+=I47hKrjQhxw>;|F(o#M)1Zs3=vHf+{4*=lU zQU(~L2n)P!C zOzn-%j;-zdo*A78MJ(b}aNl*Pd%bH4<%$K3cP@a%?zXvnXr7tnRf8PyxM=h2%x6XV zGm+MfF#t#t=FVq6y^o&};nl4gZ1=OgS0W6oT4??aAn_EswVeD=G?0*F3Ky5X?YMg! z*>m;`U68Bw-j3*NS)Xv59AyM$#IrAaBLy!3%T~RztCkOyD`0Oh)~c45m`f(fWkn+8 zFDQ?ehB?iesKfXr>kR(d+^nK;|$bJ0BgK9l#= zSZkY0hNH`T%pTpu&S<)sN$BmKep32<*GjviX5<~dm2S)BRn}Za<=11?iR0CbzUy=Y zs!S!r=YBKN!Hvrz2HB~apVp)gQ@jZ_C@MZHwF>*RQt`RvqEl`)rFXy;*9O;aJ^+IS zAuxBFkwxDhrD+zs6}YE;!WWE7N;x=xxy(hv8tOrT%;~evWtP_;i-tw#{=|s|_1gD} z+$ZPC>;C15y?f=k!B)}XV?@W+W5Jl7E#au2n|eXFYo52!7iV_nr>%rHTLnmp5t__ zeQ~n3Y!)Mwq>pgU`A+DOtI(5{uM`!T&#y7{XqPhrZyx}q50{b`55VTpH9@&go43WC zqZc?IJ_ikEfm4 zqiap;*teY3XjF&M`E)w#v0j2fK8>&^=3ARl7X5?sL7($cGUyT(&GjZ}T7K}UWUq6o zgZIm=(`C|a=eg_1ZeQ8aAv^V`3$rbeo%f|J-#teM&do=aJ4+|bCGzXl53;$~hV*A0ZA5ycpm&br> z1s-woGI3ag*H2HL@1`7`+#zk!nQo^`L}FmXBF9_OVvslb3Qd{^lg7NlT6j-eh)ldq zIsckeM z_udDHz~0vrwpZ3KkTG;-vI!dRfSCp$d>Y)?cj8N5Tr%KDYlI~&_w+W~Esn4I>jEK8 zFVT=y$0H**Z{;PZsC?US7QBb(=tZKtCHDjvqV8L^j>>H?^4A4kTvR^*B7Ecb4?qFk z;I3A-%I#4)i|WCd)!jLZw1itTxsZ$F`MsNa(gzoB&z!Z262^le=~~4I&U`Eb`C+z^ z-VqlxQ;MGC=e90n>dE>aoHV5TkqviF0s?l+z${VoH%t8KFvbH=8^6e$^AlVGU~39o z`MtfitBvEM13&NqqE=`^fHwS_HEw#UDbHmBR+1A|sO+c44k$ zHR9{S!q-(m1a+=}nRGQkrWg-S#Cg;_7%!4Ry2VnE5r>E(^0Gl4^r-P`1z2qO@^9(pRjEp!;DAe7B)FZP$pa4?IWYcn*v>YZ(G2ETw zy|C4)s}8H`Ddud6ogaW9O%*z&O_X=V^6P+mS%uG2EcbTZmk$RT3*(0o4D%(Ts3kn3 zR^3eYF*}KjX-S8m()tqnj4;!Sp!Ho z(7&2M@h1HM;%Et+(u{~Toh0sg@7K`vuJ8O(-mWug9HRvjKP2RmGqWQF%DK(bM_*a0 z>f3#KhBt~#=bL&FWEC}JiXdh?Q9fn5e)7$+{?1Bdf8>;*vDW!BMGjU0?$JBadm(AQ zHAmi$WF|HJ@r5-F$f^VPE+X>suAfbT1DUvi%}6k2#y?ZFyltx!?p zAr?D|oG4gh_c+U9sb>u3LP&?IzmiCo$x4%SP!Q8Q(jEtG(-GPNIhRV_K5L z7Q77k6Jdl2*V9zOs=X@?=vUZ(27Ngc&%L;RjmxGl273=|7++0XC*K z9Zp<^Y~Pm)w3D*jwEo<^OkS4Y<#>lqUb=O)W%Fa5t!Yi<%z$TRIO#_Z7Q3QZ2H5BD@(x_63h;Y($5taTf_%0;ZvK_v)P3}%^YaRF4ri60UEoVB z9tvN{)Jtntfs9Z(yp!blwx06#5$P9W8ouO?r4Ila4@;@S!F4qL>h!`rvxwm8$-&c` zq^<(9nR=GK@B4e0qjX45ZoSs3?|jeZ@13@KMK0R)%1IlSsLp0DH)BFK20FoEM2kwW zSasI{O!BwCJ+a#u@A3ot$06uqU?n&`1G^@J*u|t@Fqwmwe+Wf0fpg%{_PCq6A2+)j z2hE=ehK9p~efCY}}Fj~mMr1Qr~qOdueZ6a_2SDwHZ*lG#r|D%`UFa~RYpuWgUN;*|PxsXBBeqTj`RJnU2 z9PE7zrU|}#_j#k%TQeT63k<&b?|z^RNGOSfltB4MjA|mxqLrdoZ?;jS1BSRxcR{3 z&%l5U(~v7ESy(7pNhyb$1x}p^+*ny$*~6KoZMdfentT6QH1Dr`Dd@U^^%MTqyRNen zJ1b!yKUiiizxRn-n~&g}YvqM*{G%USoM1&>P*AuSldPnqET|FpU!M=af1wNq_3z-J zu56ng_&fk$SpR2Tg&VxTY(oJPP3gAh>wSjZ5#J1#nHbkU`Cof;dA1dQz?$+;E7aQf zK?$L1IL6d(9>vPMi+iISD+SJz*W!e)X$i&Pwc(XN-;gZPke+O!zgm29u4?v!xUP9C zcK48Y@K`NN;M7x{1@te z=@S`oF&M(3^!G8wji3Z4u|IZUp?p~QVc?q&l}!U>SAWC+@B3Q=M8Gx8SMIb+e*r+q z{Yg@g$}_Sz-mgRV1*RA!0Rj$rc-W8!5u7m!h@?;r;RvN(6Nx9m1}wb6UV=69pH!1u4ND1C3^0#GV9Vk5v%jLF1iBkM+~_oe#(k6e04;|1 zqVxcTK}B~<8@cW$rb+NWw4LZ7KVGkN-UHS;bD^cK+2-3`Rj^V98<9f`kPTuKt;S`5 z?|)V)15P$Dy~TG^p+BRJpbTIN2fb57!5|jT#s_X^pnNi>exLT+xuR}kI zLTF>DrKH5As1d;xUMq}JD`rE#xm<3PV^bKt~*|K(@>_s$+l6?PG9c;I$Y$I9Wx zA;xF_MZf_#OaTl`qJ^-80rMXYZnX;yHMnC5N`v2j=zq5Pz&RPG92*Z}aj95Z+R(pq z5>Xr9FJ8qsGy#`dMOy$X4%|!w<&^&whNI5zri}lV6#?4!$Ljbv_f0<2-3Nu?974eOh|NodBrc6s{g264H^#+vv zkI(-F!??JN@B<(iW`KcV-0ngu+-@)j;0A>UFo`kAQKI6|7gl5B1rI>b2tj!?@U%?! zpFY4#g}oL@l|*Hrm#l)1qwa_0RO)Vc;oKlpABihvuq26}r$$LgB-%uwqRxuRrpyG- z63Ji#aENg52nfiiNRQwVk-^yt-aSGBkWsL4aPbK7DcQKVMb!z2h+ndEs=YI%qUPWc zQ>IZ-)zB2Te@6Q%>$!xa)SLHy;OQb1@YE3;2Jiq}T8Nyd)7_1XLd)Qqf~l-gf<mu~bv_xL2)jRuX@t1;#}dEe+$KYBs8Ozc8vKSmQMe zW+znS+=sB{$!eWdtEK&;U{CqQ65Mz$g8{KO3091K?+PmZnxe)Uj z+Qa!s1zBptH)^y=Y^r;+YwUV(!nv}S<^CwP->`OJJ9$f5gUG$;btdeT%D1lTQVA%c1zi!li^! zRC4P;e}Vde23*`#o$}dkJ+39wA!C@gdHJNz_ROozn%~qZ35{gxr zfiN+FJmv8BeiZfN4}PZY+~4(EHI@`4GB%VeN^dL-nxv{!>bS=G=d1&YuW4g(RYo?9 z1bQp@-L75k9jgsahz$6&S+Al>N$6|(Uspyh?G^CV(>yb-uEMv?{QHK7y|JZHbV$py z%-C#HQ^wHzF5_m4mG%K(t4T}wM0ZA{r9PYV^B7{;x3r!Xhwb>CR?<2{=4)iW>-lFp zYAZW-ff6Srzcmf>ey26kFp~2&CwAle919+v=b#GbfQ_k(^GDH^U5h6Ij_hJl+$cY7 z`$l|J9)NY0%G=H3-AiTp4`ibZCebLFOx0X*^9LW5S-jM98V1l7TC$z>H_cy3Z}AyT z7cVLl@}RT$dt1%R4$rYgTUqZJB_<@D5gGBnLzk|&Ap3rHOWJjl)n=4BT|4ZgqT{Y# zt8otJt6vZPNdUZ->2VQc|t#}@1f$zuiGu7Z`2Eq_iUO7kLfvf z3+3l;rJH=!P82eCED=AEqW3F^^w0nBW|fbIo$+A)nzK!N%82P?SXGa`4vSNK00<2u zG?U_{jq8ikbd8p@c-wd;R3TJ+v(c9o9< z15te~^)#o6%yp?zaR-=9=hVgU2)|jpPHt`JGmCnIB+qepbmFikm>#nfBmU{7vA8^z zhTK~#rjjnUOtV*azuR=2pq%=qDo}!HCW$#qTWyAliZ8Xa(cAZ0uV^tvuLjr-#E|<6 zgACc9`oD!F+lpA=rLNEf$nCx{x6Vg$hB|ia>mt1(@zkT4(zdKQrNiynVbyP`+<(GC zZSyg_F+eKZ$i9krPDP!?9!-GQV7-#k7*{YGhxdf%D@)yd=P%=c?r60bP2qytty%-G zh7;7A?%TTQIkk;cPgbW*m6aq{m1>`^R}`Bmi$Y$X?QaEJ3_Auk*q^L1i~N3dGM6CL zP<_JeZDBHK(^_7!@i}$(_U*t}@%hy|H{~Q{;gP|bU)fn%xGdctI%`>elX|Q^@vKaK z!d+`Jp@j=)v%^wXH{7|-__X;}-BP#uIY3=_0IGNc zu~4o%m8|B~5EtZ$^}=3sv!lGEYU+H?Y3%_wM6P8#*6#HJvT!3ul#<{n9ja- zRGu5okTwJ1Zmk}BqcGi4_;~IURanbdr+P5iXG<{exUhhs+*pLQ^{jA#EZ#>o0{+2Mh|5& za#ugek0I`(zQL#5eLDARVY*Xa(DwdUqkel}vhN3?;f0iO-H(xqufvN&!zQI78i>uE z8>&m)ewHaoGgtXPku_dEb6PORWr~;1cC<+G5K=KBl%`A&gp6C>lB)v5Ri$FsN;P4>0AbJz7kC<~Dg6Mg7fXVHmZhEHpA*eA&u za?3ON*{!W8PYLPoTR+cR&PxuH$lp`AWkTjWWz)Zkn3TIiCEofih+Lm=9GE(9)!Yfc zt(H1<`s=^*222e=?7hC0lh4e7B}PtVI_{cAdxGNtdfZX}Ca>Ti9YS^NB6cCtzFtR} zgaj!>#THZKLuuFqeb58ou+VPMIV94Az9}?pq(nm5%Nr@`CDh7dQqUo_(1Ka~Jk;oawETtB8>b`mRyBtgh zO#hV*Tx!lPBM`YD{&wUnqnt2DkRmgRC{h$?KYyR zNy|HI%;HhKQrs~er!LN>c2+qWT)k%E+~E5H9eFKV;EhkieNbfqMTavz)YO`;;q)r^ zRKcAY}gLEwaGA zNB*t;%C<*Y+tgCdcJX-=MUjGgyz~ESiO9#&b61{-h<+|2 zO;mjRZ}0|pCLmN$E}rD#(9h}~)QpVO*=OQA z#Y%e{>N&D?0uC{dY5L(<8J1$SoXTWsj~6x5e9=~^#nEWa^lWqnid)H7wg`B&H>nuf zicIgRBoFD2ii?SfJ43AUH&TVFO^DDYcT;;?zvOP%hwr9IDk(8n^Rrc$KG_W$S^CCU zJn=ZugG;lxxPrOnJdw}Typ5n~t5&$I{si5!MLacZa-r_WCh{j~l7-Op=$9TV5idhN zglm&=R)0UNEvq|kz+%&#x}Q{2@c3ZLBldp!yX7N~c^eZPht|o%1isQe*+RisbVF_% zc)4$!;>pF);4JrP4@@UX#!&8hI;B{0l7;+j>*r10Q|es&1NFKQ)-tV2$Om$A@O-## zCLqC6viD-87K8StG^Ws5ct0&olMkYox>$?+Dv3O{NlG}G;g5QSmf4?q;BsuQo`^U|{x}>ACKXRkdd^tU`U+|LS znWy0^S2)LcB@0!EdDt(Vij$36^78r3tM}C?KI}e^X9-D}*M!iFT%zNr0Gf&Ck7!`A>(uLE(OdeRwb4qX3EiMVz=vWC3?2PE%-wA%a1ap0C zl~rRJyzSkY8Ag$Lm-Lq^*t1^}+zs%@8si;z!Aaw5c$|~Vez}RpL6m1>KPeiGJ-kE2 zbc5&X&fJgVtRw*RtiMc#4#s3H)KgHzHqg{R3E#R(bk3b8<&|L5d#($dxdtH$sL)Ko zW+BbDfPQKTs#e36Joca~N!pf`_Le7~Lv03)(7sml@e{h^6)?B<b% z4<^3n;sOFVdZ|+>M(^LPJA^2T?>N`FCB!o7f5xo^osCpJG~aJR*pRaJ`|hF>b2{X( z4aKEJ#QV2I?XR1|0J3}|ZH&ySn!Nm=`P+m<#hI$;xz?{pkF56P+%fUR#QbB?5vU@D z`>PliKDIXEyl0$1ZZC5zk$jU4dGg+)S}VQJ{2eA&|CmIoN#1+}`@$?!Mu3F2+9T02 ze0p5ot83?2=!y%bJ6DW(u9o4&WO$pZ4(odr6?FoB7XL4e)f!oeU;7hCto!x9u^3y2 z_p)OlA3aa{6K=F7$1_8Kool5Rz84;b!W+-X$m#2JgTdGR`~%<5^BB{h$tmHspv zRGNoo-aTFhEpL1CiLM*gJ|XE30ntfqZ6RW8RmFz7r7ZSdo2F`+dbIqX^P95F?^XML zEd;Je?~!LW2b^bUTSOUq6$IdZfuOEh#~DDY>}8&v?k$U}JNqeWBw+k5RaOv)s}jE= zQ}Q=>D-=P$ONyT$s*Ds6LSFrpWZV z9vm@*jijy=tPX3=aU<`d%SuI}+t_(ucyRkiyAE)B^U$L7DbCd`ZfC1GSJ8C#vU2#vSFtvhw(~TDanF;rn!a zWgH2WF*ekmAnI0Qm{vS{Le0(+uM5o()7|2IRkMwT_#?fPo-fNKuG}%_?WB5XSGAlb zor5}ub|f^JD<-m8x~AHfvW<5`F`lhl67hM38YaG)q~vy{D&^Yntrm?>4z^ZOsgY#Q z1rH+LbV>KeLE_&Mx4guoLMo);;h{zA@6Vg{<*=;A?ow0;2nhIdN=lYmb%EU~F+?HH zLaoso&FKfglw9l+vgl0wD}L>5CraD=W3%oYoYELRdWj9p+A0?Z!6LgiDg#Eu>Ssf0 z&g1y!IZG_R=3hb@lHbRp(1j)&W)S7%^q<5B2`lgE5Sih9hn&%pLfAg~&g4O!dAzEw zr6}!RX6}Ey-TL;=D!pNqHJX2g5o#)RC9PgCs$st=+TNbHeB0ziMr46BDXhn3@+9lb zakzM5tAy8y(qP%tE{ZSGapnb4Z^LN!*_y7=s>e||+mVpl^pnes7OO}vC4KH*VY&(u zBMQ9fD2JG^z22EVkkJ~(SO;UACk7d9{ug7_|C8~{@mt)aT#ZU+DQOUbF#6axF}^Fd zmhtBwd{#Y3lNT?|FIsK&gZ~-#n-Y__6Paff`W5$GI_?&4)>Y6wNn%X>=Sz?np7Qyo zZH9g7Vq#S+Wke2_L1>5intVG>$_RV=;j_%`e4O#OwWIFnFw^vf``;Nw$R9Y&G7L@Q zEpjyn?t&uTR?$ToG6e_w*elUbNC~oP3@8{6T6R7*{BS$ppthlyGy84Q%jeFbF-1n> zO)SGM6LD+T;r0urWn8w~gEyVb*0_W98_BXWEHC7aW9+`WLmR`7N+r~9=L(~xq$Jgb zc0`M~DlkIF1Q$x214|&HJK67p$TCg(T6J$4SH->xR%+&~^((0Nxq2lp^|OY^7-4i; zBL#gyG5+ECIpe3%Ik#hK5FP>?%G+Pa7_Z}b`G(asWH1;##`0)}=0g~DiAQ%12Cj5i z28T%p_C$R@L_1|{@r`H-3@utWDI40LfR4i!SA32m0qYI@45{@x~z)w#KlJvgXw}%|m zRo=DGsu9QXI-g+Tl7VIjr}mX;4fZ(YL6iQz z`lznb+}yW8^|YL;n26~KwXN#Dv2^Jf8J;RGE5MC0?77MSdMq!OZES zr@rC*vXhutbr*g#pI;TJ7-h(_N3>Ax$cW*Hvendxf#T2KHpKfFv0s*GVYIHa#ER76 zH)fn1{!z7-v31;4FFC;np`(vIh~mi%Kk6K0qRrbY_10$&xciNpno*F#wFH=MCWkdaFgK=U$FHh6#XJ6e393;9h_D1Zj72KeX!pg_>9E<8*a-g z^}Kf2k*_7=T(WO~W~`LQ`#b^ur_5KjDOs!UUZE)a4ErIxiW)A?ryWE_hQ{K-z66() zy-hd_Wf6g>qeoGlrK;PChpG^jPZRHd1~2MDVv*}eCafA~rLyFEm7f|EuG-#T2SgA< zQulXvo;0LIo^229Q9ItQ+RBrWH?~QpcDh9k(_=n;aXhtJh!9kR$kCNj9kJ=~BEU51 ziIB~(jdq=S3*TzWE4mQ!!I|ecuJydbjIPp*Xw5Ghu@wSqzc$S6Ix+3baF**T>Mt41 zK!k+2I%~h$4?s4Ot~MGVS3+Ob?$pC%AG>el2v|PfPf#)JsHx(Ctgl_0O>zUrPSn=nDj;t;8OUo=NMf=eZW`H&)xh@0RbL zug`wD9%>dDMf!g1Mmbzz7-EO^Yys;ref6{S7=chPEbgzvK3Ygwd;HLVo?}5(#ACVb zWsLd8mLOML?j@oEu`Ybe-Ndygs{ANWu zTYi}_YQ<948Jzmju!q^KwWli0(I_g&4zh3T`JS8oyS-JxRIlxlOkv13y^u$ebFvDyZKo49C5A{;Tr}MGMfceW3vqv{k;$^5ymBa8D>MecFsutjT zA|2ncpoEfZ3}EUt@Ng34X@75@l=LMd z^xZ7gESH4|2|k980z_jCp=#YZA)wxX8X~1diHoFqFvh?^Q;)oZcQ^W-l}yf5-ITM^aKZ zdfcjKlYl-&+8kEemP6lOR$P)7OO`b%yP(T25cq|hroP0p;{1@NydW2?&Uu!(^E(fD z#^%)iOUjTB^}P|c>sOo(_ivgq!yorSoV_H}q{tDvSL(K+bRbh52yrU?;o;#a1$BI; zG0RiGi1qO#MDdZ{{&bK@3)dmD(0ps&@XAgmQ$@l-h4Gx@t|NQC$u0q^d(ku>t~*n- zd~721PFdAKA^EX@ux5Tar!^~Q?kN4Q#)8B>%mcd&9luSEH|o>s^4tryTublkdEEI{ zKR#&=Y~)FcH*t4`M?g&TY~~}M>#}&vt3FYW)XMt2n{6+LCM@Vc2}fP)OONUg_(3`R zRab{`pOc0H4Vwb&4_9$Hs=7gmE~%pp$%I+QRt~Z=N*)eeji{_PhDB=gEL1PPqQmXj ziAC29F0k*5&JI!cBe@oy3-j>BSk^9W)qi|x9siuq!?B_AiaL9Ia3GgP?P`@aa0sC%Vx~ z4_H;|sIZ_baSi_@V?ArUq-+ig)fyk1eXqmTJP^R3h2&8I=PKcQB=1Si$Yi>2^`ec` zWhT-zHa%mNK+fB?4Hfg(dl$9ssVh57orM0LPj=M|2|5Z33$ZS1MD#ToTy?*a5E<)o zZ^vgVRHt{{s?S|cu9e|pBs<_KW^^?c+z zVk*-fa)Av4H$i8mAsYz;V>N#~@y4qSwKG%ox#ZW_-xaK$Fo)u_7H+~xDQI%!Bh|re zEIa^~TT?%8*jT^u!yxl1>%qYTu)I_Iwf#Cm!)=kQd!PDS6W_)FgT0q+ohn_P|7b-8%kc;m zg1^9mPpG^{HSkKoxNcleZ|3O*V?9Y(hvnWYam7N)*3PotcW%Kd$xrtzn4cx+@DGp{ zFPwjuW6B=Zy)W%}`8}SIrnZJ4SEixC`5nMMSLxD`jCML$)Oa|F+)t9}6J=&fRyZ_^ z*(>evV$1-$K&$Aa2X9j!@6ZDeqAYa1l-8b9FTg}aF(uUeG0nO9eI}>KD(22{Y3iez z8sj(PllCVvngk!res$*`DI4Nz8|c28;b3g=9C+P-zJQd-I3R2Rjn*zpn2l7K`Dk-4 zq4GHFR>DRKlZC)XE(X!Rv+KEpkgX@Ph)0`3j~T?RfLQbFSRt^V`+L0ShrurdA)6#R zbvLEIWqYfi#>&qP=f_x+*)14zkd8ci08%!rf(xnWtQ7*>#*Q3lqkb5ZF8F>;{gl*e(oha^!C7JqB6_d~123dt*fdvJq(?6p*0LOR6U zl~o@(cjQPyT3~|OL^gOFW$f2uVn7?jn#?#D74*G0zSOzzEpH3+v@4X!>%a#ZdTNAo z02SDS+U^x)AN~i#!qbx+7~#+diA%C-494h3`5HW7V|SpXT!d-y6K;E6??0eZ_5aM0iGa7jgD1?z-2)tt(?%)HrV0P2IbUwxg)d%!3 z4(Qq8t4L!w^x)eVTb&7NdkTc^eWb9hI4uNo=4Vx(!X0`ZmUUTkqhL%zXoLtLh)Z5V zt{c8kL1$SYHBbFM)7D;w($|K!o|>Tg+asAc(_eT~?!65~_r`GLc;t~??0R+=C$8+% zSU9dXJbLgR#?h~h;~9v{d|1ty%Q<2)Xi_iT>Z%Bt?C^@A1-{?xP6+qny4pNWax8sr zh$_z;Rh0)xfA?_O?hY?gv-D6ddJNR4@Y&jc|MeC)wpLV5P2%7;{EV$#ZcqAzo!qmx z?ntfHdsSvdZRqSGv5P*ec0FDX*}Bmbt}B=gb58YCcP~YrMboq0D&KRi(a*1$I=D`) z(2;{aX$+9#~ce9s7Dc;AlEy)1ge>u4P`ls#tV!AH}{Mrf3Ev0g>k_on;O1VUFJ zja5^PD~MNp_xa--s%kd#tw&d-JDVyx?UVu)d+29O8LvL)y+8u|%P4{5!jguGKBVVX zp!?(Q-W+--0V4ud;Ga3@%BC&Ar4xVyW%TLQs?ySqbxoXLB9 zegDO|`1jpj(`&Du>guZMs^_U@SzO2wiCx{s6}xlc&#oh~?+TXf7P=r0OSNAfr7?9= z+=L&!eF>@TAe>!T(a=TM0@E)Zl#UnR35M&^|&$%M!ToyO7X*>OO8DdjGdIhHXPX z?svWHw5|YD^yy!Ed6saf6-1ZQANVTlA1J0y8BhWitD!fgc0O*ZogU?W{Bt5=|3G*4 z0jq4((3_~e7hRJuRM`){U|z**Fm`udnq^RoEE9-!$k5NS%TzM(uPX~_hfO9JTpe|K z%R@gT`}pR!(lNGD0G4yAhj zMEi$N{5aLE!7mDWy`(!%x!PN3{hv3%S)|U`OK02zn;mkigLW|8Cqk||nYC#RM3piP z1hL@Q<|b|GXjZHE1wYf7mwb8HTsHNp&aOo8IRTPw{J4rdTvT7LGO=6`h|uC8t^tE^ z2nXn^x%`~8UdLhe>F%x^KudaWuj^CIgH|`GNqTS1huhCeAzR|zcVN*+D^GZvg@t6{ zt%Jlv;t+k^cO{`*Oyu4vy&A6z3MJqkIX9c1AKljGEZooh3;N(+_BT<651L-I+e8z) zJj{Ug6s~`2z968B!3)qy`JqVw0XcMz?Z)C-ni;Puf&MR5s_EUj`9^N zc;)D0ekKK2F19`-g_u62@O@lqzi$?uQmFd1QaNobI;MW=A>yG|U2xA+(&{n4;JspG zJ-vAO_MWK+!A_SoceK(e*pjJyX<)UFz?T`Y9-H}d$jADsFSt4t`-_TXMgbZ8=s-uI zN}uEaz=#(l8|*5;4k$FC@p&!SWuo}TbavOrfL;Xic}AxxdwTfr^OtTM9$#(&gBgL1 zCgRm~-OP9kaZ(%GS-8HpsZuFAHf+g8Ui_asA_>2N z{}WoY+y{;)wte$I9;{JE2LYtY*L*^DeR{mjQxi_YwYJXSbXjlVYbWV!4!n?iElyk& zy^M>mx?ICf@W0anrFqwS(ZZjxm2p{Ct18%;%=`5whuQRB?n4Dp#-@jXfH)`T4>T}@ z(>zL!clT~7L2ehKJ&TDg2W)5kvy+LcyuryarP5q}=lE*g1$Wvc=HHClGs`X=cHYVQ zV}5aV#pFaKx{*62j~+E^{o=!<`%)BcQ1;0AmTT>}S>h0q=-1Jorgo9}7wS1Vyu?Kz`8EX1p_-4{J;lNJ2x?N3deQ?__Q4X`u)~;kVttI`SSwqY})U zf!AS6{dh$TKArl?Vs+3KubJMLAtooil(z? zH&-|YJnm*^mH@3dxDfSU*-TRgaxN1LCP6qu6!CF@J3Oh0=h9*XU1M@+6Ladmu>#JL zivIKXm3}!-e;8OYA`>woR4Cl#xB3fxB-`Hfqdc^pNib+J^$P$`DP<2hsrEp}I zQ_(``<1Ijf%natpKc5HM-Rbhu=J%eJL$8^zKwH{4agt`@cU1m zpuThV^OMMoOu|w6wC==YEgygQfoIad0O`QgblvY9_mqR|jApUcdy(Lkr*{YU$F~Ua zvVw5Wf>5GNfOcC6tG6U_>qy0qoKn(JYXY~@{Ms4=6*zcF8aRn@6ME~GsrJ;*92N6^ zY&>yh34%;EV*Zw;eUAUiZ&wupmR#g{_0^$e6Jn*c<*U&c;U$E65sQ5)%m&SUYzMv% zL@{=a8s{6R;#~Aq!_0ZP+Tc)HXZ5ttQ41tW7Sc)-6RcWb|JVmk8IeRFVEm!eAw1hE z38h>Y8j7T!0u5>#PY-3{)X9)G95$Wv?EN>(`ptIATg601g<1x!fptG-rH!E8_D@^y z1dNbQ@fN$x9!1XHW+PoaRWA7IS^)5E@W13I|A?-6U)7!w%dBI^uO*pI%56K)#`Thv z-ykObUb-b&0wAUMakr6}NE zsL^B24*0tdMdL@1LP5fH`2~=$lzpVC69|=}~RgpfhWupn~ZWk?Y`?*YnkT_6$PAm99BukW^KI)qfJ>l z7gXMiPUofoC9Bro+CW7mC0xY!TbAfh0b1`nTbEap3tQFSf^P~N%gc}L-aK4q7FyV7 z-@5mo0)~jBS5zmee1R-;UOJh> z6|SRB=#IA`W&$$?_C^Vd&&Iv7(>d?yU;US>%S-BE#sGTl9D^{`XhF(sl)+s)nO|&? ze4$V+tST@VS}vAD#eC`K%Zkygf8sG>Pkk)Z^}zOVizMU#CQ8@4t$~e;W)dyD-enef^M{H?8TfvnQ52E(dj(=QWa6&O0Hv@R6& zpj@3*{UYB9a;QNv9v$&h2&FMY3{H@X_2m2D0qm|zED*}8veH-axyoutqwF+`s)m|j zar8t1hZeL@p<%kzlZ}vgS;u%!PwYlakwmV{6rHdH6q~lQx|_r;Y%Ugs)4647*q_6- zwwzIk*Nalst^J^^%Bw8uzG*yzsz3`;;iL@i*opd5c?gEWnV1H?)A63{rHAr_EeJa! zvLVTlcpd~f@!0}a1uC}NP)0oLH_psD)Bjj%z?;CVe~Ob-vUkv+@w|UkHrAF6MB^bW zXERG#+UDPn6}LdfiHN*L4Y63-QVWLf!d<@>3DgG5QHbSQ0JwNPO~03wt&=#W40a`s znR6ty-#LlsAr&j8WQN5p%Z(NJ26hwHL~*DZ#|M_0tKqlLJC0TPJ6p-04~_mvsh2yJ zcF|vIuCXa-`NLj43JP}KqP;}qDCMonly(h@e*0Mh66D5NoA6m#T_!NLI=5w|`!(Ki0SOZ$ zAkviwBa7y?yDKq$8j(Iryu&3z*5dMo_^O$^eVtYvG5y>wBjjSkU=jo>qer@qPsa{4_M z(Xibqwva-z)kVxKEJq4Xr}L8~Cea8ByVGjJxFPv1my_RMIXt})#m?ixGH;vQLnGs& z(%FW1e$SO?YtGfHiyh}F)3FgT*q%X`S4URO%=#xn@3tOVYJ8{~sR?|^irvM{_V*at zT}D$9Hho10>?JS#r@W#HExX0O;Wi%j-mV4;`RymI_fb#wWcsYLnJnWd4+R zQTCq409!kbtSIN$TtcWjf>tL_i%h(cneO6VujA%+V$YUuQNPitngyJsBYmT?m*Ew)fQL(Vb{TWhqd;;-aCMu8Jqy zw2Yd4`Iz-T{h?>b=3Q-OxR>m>!p8lX-+x@r`JYI8mIyx0sOg>cvh<4&)gh4hba2An zmR(mU>;-6VwQc7Xa@K?Gzs5RDL)+B7sH@|A+w)j!YwDZLn}&KJI*N59c#fg7>AE=i zINsqY>+;Z6qnqY*iv1VLEcom0AhDH{^4ovv?*(W=TKE((gi)J1#w**@D^sPqAJ0Z^ z$j~1H?&D{nlhjt!m+STEj0Qt@%!(D8{b_$=V*B5$ zHD`O^3SIt%ifHf~oz})(b3JpS2zs40H@I9~Uii*uhH}v@Y~*(dvxFpw zA+1~<>mw=oBLbi^HIV`mbpE*1zc|AKIGkV{vP6dakoiot8>A z4!wuo%14@qFmIw*7bgnXj!kmRyL%p#H&@EfeAD#S@6H6OJ&LhiV{HA!) zQ8Y`L$Bq9Tg)GEP$gy?S^oPqB1^qt zJMHL~Uk18aQ&>09jAbl$r2d*J!NI)XdVmo{RWDpYz_TPN^D#*p!zvS2^PUf-Z`G5nB9L zSnclzT+*fn7R5oMKo14@r@pE`I ze3}FQ5~U+Xv;woLD?&R1@SMdKn`3N0%}d>SwkoGzP}bmzboU+(ZNONteR?hP#JA9zYRE}5ryhmi9r+hJ}$VsJ66eF~hT_rk;{+D>g#GN`L(iD)H$%URv4H-v_z zS8NRLobH1LD(Vn>O8?W?juDIdbm`_;YC+B)1Uot(VJV@yVyEpYT*ztMXMPbjVW8}s zm5yBhVX3%jNNmB6FX15?X~x&$8R~&CKro?`7e;CJVecI@#=9J?J&k1Q^zj%F84qTP zbPUJI4atIQxEPyO2mpT|-1O;d9>CnVUAH11ws;v8$ccDV}ac2<q3&_&!wTy->U&lk5cVKJxb9R0Iig(AXDxJKGq4N#1xnY{BZl`vUHL;ndgi>@XYSTCgUxaNIFXF0C@0)X7TNicC_GjvQ ztr@xX9n#fJzpT7HS-e#ry?SurQZh;zH%PMWs>_Q+ei|7D16dA89Ot^8%zgP*V-v;V z=UU|U2G|-D8cN~^u(ut)Rh_yuZ}zoAT;cspnTQ{#fT*Eg*#53NQJgvbq0%VMGSDbB zpb12ox#9fUH9M8l()~6kFyoVTD4>7o((h*{n^hL83_%gyHLpBs2$HvORIcz zeCP>s?ytt!8_cs@Kg(fmNgZDKmHV0dwaV7N6|UkBG!>1)20n)#j(JYa%t$>0zji+} za(I*i?l~5PWHk;{KLKT^rnEG~8l^h^YHg=X0+8S;iFhD;M&s5W?zLD*NAI+~f6yf} zKsOhU;09vj)lK8lKuBOASqSsTD7D-#En9kwA@-+-bRERwB3TUftK_4_Gm?`W+rJ!c z8V*JIk;*wSu&`-(aKZz7DE<=O?H%1}`%`rBr zj`aar@#AMRq6?B}^4GFhz(Rlf(G}q@E_-E(N2^4H4!m)stH`W-#k?bK%{74=H4{x? zB6Sf18yibRl+kUyIyX#xSlTo!%M^xGb_^_!6y?X^k$#TFQI(WqH{T2PZMF2=p?MaK z2f!Y}ERcH7vn^|tZDLR;0H-Q^tbyZ?G?7UlIkYr6KLrPnMT&w8A=at-$*^CUQv$la zp*9NVcNaT)Z4*HU@}|f)v~;r1TiNK{CzI(r&Ce|YW^v0?QWB=GA|{?GZx%-c9-R17 zFIQ(Ho+B8)3+Qc6%zd&1h6YkP-6YVeQyuPFU$C)p3rLVssmFk34c79jC=rG=fH_L} z^Y#K1?Mb0x)=!J||1f;^50rWdxXAD`3LnH{VPjo8ZIU;CtkU)`gRuK(SmaFPNsB?h0arwM+5SUmvL&Q%t z85E>Z5&~)b2YQ3}A8^Anl4O#Q@7JY9uv|(8MfPz@rOe0;uCAy?;gwAQjVi0yGES_p z?h;`bIU-*q3wf!=5{2HAS(DdEVOAT5ktuKFsN8)J)Y{zvD( zr(Est_{Q#>jx-F`7Sx_j`{92xv^}bPxiykDTFQ7~dhc4A)ww_DiR`WAxzl>{`o9N( z23n=16>qh~Uek0wAtr-93J#q}{)OT_uu%z*yL|am1DU7rKoo%Cg8&XS^;dh8k40{m zE=(7&Eip3z6LBvq!&2ENm480+ewx!>8(vQr6mXVD_?ehccU1DFeJ7Q2ad{f(;^Fkv z_~G?yb;CeO%B=tU3D!-NNs+Yg+aH!2&dZYQMC~r|yH+W)S$rG*8rtKGb#O3CEpl^1 zSh5~E6-$!GS;vmz1S#jKVxJn_e|1i^#X3hK|2)_+Kg3m46!vITR(~Ad3(8S4wzuY( zA;t(*RNzdUbA{*q60*myOKCfZ zSSAEwT-~zu*X>h2S~ZU{TrIutUC)Y4){tO$t$tCTRF~NRP*E=~Y~GJ|U90UU14#;S zGlsxY?~zzZ-Q~ECZxsCiarmZ3iQd5$o&UJZ{ze1gP*l`P|}5>3^b#oXr3*IAUlL2je^D^~`l@z_vZ0u{S%M$&)aS*Ij! z-hNtY`2m7T{0c%9|7%sFe=RsVD`#s|FqQD7t3d;di(Lj|YHU}Qc*d$<$J=VPXT>6B z3OU;=WJVhDIq*|VAFqnsn}13D!LHm&D&u8PG(5yyF{(^`e(D=p=Oq90U*n3qEJ&2G zpti}lu$a4dBmQsh1T1Hdtcc{D~%)d5FjW%D3q_w1^wDc{5;~1iM3c$bb ziJQs-Loo06jkNuWrh>(DsmpA1L12D+XMxS{ERq)f@ZtAINzybplW5i2;}=KW_=G3* z#>w(6BIiecp~@#>B+daN?Ao??)o#UGYVLxg&$*(b>wsS7=$Wd=@Z7&p@^8}U3e}2I z&g_oikS81WguVK^CTR-3(7l#(1>}LSVCd>55Y_z~W@bYElp0Mq%K~P51c>4+RYI}# zpHXYgig7oHso2kqR5CT>4Vog>TkDZ1;`D_O$+AiB30ftzWGbmUT>wr5G@@Rc3$vp% zwdPLsKfcn3JmVIMPKP(X+q4WaR%_kR*l_QkFEq(l06CN)lu03-g|Ut+8I`MPPiltK zUwhM@^z=`bUARfFT!x4ff^N_3hREaZ#Iedfq2eVISz$jaT$2!k3k*Sw^Pq(Ou-M_EdYrJSmwf?&JJNH!_h z-&nn%za86-q5g$ZFcdR-`E&#G7iw-Pp71@j%fI)|O_)H9>d{R@v1Bk4E3&^lL&z65 z`3F^p>MQ_bmEhhsR+N8LEp|bjUJVh#-Cctu^UNw-{z9>z=PvyT{0n6dp>%6tLBT-7 zKyHLUMngn^hlhsrkbr@O!iK}b!KDO>Nd?+E=P?XvLpD4QvuD;_jeuoU_ zdTp8HsN%CkkDWX31pK(5KTPPoK)qkZ`gd|CNDHIW1XVYb9qXU(_}v9vU!H=*47UB$ z*$cZhOzSf#glqL0HAK2;FZCmX%5-pt!mg?>kr_5M^hu1!>8{L`ol;qZV_Sc_sY|nNi*)U(D*Xv7rj{`V!YA62maFW)Vpu|rqFC}$p5&0|Kpp+-+8Wlgw7 zAQZzc&Ci8mdQQset|dG**wvXDu|ml7hKXO9efs42=9dusiH~G#^M#Gy=eC?4R@ov1 zJ4fKK+_7vJ^)Y9!;xZ1Q*AJQ^e%i3HQ>76`>C+u*zSGf7?4W9w6AiS z{*B=>e%(MRyo{x>>`#_6pxkvxuG8H92y^(dkWbd2AiqI5D9!~#X1t&74A4Q;@x!ag zp(~3(KLdM(*s1MVeb+jg%F1G^u=x|=$zPwK)g zuZVuc^RjBB{duk~!{6{nx4v0l@&8dulgc(YTL!P)2I^c*(#Sy)T}E_xO={>vLE9fo zDS4r6X);W{Vubd45iK6*n)ezQ{>a`P{wico?6@lm<1yl1o3|Ird6>Eiwa>$xDl8fA zjFw0y=?Jh2N4W_EjGemBg!I%smb8Z&vox@8d5*|s339AStKf9EMUadr{cmY}9+3(N zB&YiZ2dLxFALeEIWAE3eLmUBq0k!jVfbnGdUU*0dtk+NxCF>hZYhmMrhX35)&ki5< zRKD=;(}eFDD6zICwOjjo4(3+Z*o*>q=Yy{~=hZp+cPw}Xfbu`v?hL+OCj}}k3%CN^ za&G0;z4*D?xv86kMhJE3+F1A(Y@h56I#S7q>L}JoPw^k#(hfA^eKQp)8ctVr;tQX5n(wuC4>kK@S(aHHUirpOekHpjGJxdjR!jmLzfy*fo- z{YS#~|0H|~_wJGwD7lOeKu`C~?!x~wqfY|UO?@^=h36)OWMaxhtSi22FgnLc9Q@^A zd@C#cd(B!UK~Dqc&Nzx^p`@+1GFUDZtKdv-1(Cld;55%WQWuXVQu81wyEm8a`^$|r z?Ipi{w-@&=Mfk^jBH$!fn64N-@Z8Lik7PGy(9K+WT7BmMe-ehgUTh67LNl(+e8(86 z28`2V&HTG8o{C|uf(1dE(9#qNHaR2FS*?|Wr1p4xkn)3``BsuUh5?#^Ro5J!p)xv~ z64E&ugeoFvk8wDxv0+UE(YQFf|DkZ13t0&&sP%UT?*fV;+c`sJtj(WV4rR7S*OR!} ze4;W@_5(1%`E^C|MShYGaWHW$zgFPjV?ys|zw^u)|mp zzZW@8AK3(#)WH~G<;aq4UyCnJPZjD`|KPIx3zcGfApP~X&2xa+8MM(ojn(Popz(Qh z7LG&zWPViDV}{J>c)!JXK3RV9G|@|#S6)(M^44FdY@Zo?KI^^N>16@>h=gV5YxNKC zt%4U8djc{e>f-tJ=JpK#?4uW9#L)@1iZN!!>c`KH41fNk0y}{qA^&mO_5+Xn-sN;{16^U3|i^_$7(e>3CjR*S7Qh z-mmCR%`tAs|zS#Rkr16}7&uyK*XNwU$%GAwx$C8-|d_cgGnyx0WU(pT3CT!&mTp zWBoGJqLPYmBJ>c^8d`?a<_E??^-Ti@hT)~TYLICauV8jGC#<8)4ii}I{b#p$82XoN z%5mXx5|{dBy}@jMw$WV230l~>3h42FD;|c-XS_dbGEtfX$+wxY21XHsb5V68*q&geyI&{ zy*^xJUJ9U{Q$06$n$w_}=ecFqIxIwAw2+E_F(m=sH< zPMV=Un^53GazGVHYZQPz>+7va$>6C6!_XiuUQee(~nJ_cz!L9acq+1SWfk&Z+1iAR*D_6J*f1! zQPQ7tK(uHUane||)U8SSB$Dfl2s{4q4Hd=-x1B;G@JI4@f-V%60@uF_Q2$0>Qimm zs5YcBp${DH<$NXM=zy(r?kI7@oD~dpszm+>%BXCTSm$U3u4j)`1j1Ua9P_ms^?zzAxdspPHo>g%$ZYb`dF-ZNrrx^6Mt4KiV>?b0pL)nYE~_ zP$NYeGJGE%|B*; z360 z=oF>sY+arM$80X*tGzsw7EB*>n+4SniQp>A$lxp75~+-xSL~p^JiDx2V-V3xY@;$O z%NdIb#SY#8v#?`ld6Tg{OmAq?i@GwZP~S=LWiP-DO2 zfPQfik0+e)UhF2jS_}+b2F1xi5y*zbJ#vULGVD8G8!5#cpJ{*>FEGjEQ~`dQ zcOU0y^v1QfPn5adbKorrTEV`n1jZ+_CsbJ?7Kr{!{MaVr<5I+;lH8( zlWWm?@-3xS25%g{URt*s)5O45P+KHTQmBiS5l41G*l2XM69dicDjS8R&7MI?rhX$| z9OeEVX^1FAvg=?cGlm5GH&pt&yd*=Av8$S^(AY%ltYRug)@W2>D^WA(SW;|dj#Bb* zPY9}ZL!MjVzPnal92|C{3IUIgvC$FM07?EV&8XVOsA2{>=keTXV!WOswB5r0g)(sH`pxVp$E*LSx0bY$^ho1gZ(Ce+BX zgV-v@;O*LCgouh%LTJjh>6fNe1i)!k?_(K>@#hAJi=BY zGE;k|p=-ghx5_WRZ|zIf2wi`nNO=!AA^h@IFVd>=cc9tAO;Z$>jb7>?tb6ny`W{KE z@4c#}i7OkeEN~Kt%gx{BlP5$=yT6^}6F42x4XRhqN%6t?;^?rmV5dyeoKLqcsOHK2 zbb#$ru$;PP7F>-8@AY=H`&w$0QopRgaXn7;V8}$bm*lMCBkc85YEVhMoV!yFW|9fq zOOmzYH%4z?uXN91iF#K}mflTpD~cK^sdvEd|BV->>NLNJv8A%AlG31C6zsX}U(Y-$ zZwF~!_}FM_&U^rCK^~wXBnkagUjoVFg9|^`O?Sx!Zea>pf;c8<%({Q|nH^JacOn1z zeADz)ALFn#kY)z$^0QBF!@D0pPDEp@pW1(>)BE4M#(XVf)^jdx86Y`CCpVU>tB zuWv)APNSav7T`?DGY-4Nv|7{Snoz5!!&0eVGg@vN53J3Ee_3g#hG{28yjf!D{fT1E zpg%UfmE;4?O=&gw@ZDbf3Hai_OYc~H3~3&%p!09Y^Dod7$$qC>#(szjxJE8nhoW^b zyHTy4i$#2Ft$oO_M0HjPEsBbN7v4b>>76ZMU^64jzyQgDIvRU(8vw zWPJAM{3hPn^}8Sq7x3jCh>#A0#0LkcK;;6~LD|#%`NK@4|3rICT1gYuQz2?o{Y!3t{~rZg8TZEN4}C z0NFhS4PVz}Y>K%r9px4qj2)fe-bF0^YHjv9n(WTJK5}pczXS&VM!l-6Fb>;jtTbAc zK>wvDj2JFDuA*@Qh}BhoWY_h{4$zT9GX>R%Nz*M!2arbiK*p^`yCvbGMUsmhg)T~` zogo2NWbfPXr~}*^P`(nPi=GphNo*`lsV|mWNcALV zT9G=LCo(Lc$(c{p)vLpUgeC#3E!-5SI2<4q|L5aG>&KDQ6FuD;dD&Is2 zkhb{2IeyUMrXlL3Ba;z9Ch9BN|Oh{&lpP3T)V)to~umT2O}(UETHGV#M=KbH!v$e0++(+CsN zSl4jZIVZ1@nNopF65IvlxKhF>5$T-|oFbj-96=Jh9ctiE1@X35d7DPBaSD)+;H0*g6&q6ycF7_o7Ecw|X6Ib0dkC_CeD&2k z4?8=&aA-}O)<}TCveL}yP3kxGgUUoI;yiH&aiWuC5M_T*)_gbr}=-st| zZJZ9OO_)~7+%}NDF!kg;Xf>^I7$qw`T-gJy4AHH+g(f9~Yxw(2pl-SRg!wfr8=mMO zCV?;L;%ft?iQ)j@x|yb=-9tNF>u8~|kQNpK7`dl5y417E$Ynes8{9URCTU895-IJ5 zXfeN$gmepw!q10Mxeweej^snobY3zU8wjP`Z4wJ<@b@jSL5`$!bslp5J**O@Yq>%d z_0hQbLdi?M!t9H9mHsEW9WxV>jiGKMeQ!=g11Yf_90%3xV6v_G>rUWzaJ=|>#w6Gt z!7>DF1j_a~&rQ84Qn+njH9Y0@^rEgU;RTPsTLbVLq$5sDYi4iv7pfSYk zd_X9gsDx|AO^DW24B~@?;DVWf=pZLF6g$J!A2^X~-$QzCY`9=kG+Yy0qnw*_=_~EN zmvYy&A-eT751Sl#79(PY&mVc)jF^}V$sWk(4;x?qGTBP>v}D_%V|3P5Q`KS5v8b{c=sf7;8 zFqg%9AX3{CQ8=vcoli2JJISLN>1js61v%7CNzMThI}#;JFoE~YZVWlH2&RkFfePwL zBC^c9cfypX9rvfb?57aJ6EZ_D5mra$NvyCy!xp?Lb-5yfL}CO8w=pD8^(npBqbtWe z0xUCvv>QNXDu@&m73$6t98wT%g8dU~(ucaHlfk$P7=<%SWg&vjyO`+Hl9|^Z7$A zOeO(-ugx8&LSF<0ZU{UYi$(r=E)z>S{3BcrF%?<<@A04krSP9aY&X{NJ*GFAU~Q`F zNp2ioI&(wWsc32Nd<&ggwXsqM(GTlAYEbad$|0uUnUksjzg3*x5Yc&Xb8vjKnM?>! zeF#^==usY-oz_FiVY|77gsk8r|G95&P2beFjv@L;uh@|)xJzj4aebFyE>LydpS;AD7Kmxcxl$Oc>#b9|?L=2Rh2C6xE zG!vK>JSXB`qb3?siIObloPr!}Ofs{EC#G+aQ~>t#!QGX!-OA zf#wb~D}+LF_GHM{J#CA8gfsC=llm~MJPCZ*5_RI6@5?mIa_Wiw4B5Dv}6#;FrRVu8jR zQ|+?GOQ9jvK@6*Cv+GW&!C8o4Q56s=%jKop=|6|B&CB5mKC>W1A3vz>k1ILtRO+cr;txw^|Xo7o4;1vI6I zA&x~YuD~?WRJ`lK*kG?PX+sv)HOUaUsmtw& z{ctGOOL3U4rz&j>uVP`l3tM8SEILA*^pL?ZaA@R_k_V?32mH)j0@U@J+?Gx!(Wd^w zI{)2K(vy=Us;57#LIjbWB|e)O+E#;H%DNrEe{_@$K&(}{)-vmwp^>XD?2CyX6{Lhy za!(R2Q$+KF-6fUr?s({!w4@$2Dggwpg`!?@Us5R)ic z08>>Z7#koZArTNXuS$mrlK>S+4a8m-{t3dHnKQk{ovDKfN3}$BhGK7s_R6T|S7ZMR z#d>?Gs$3g5+|N0|MJDBs7#%NfIJ8Lr?{*!TV+aK(mQIFwGKUd}%}YnaYZcDHmUls; zS#KH5QZE}E@72DIWZ zPDrZtVaRC?ff+sIP+_6#|j?V(2=p@p+rvTQt+G`62yXR5@5@B(b$-7-lj3+#&Deo1XCzPC>y*N3}&uX0<*I5PeO-4)iJc@c~< zx)tZNom4Dw^Nm(2y^EI>Gu^J&4&|cOwGd=fnl$LGy!#_PD3YeTk~BID%?Yi2hm{%b z2i4A&VXyz|$~)|>Ep7~d{0=UXUY-KDajD~JQ-3~tbfC}oRS+rn^3#ZiGBl2>aXSy3 z=kE{c+u4kIqR2Y}4Sj#O;urUZsUhW=y&vVEt*0_`OwyDc*JT?t%Au`m4bn+-N)kSv zK91 {ReJKDzsq0S-SERkON=-c09|2#}%+_b0t3Ya`yJPygodggISBkbAcyLjE*Yb3t~UOjgkC_x9x z0%ciuS;!aTIaZoh3#Ky z{Mn*dN(JR&aE6UjX}(iKdiHtp)?Dn+DT-#nTL!|b0~qQwX}hrXNf8(CFUUz3Ck@ZO zJr(~a$g9DPz8~o<709L)cO9H&>>POetiuW*8k;I$=Ny)+Qs(gZi0C>6uk}eX-yo2u z_Q?nPbZb&5ZAQ%xm3P5`a##*2TCphkfJs_WqJZj*G(~2M8EXJEwmy^-`Ohh+P)o8d z32-I3#1_iA1go*xr0xoVszj#v7K+l0sS|8GX(C^BPqg!rz>xH+2_DDrF2nbthIsV< zH#H9BPA2g(B$J;T3)c(AivPyJfRi z+O=6D@RCc02uj|UQPXi!$ED@sxGcSV0|n% zESt|!TTYS4n&=IT7>A!CxHRwu+mfH3gAvO8qtFqES*XOFv7wd=(p#vB_9p|lJGH#< zpqSTvztq@Vj38pJ1E@?*IZalBhiY7qD8lr9he#B2TuHSjNRe7gSNXyK0PN+vgGpJs zkbLPNQfDEW2OTT{tZkrJ@nZ(^`bK0RxEf-n_Qzz3q-$Mdh=Fz>d(I~bjhXwkwAbE#ajxzb1>IY4l z^bvM+z;j4T3J$DIIy7VdwwZsMK|r*zVIa~_TNNHxo0tP0S2=I_2a(-eij8|P=HCyvL?}NiRhz4V3H4+rb))2ccB9ciWLS?WQN^W zPT(mTz8B~sAx80&B>sLON)#-(m#)9@TmbJyu#(!n`HrE>x_o5LGmLwS=iWUCJ z$va2Lku;fU^K=pV9ZU+GEgLg3-USwpMBrAY=I;WH;6Yi0ua;BiM1;*Za$JT2 zc${@R6iaXXO$zt4A$&3Y+u%vBVd)u=eplj0mn}wMdkiGxc9f9m>u^Lp+UW{zO)C4HEw?2#b*6zx8Zr=L62x~jL8Fw9ewU#DT6 z2*_z8*r)u>2`PabRe88wRb&m|lG7)<>6lSQFjIkaL9Q23Uzt>(=JC^`hy_&9mX3S3g ze17Fpzc(+phd*xqX+PyJRJCh^kJjAyxsC#TvjI!a!vE8&T6n(QgS`~w2z%4=KOB=O zOc^0f#tPmk7=p}tBKZ9L2|iK0{8##~GllmA*&iR^$fziT2@EISxQ zGLAN1)CgHfd88>D^ZAr(@ERBCxbY(--zfXMfN5Buyr+Gu)4y(Soad?6Z8R#)^yd-d1Gau#{Ee~Msa8J!f(4)&Iuag*7dFBY{{PO+n0{8c6LZW zXc0MwtoFq-a*0id_%Bpyoo9GGkr%%MVY0J2^%QkbqN@4u?s?hn+AH`F13?4^#A;Mb>1;*iQ3? zWVEXstG~!WJRHWQDK;f|Fk)?ICjzhBxTBHAdvK6uhENYbMuF6@1MTCxZvsw3zrQ$J zOz5FIQ%d)e#61y$oe{ac&>Lpoui@i13&d%*oI~2`;BF^@9lE)TaSd!h)6Zmvnvkzv0aQ!JPe2 zQYfgY&U8F5gc)97Dyo>h3{uNTN;HUU=Ks(RQ>BZpSyX6Z0_y8r-Rw;uq9K7`?XU-A zN&TrP0B4W#eMpL3Z2WUCwyS)=%^hu6L{T=aXqbHpi8DML_%mjFVMj_&iaJhG)D@fl zqo#;3tB55bT78Boy=Cx(j zo3jc`p8rPKTR_F}E&ZZ{Cb+u>cOTr{-Q8_)Cj@tQm*DR1?(QDkEl7Ys2)UF0Ip25B zefPa@t+!Us(0g{%T~)hk_m-+(&9K%l1z=o53Xca5dU8UBr(u%i*&Tki4>N}JEuo5N zC)XxjPCN}pufXoP=W3PQ&0n}ZgqpJ4D34aE8(!8Psn%03 z=)^oHDl?{M#*$Lz#s)xnQ-!BRVF|X9F5H(Wt6i$v1kg=7eB>LzqO~iUP2*|&}=PoYMg6(K!GRgs+J#QqOoi;Sa7Q;5Co|fI_S}ucxvP=_qicnw#6kW@3 zkp{zDnL_T3_or*9ODt z)x^)|EDIxq5q1-Ul-hD}%ES%rB~f;2FMx;d_CZAv8I*Y@WU_m9Dcb7ng$K)r#ymf* zI8#4L@%SVu%SJZZ$>31FO?neEFnH-NaEu^j-s}fO4J+jH`q<>B1PPl4Kq8r%B>A1f zai{)={(nNQCWh?fO zr|<&7Sx$3Wb%jBIFqi^ko)!m~=5g}@VHJg6q+EkZR;06zVq92iQDQG;7oLS`b)TU+ zjjnfkmIptt)LjYP98~MrQP7jbywS>2e#pU%vVb`Vhqa7F$uWQ{KUD7{wr-WD&nQ$F zt}XSKsR(mZ5eL|Po0c=OSA>fkZ-VU7sDhnDi@(`5{-Im%U?#DxZ)*u;oMs&{9+66s zgHqF{XSq!cPg*Tsk_)GHxiYVXdpoJWu}rM-;SXRc=uT+C!&kRxqT#Kj^F)>I%8)7d zm8@U)gs%V*7_@Awv5**8Z!o;HHo3wF(93^F|Aa#vKs$jZMHI{eyG9W#JK0#=%Fr>| zAH=8=rpo0h{az8703Fi#bn>9fYGeaU<4fo z+M?-Xb7oo)%YES`ZN)L{Tu;J3dSb%=pKiO;V}AGG-o@yjK0CO>F;WCEj6IK1yzXEI zml$D+C()I-XLI!PknLXM?%a}~uhEC1ho7=qowQGOuH~KxD4Bl%GmJhZ*#4PduTy0% zXqsBIxQn=+Nh4kQ?JKP+V6kE6n8^;F@FtWaVUcwm*%w+!qq|{if{&K$LwJJbS+PoF z!_Eh+nDa);R&W;PQ#a3U0zO)RKLA1Rxf)IcvD4d-THHSXEAh1&Y@u4Z`90p_qHTTu za@%Jyq)S-CLs`~|1+S#2n_gr)W~xNkRC**K$ncrLSiIMD3^lPKR$or?p@w4-i#kuA z0-qn(hNsk<_f<;43*MXVwP;)$^MdY9UmSHc<2!!4thEy@KB5?2m;elX|rt;kR12=94?mIjUMAP zOg4QW=h2+RjQ$pJSf*D6<$ltKTb76jX+5MJxX*U#JdX|V+!plLGTfKBJec|xGeaJm zXqsrJ{<5c>dORc-3U3+EyV8^jLq{9(AV@Z-^UVViH33u0HA%YOPO`$84ROdpT=z!W zt05xj%Bikeh{LjBGBR!m%91CY=FE?6RS*M~8Y5;}G*PhZBRR9dXsYwi%r@AF9g0(C zgNf0!9HjYKcDaSf{NeqaRGk7J^fs(-{#Qw|50N>=otYS0HDr&g2%J9Fnx?m9mjEr; zKyr+bcob-gDo4?X&JokwI(!rAA?O(Pc!sP|`G)+1L$mQBof3flz4^@q@+_xB6y$7J zl2$qbC-$hc>r(+3V|10+fG_ikGS47r9}YsZUWSSUQt7z~y!Mu!h~2FH-d-gUaGBOK zI`%oO&W&ZK-eOq%b^>pGf^^2@9JVX`o7~_PkTvusM)J{F)wEraBlmXbRfhT0{AK`I z-!2**CYNAtON9@tv@B{AJSWHS9ePnilhnQfAxrWQkl-gum=t=kK*z66Q7(M*M%8jH z%R*ElJFvGBOsN*vCDg>qDE(}>7u*qQrZUPTnIcC%7|<0PK)2SJp`_dLJN);y#t^|u zn|Gu~8uqt+g47@QA(kT)n$%oQpCZa3&w(9@Fh9f*Zum4O{w% z;;7-1J8)V@84Inu%($l(UhDej9k?!_lhP@$G`@Td_Va%I(+Iy}QBJffXT2wy99+UF zsz?JMP&=Ve?2bakv0D}0G>HXHdGrX?IziVP%^jjceWy?q!8+A7=L!%&A56SrHM9&0 zl3UT|L%D=uV~dwAUk_7j#sU_wp$}tGO1G21#|`R)$H@@ z;lO?X1(A?oKhb=ZO*%DCc{BqE0StHo(^#{hl7om5=q?{KL$N@8tL)Lb(_9Wc-<)Fob6JDKd z?^EL=JS+VT<4mX`c*h%urcs`z^N(bBxMC>9Qp%)pG^WZCQJn$Gobde&gTx;wY@C60 zxy4dHTjI6Fx7nn31_`#fBqQ&t@WRqj$Ui|0%9gf`%O~Zt?>`lsxr{5u$dQ%0 zx1OA$`6v(cXKa9X*VjYZeBL#!qXUqmku zPL#k85!YCT3@nFG8(o+}j3Oe!)vkg9a|(_>ASf>HHA%qGeq+e6xm#-gA{i%Qin8f*G*!VAOR`Bly{6&{#s?qMH^)GH&P^Du_aFb$f5S1zN$R@JJ8ro9m6k=!1e8=?Jg>Qqy_%Hf7s3;6)Dh z=Qb#9p9=7+0>>h7E)VU7Sb?km!>dB}uU7>pQ3B!O<`nI{$lqyY*jQW0AAsS2)@uAu z{2|2&Shva(_j+DcoRI@4Dr`6lTzAt_yA^85k4QBYhe#9%RJjScBa=0bQg2AYPnMjF zvMlgDl-Z)(RQW3hLEE?c#(#DlS+FU+&J`lahDpLk3sg91pb|7j-Ne61SD>;zka&Zq zm$v3K1|I9z4d3)!hX}vd7RmoS;xmw(_m-M8krZ_bxBLtNa{WH}MSHZ(!9=bhpgaDw zZRjpU*69sONb0@3uE<}oH}>uImFwa1Y#txVKJWa&^hpKmI#~tsi_D zOKpL;&rA^S`xVZa5T*$`j8-27IWSwC{>mv=8$aDz^+iCMcK;;wxFvRmIiA4QXCQpDaY}!G^hp-#`q#Y5y;gC0FC_f=u zlPn$-v%BA6wgS#Y2-y67_lr%x6CKCs3G`8*U6SinzZE+l^Vtj0T1FAvfXZwFUi}txH8QiGXsoL-_^E$5FG~n??LUN{{}|KN#6T zO+__B%BLbZ@}j&~MUN1Kd?>!1zk27d@zYC?u*~>~&@ybPCm!!PiT`8Zs`t-OqF|S} zPx5w^g-2P~tYXblliPiCvm0df(DyYi$pl)sS(chRv;q1Ck-k;B8M3#zti;f~jt z@@PD8xb+{v1wA+dixUkTfdvHt4F?Ge1%LtvVEq$;1r37+4#8rB#UlO0!paU*#u3KE zCgTthB^NWMbV~SF22Dr^h>zfr>s1&vkqHy$%x>jf^LmaM60%egD_e7#VoVG;W8>|* zqiw^whg&)!eDpfl*{yzO#Z0HV>0qQo{T%cinKJdU=Z#F8I+Qw0J5PI)mLj%q-wAw) z0rOG)MsPQX?`Nyk{=WI?VuM#E8=^rnT&%=mBQEsEMP0ifI3^3}qP9U@@uFx!>`4v2 zbk4=i$pslPBuimnVr$&$o)nQ(REzbYSwd^vrn>gU7A|~v&bqEmiNSgXgx8badJxp4 zJ>!qXT6;t>Z`)1G6ds$JBI%7#5%h_k9tyNdR(PNVR=+ITy}emX!p62U795 zM66??@Z~c%n6cXQdu=>pRaFlw+_FZM-5wHPhGs{T18d{IPr2m74(d>;UsPcoj_U?cPs;H^i8*FRcAKrB1=Uz#>Xj* zoE(BG&mvzdtx(;Yy+W|`{QpXC=&$sKNp7X-?lJh0qbA2?>)UhHX&9#6EfSYfPtt^; z79q<6b|3yjh+Kb#*l1RD-Y9gfH0c4)CsGKk`S33Z8vK=DSNql{13ID72~d%lyfbhS zdkO#0N-8e>NTr$#ycJkfq(*dJA`p74JNHCv!B@AeN9T?4O1xThWrz=azZe7%9z1^+EGo-qn^-d{$SNrTJGuuUZYME7aa@9;)JZ(<-1kAAi(jg2Gdgddm^&z(CX{{~L;7TC5IT19E;a6pj8J&|USY-=JzA-sECEIeCcdN_h;b+eZ~E4ptm^Vx|NsjPoFyW&HlS?N8+@HZpooFP1F zSl-}w2~w0Qt}krV;p>i@{l(G|5{tchgxZgmFezdht2+50eJ^14J#W}9?J_$%k=_8)k+nyVRQew~Q&F=icqwTq=X%B7kK5{?s1Y7k=~TKKIkJD%+-t#g4G^&5uqr@*q9@>Y<|sHe zz8^pA*S2)fXy|mL9M%5{9PWG4S0~TnBk;;J@Y6jsR9#wlK3aJDeSP^3R47-#Yo_j{%W?rwh`H-ZYVeaZJK(nwekV{igcgP!FswRKQ!1v zu*QPYPVEK~Rjc!94OTW6Sl0Vtix$DFY^oo1K(ZpLcv#6pE!OS%Y*S2{D1984^1Wc5 z{JUCjxUk~Gr)zjjB#aWM8mJu!&~6Pze*U-LS8kYum%Dq0{qxgfgDt%J{eA~V2bsdM z)Y>D^1Sz=}gN0DN>B}7XIJ}_*ubNrX9AM8gwmNTC6n2>cQ|Wn`?IQ2lVjI#ccuf8? z@3myDr+mK0f@zS_ioyvDXBHB{>uO;0QvZZL)pvjwX)0+%G5Tnn;HJ^R*Mzm#5oFo; ziAv@Z@cnbH#a1|cRgA7HloCqt0km2^x@c!2-=(OvScj$eaSlC4Dq2@PfNkHO$(C3 z5fZwdh~mfj1MZ(8Zyl8{#+Aq|%#1WJ zTDtR~8f$tHT@>DV@6})fkeg&ie&P`d^_zdwDY@L>Lq_UtZO?-)MF|(;N7t*7i)U86Jb` zTv~#r&8?=^C8($LL1WoQ2m*fgj3FvNi3p#k9jA_Jl0D=28CvY8Zl%IJ^mhm1G_o9L+b`ZO zsREn&1mSuihjP4mm(HL5}(0?X$mJ5kX8u{`_JrecCzqt`C(I_KsMi=Lm_T)p#l z@74-{Gm!m%{z$&XF%#AWtSd3|IZLpy$54Vuh=9VK%ojE{g<-Xq*jF;?pw<& zZZdE4%WVzq?X6=9udCyRjxf%|)3cCFGHS=N#~<&#U)Ppi6S-Y@HHq-`OOhy4yK0`1 zm6{3sbHk_YGHmmgTHJ;{aUOwkx6AkTGXZ&^95*9VLyrD!b3+1vMye+Q{og2Fd!DeD(O@ z#GMAiLz^bdVqMU^w-moue{+t$XpPoCtO!aqxe_LeP&jXIO@R0lCffc{Vl>=Io)*( z(P^-Lj8J8L>m46P?LK*cXwaeS&_Vq@udb{1e>{p}yWT14`y?n`a21oyDPa0&-NOFs zQ*`F%y$(C(=HLVU$?k3n0$m0S^&1Xe)RP+d0{~A;h0wtBP)Hb9L>MUOe`cis2mmA$ z8Y&nSLf=m7gYJljwf5 zhXXsg2_7$JR1ZPn|G!@AowaipoK|iZUM<0g zjesU`D(WF(hOwD9jsl;?Od?JfGQ@aO84;L}Wxhaa)jR{oS9llrQ429V6qEz_E?U|Q z(N6nC3ogk4UgAih7E8$#3yrMChJ3&n$C75*alzK7YL^*MgN1Y~;mnPpqR9;R1bIs+Y5cWOst;kSP>7p`vlaQ~{h=U6SwboDT z9Ha0wE&jR!4{#?i6)O5$1Xb6RJBYIy@@fP>RyXgm`3a%K`bId2iH<%18(^NJ_~V`n z^Io`ce!l)+Pl;|atA6?yYb5xq%t8`hw0t3Zt}%_^2BU-DQw*PpB@vo1ZMn``1lFb@ zh?ZG+(4B3b^5s(w6e05q0;~s2Y1iwuW05vsVw7zCr0pF8l3q;G{fge`3p)(ZnhlVa z4c8W`y>XeQRmyh@m!BoY@j~|2c9yOc;%ne15(*x;;aB#sf`-)^j2rL?8WC{wmXXcb zh~F<^uvuV{kKJ^B2Gjufeq=6~nS{L;y)ma2|Ag@-A6D7qe#T#$eQFynPwbZ3K-V2h zpl&e63L}}%uLUqFeKwSHmu=|BiquxXv(U6&L4b+SRtp-ob{MCru^M7(Hf=W(^WaDV zrxbK<8MEbI5_P2Rg&es3P7iH3xWwD4GvLPPflEczZufHAmdxbgi z+B2{qv_Fy`DZLbRREKYdgniZ-C4A1ch zU1-#JBel800)sTv7%#R!jz&xKBVv#=(eC`~vF_?x&zD&k!$qw8pu!i~=wmwOl=5EH zB5&E)|9uMnl`Exus2lBZi8CxIPo%Gc*rcKis?FD%ci>Ca+E)GTHhXb=RJX`#fG9+)YDz z!=}8$C0#~XWK1rIO{0t|0*xw6ikeT#J{XwEzlsjH$lBC*HI(^K39@ne`^a=)oiZ@edc`tiBOeM3p#bohJrt9Gr#uNH&dF~6A5IC*KH%{hEw)7uy~+GHtg zVrRNfd`wElk?XH#ZoP*9z?`RbzBQPKrkjE{D!iEoU_JEnm80WKqE3 zhsMPw{D{6N5XM9+#S#98YwK~Bfa9=(;=5)K_7QShYYui}|3ZVJHGV{2`ClPsdC1{Y z$(Mrp1+PD$iu(|xh)3JLpVPQlZ^9pPiGf}Q(ZW**POxh^e+W^I?t~w;Z_U4@6MQB~ zB0Xx4j7Chzju8gPf1n`D2cf6ycfhz{Ed=K4R?`pf^9If&_1h0 zQ~e~eGB}rTElFg?*0Rf_q@StzYQ|P&K-{j~8+~$|tYeF;y=?7G3-k34AnM?&(Vf29 z~%e(~sow#P{}S4R?r z$V3=)|KtanXDljM@WgN|I#z@H6Dl@F$VJv^Z{JHbU%$SiT7b|GKe^Z*lnLjyf)^$* ze-t7U&KTHug(5QqKP$4i*pmOX%N1#;GaKZ_&tJTK6EA4=9n+B z#Pbey+X&?jD?_*!?=N%L(XeL`-IeedE&Mm-0Ja?Y&>)au^p5nR<*0&Ns3L(zhr`^+ zPY0(o^)d>c8UEPM1jz}2iN((aL)ZNQhzn2DnR5jW!7wJweJOZ4deN$ldvd% z84!7Z`7n+7|9Xl8?K%r_MWTv>b2Q{A5yT+WdGH6IN%D({`O)MLpz+^@kLzYQ;wG=? z1qwIk{0R}RH~sz*egE1~fPjVsK*4-~hWOXm4H^vU1_OXaMFXN^V6w1dVUx0P2rGYL zr4xUd(LF%mnW_6V06rl^(I|BHM8M9ON(0OZZ zw%h#dp6cK{J$)(NWi#{M7N0I1oyHz>J1HlM46(omdCTc9-wpTd(i09$ zNOs2*5`iyG#7!wdO*p`&6tyk*!*|b&8#$N;G;E^9BCb2a)^P|Zq9IinDYui5{T^?0WGBxO>`Em}0X3DYC7tC1IYFYle z(6nq@19>^_ggU6YM|Gb>zwRaS3@FXXK(Y@PSE+|jx9x_Kada}vYfEs@Q zDm61%eplGyUpx17&*bsS74i}E_4a4nLW5?hjv6^>iW3*d&&`vh=9kz;j5wZ`l|$jt z>50#F)>>)NwF?tT9{PZaX*aOGCOT!la5^2*mDG`0gq|}BIxLfd*nGoOUL<9c zbv0?g?NhBR1|Au`Yq7)75m1Y3%$fF6N4zUh>1171Vs!WCJ(yZSZzeV?&9WLD|!cQk@3N5yA!LvX8%>3kPsoHU_A z*DSS}>50FBTSe|~tHjQ!u>*~?yEltZq!W+DX$3Ou^tV1q#K_e1@D+|GGacPj#(KhQ zqkit+Ok?>OAQvf+ZjlTwL+`h^w7@gj{t=O*EY& z4mv-!kny!+!z!frdtXyCYaSil4G9SP9?@^{dJ^{>2dHP? zR(SQ=@g74hbAM1;?$LES%Q(P0oA5OQ6*qQz5=cVOKGsigj5$zBpK_4Z*eOVevdg@R zxq3bJ&wy$nhCaX0vqe{H9)DG+->)X4#PUaaUakh$Xx{Gjz;72{VtI2Y)-?62Vd$0Fos^iH{g>KMorU%iiJbaKM!D5Fb3F~A+S9$RsN9hd z+n*pKT=YxW-VtzO*S!pI+Ub>@F1p0(uv)U?1_{9Th5a>zmNokSGK5|N$@*W^Uh@&e z&gR->GpZwx&rsCcn~xamnlCf^Zn_^4yJ)F60!kT#8o)gy6G>V#GJT+owVChlFw5%UlQn@z7Qtnh1|<>2ukCZCE68d@rDn z4MlPfHms%k5G6h@B>Va43NQVhA^k&#+a6h#Dnc?tD)#WB0`)o4%;8$yB%UgL)G3oA zJK3BOvdUxBcGGz)Auuo0XvkOTapf4Z0%-)a#&w=(qz4JM>0ZJGjI1QwQZQazE2v)m zSpp7YmDVg#@L;PvGZou;wbR|_DI>9Jo#Ox{y*mr{EB}J{c#$2e6oE&%k61Jt>rIrT z^n6^vLM9(`yvgVvz+q8vUo#p@`4{10v8bq=1@~<3OpKsxi>5GELJFf^1RN)pJCo|0 z7&`vK7JD6LFd{muIoe@pmgjtGws^>h4Y`^&Flgh+LPN5!ax-DDS|03206aCJGAOg$ z9O9_h_?8W;O+e)3noPc3=bF>0v`COWZChQNj(^HJ<0G+kNlb1|wm2xqZb|#Yz_g9w z)jk}_szB>@mrNt5RbN80k`AV0rJIVsDw=wWgjKQl66oFRIU(t~4+iG=ZC)(MM>jxi z`D(5Jt-|7!X0sRhj~oWPK<*cHYUWcAUyQ{?;v_(+RYMv`x*Jm-Mz96z3R9t^wiXFj z`;9S0o3b~k!!IXMR3sQC+~b*l`>%G`+88r}c>Z&;8>6g#St5Pg-{tN>J6cE3@(eX; zPz;JfO$X9}htog57XSX#(GpRjE_-t8lp7T>>5ijaGbNa9GNf~+@y6MJ*{RCM&rf2S zJ<6M0t+6jw-w;9cFhIIA16_n~?BE)fWmA^8s8AkIrXP3wE1D%H;XZH9>T9Hd@$pdr zC|O{}JI2h+OnVlmxl#HVn?6yuGOnhaYEbfsWei$ngji3LZQ5ZJ^V6sChB?4PDwz}v zqZ;Ug;i{pAkG%PnEdT9zgG|k$9A<=#rp79|cFvP+(JZ%ltILOoa>^h*SuuJFPyV7c zDke=uT{1Ekg|Gs97~2sB)&6HGrYk%K-Zq> znhLf>ODW_T9ddel3HYqWNqXJq3F9?>sEj#tJYvLU0jYw%|zYRUir8~$++-)D8M*WlNiz);jY>+s%E|N z>DZ}y$O8{gTD_+J0AM5}PRC!c#ikM&u5yj%Uq)Rs^@Y84K>@k<#j2fnW~mkas^yv2 zuQ^Y@6@C251p3tSb}Qx_mrvU+*tZ^eu3uxo6%y`R?1?pR!{6PU(OP%+K72R5lKqsmCR{)xUu)dZkXHvg7h;oC#Hpv$sH_hc@lqOZGMc6 z?wacSY9+fia1S`Q0tv=UZHoR1yALsi9_|pW)Rx0;eW3JT5M!p2e4J^$4kV zc08;a^=Oh@rRBl5o_V$~^EyKuB^6p#s*@_VZkc`6BI!snjt86945Re*D--Eus@uLs z+@ZM(l~nRBD<`y(1R3;~yI`AnL0b%ZWb#b|8<|vSlUN=U^4BXmU!c<7z%X z?%CZ`CD}`2mnq^7^|^1Uz=pT#Fq&Sa4jb}bZ&F7Rbl!v_-}f;C_|ej~36RDONSEdc z)63ZEoBaC)p81T+%X34@vxesSP}@c_HMZt@>COGx{<;DuQDxr8Udo?XYH2RNd0yJA zq;(n_zGRh>Uj<1#ERDA`h85#Qrzre5Vyx60a|LRcQ+;%}x3k4Zv8bnSDcwLQ*F(p< zgCX+kxA8%1iT60uXVYud{k9_&Z2SPst&bMd$BS7S2_Di3@rb`lGENP;1x zOB@@;CGU?#d z{T7=viWw{Fn6ySuxW=KgseC)T+xiDUT3EcIG}EZ*)9zXyR%yLgt0h0Y@+p}k#mI7p zPiU-9$ttC9=9*pYUCA>592?8d;Gg#aJdte&WgiFCJ69DI*U3&cz)TW(uYqGvHEbMe z>TySwR`441M!U!twnFKsvECcBu$-NR>?Dq(UrU)M!Or`mT*tFJ|R={uh5Nn6vFj$Rxsm7+sM zeI^BOS8V5cS##dG+*+&7Br%UX-D}R^9V@Hr^T=Lbp{ZX*^eYwfROD+L!S7Nsa_?GJ z?+1Bt$%lIn-ZM=gu-DBJ2d9kaTeW|)4=`EK`e{OKIUa=OD^drVN=#&*4a%#wS&s0W zjYd}20@w?%gOfbfIZNx-lOE;{vylc7Yt0~tfpxzP=LpF zHt5=j0D4$*1YDKi$WOTSkOI{QPAd}TM5hQB}A)j1;A$TyZAS$cbg2xGnV7ftz^5iw zKjH-Hk3J(`$MvL90A71adzZ@)h%ZgxsQcOJYCg1K$plYtF#PT1UYb8CT4eOBh5LDV zp8owhu=s}na2~jp?UG-PmlzmW-X}lw@~fg?bE~{~KiV~}F3NChw(fs!M5>c84@o=Z zuueS$CFe>3i&_SB>}!cJH!akuF+M4!D0y=>nIwn^eA|L0=KDk`WXHfARpZy=Z@7As zdWZOhqP4UZKTzHJ%M|i%JbT-59gd6Ji_j&}FT zFT1|Bb$sTvp=N4&M+49$3WO}b8oc9IYqKJ1$+CvEN%%KkNmop(x;4G3?{p3t*beYM zR&(N3^r!Kq5W9(siz_u5(*F8O1XqCpP@jV1x&Sdhtc?*w5wBS3fz#Za`YXm4yu1%{C;K7E_4JwWAQeduPZDwF62*>o4ULj_eP^q9 zyK?Jh=oxJUM$mO{iB=q{!l4^~ZM|IKVHj>2)spWo=~G}`8qzUsZNT!UY?kfi_9#)g zu18C<2zMOI+P%c`~_RU z>P>%VbIcQvjQ_LxPCL_op_<$FyQ^Jl#S3F@Pd0X4Mjt#`-C0&YI+XU#bKLm*$fwI8 zO?dGn)7=-wS|%lAqlTq?9YzxBq4wFt6;6Iwrnd#tx00We3U-xwrf>MxppWe6--BIP zsd&+{tD+k7&e!g3!HIbFl!*-W4j*tLAQX)C$;J86qM?-~h96Ao&{Zw+Y~;vfjO0Hw z4Vn?Xhy?@Ggr!71(W?^Sple_Up^D-@glY?w4P} zb(<5<)|OVGRM3m~em3<*^Zjfz-6Fu6ZX+>n&+Iu??Cm$)I0b{-)PWb#B>uYPLPEg6 zBSJ%efcP)BTr_lO@D8X71{s@(s+x&&!vZ;ru&A<2U}8aG;{d68(jaC~(LM~jv1vkb zlbG4R*VO*m1yn zNUS(Z?+ZH40x;@vlM?YXtv~)&tTU1|*va`ywlU6%4pg`DV&<&#(|*wo{mEH`4M(W~ zqKu8z!*uGZc`EP06_S9ltD;djxWG9S5N#a1n>=DO(X*{4M&+@S^Fyj~**@|CCXH#@ z;Uwm8e)3f}8DKbzHE(Dlu*5y}zdwLoJLiM3Fr_?@UIqv}b4aS85C_!qMwE?V23>q9 z%Kmiz% zBI#^-ld_G?4{6`$Ijs)=Iz5$nKCem4+vK%KFsg7niRqqZ8bibV3{#%eiWqL2#kV0M zwn?u_Yqm`DEjOCDNo!kq9ij+B*#wuA7sJO$1=DU)LulJtPnXYf4%@EMq3W?2|KdvEj*4U($6&Z7v{_58Y$(b@ z)+l{o$2Wng6ZmVsK~>}u(|;;A;DYquY$pE)oBap~UAeOKOgiHB9;z8$HAOPD@_n|a zf@54viUUSj(HB@XF5Vw6hq9?;ta6>dEpuY=2K0!N$4L&5F$EB4leM3!|MuDKOL+)u zrQQ`{zSa+|<7C?{-?|n(Bqo3Bx*AerBXP)jpcK0Sj%N6)3}t{~crJY(8K=b8r4*Vq zMTCA^rc_na6r-6kFzOfS|MEcGzI<8}`Xyn@0&!zzbbPLLhRFEY-Oa>l(gDd_xjV)| zCxy#iJc5%3ps9eF*9m)Fok?zmZQ3jh&`;LK$=vuHS?lGY#reCiL*Ylxmc{Ruxe`A^ zqv8{S^CPO?a6Nb(Y`?2=1j7HDy%!slb|a1e3sfrDm`hSyvV0x0VFCo(_Ud5jm{Kt-w59*5 zb$tA)=pg4S#r0R~!s}0tC)Vj7RD4C-nL?FRunVjrC%GCUp>4^E->E*;nD6`GXBW)h zCR_=s&El_r{qpY9N4HLD&- z>9G{s7#}1`TnT;4`L@TGd2UE&f55~=pnWluj645w?){Qq=vp7)4w*E2N}{=VJ|dfN&_(5b&gH(HuQ`=r};x=%Hpvku^QPCjsP z9yZA4D`vLGK*Ce%F(l63ob@2^>=LG0yJ!G_XgLOsHOWY+_m9(Kx zadThtSgElE4ez>^mgPOsR(O;Qo9_;z`efN9Qn2VR7h+FQr=ssQH}=+Xr!V6qwx^4I z%*>0fE(8}m9c=HLD_!}&B{y0^6X#m{wN46O!@lHFD#S5sp-QjAV|+oX*1iJPXtO+d zD{@E4Cnpan;k*Y83#4i-HreSa`A4A3)aA8vkhA z9{_qgfn+7QSJy&IdniGY3~&y4@_>!@X?>xI7MdtTtx*xj7gyE6e@k>dHr1OB2>%~K z=w3_oSN?Dh@8QjC(Z<)s5_4-4^Smytgtjah@EqIM{gbwNlGpJ6RsV z7=d*CffvhMaFR9W8j^6R+ss?_(D9W(Yx|*UUfXKeSw^m0v+M?+VA3=F=6o6542*r3! zspTVpk5SNQ)%dCjFNF^Dcz_ygSp8%yS5T> z#_YE$<<6e#kZAmv3a9~c&||DQj~KnuCuqrGRNed}PImnds>RVr&23V8Xwrr#oXQ+} zWhOId^0^9w^$p3t!1fkVt5!?|QfcJP#sVh+VPn%Cw-vB*NGHltx9mszf0^ z`4PE92Kzi8zMeFA6iIR}8C{ker+$3}4bJyRh@-lu978n1=6GmajpfQaNlGEZq)rwU z0A6)^UK#*-l+^N$lj^_tdxe0!vSlR@+A*%)6##~-UY36$C-`5LU1>NJY}+2$daa3J z9!trLWsqv@j3t?2EMbVoIzsj>#A68+VT>`Dq>^Pu4Tdab>&Z?=v`CZe4U)0TGI`NA zy~q3g|Gt0casRuH`@HV!Jns8G&Xb&)Xe8_)t2<+f+(eE9E8TYxBAcD@>C*M#SkMX& zI!HmY8?|fzTrcyGetZe8SASt6a~|S}{V%Z>f%z})W&f&X#8K0W-a&oGZ;GV;0F4$? zxYm;+9i5_RE-B zj&jqfkP zX(b)A#Ga`oyt(VkO7Ot&R4jpEqyg~bmbhn|`4u^zhuQ*ty@ab&=*-C;FS!Z% zP00}ekL^c<-zClw7}6GmMI#NkEX_maIqI)%cMD0MBlki%Th}}bugJ~G#fs0KW*2WH zzF&W0Iy3~q!Y7WYC;h5$5~;fAh7Miqgo6mVM(@4rt-RR;kU5&6U;FRV0_N)R90FEBWm}huS0^1RH!+Ql>)Dd)-k!nz{Y;?mU(Ll;)4vng|hhX?kp*8nw^rGH;-=Q$fz7Eixxn6FY7;?n1! zm$H@(k^hEWjORKKGudEUuQg4RE_`cd4t}@vVkbsc=hpmfsmncRcPFz*EdGT!vvt9E zE?GtDxNenpqnuf3#(ZCM7ncyZG~Wy=lvkdOC8-YD_GM7L+vjB7M_8(NFCdGL5zn0^ z64xST;(HL4;0p_A>WxmOB>xq}@pQ0;qbbH!~>^>dJ{hCjTp0>F9>XOOg#lj0>ED3 zQg6vafv^X(s~S%o`=MZ%JfCx9f;dH`LSXp7pl!wbLPr6CUrh?RJYtcx=#()0Pw5YT z;=qn6cT*{%L}~Kv0N<}oS*1l9X5@1sZ9K0ZrSK%Ly>W}c{;dBaM}I>mv#Etj~Ewh%m_!Gu$?c;G*lAl z5J{~Ru37T3f$LLxXYa7|yFrP1=M2m|LWB#+!QbKi@t~LE) zT$LN_07xkKqJP@Erg4`+@7Mtz{RWgb^=*HFc5IN_i|PmX6=OsL%Q~F?dGabyo0K6f zWbg^Nev9bERIsIIcD1_hNlv&ck(!V2!wl8M$ldw1K zyMH;vvYbH(K&4iD3#u&ESFeY5 z71fX|XPe^lh4z-i#NHdJ6zi00Ewnsf(eo^XsqBo$uy5`gwHfhp-s`Qct-w4pWrKy| z+$CXc^fQ_`S9D5C^JNY^0vC5)U^NSRB&W~Uu7nMJD1)s2$?p}VGjoHYGo5hTsTi15 z>Et!(wkn>i3*SrYX!rHa9@Sn*a7J*$FPew=pzSqsB{tm#L^F*=lvHq^OG_Y&@Y|7M zm@AvWKC0N>vwm;9Bd{hR9^|QiwN2ME51#*cyRCX48itr^MYbiq@% z4=(ktY`;>~lh<4L4M>(EjXNvOgJjnU_Ow^~;Zu(PnwLCg2=hFuEAv*Eo)9TF5%)&8 z)l=H8&gLB`@V>7g{P)P1E4R;-k?^KHnw;5;Lgs3g>Rk#NIcqldK_My5h3%)}*DeDM_3+e-(|7+*K~X1G(iFaCtRA?39O|vA6_50Zd_Fh{38*N_DdmOK zmxU-ebBi`(p9y6AXGNWwMpMF`-+6K#>Otm3kO9Se7@)*Ee;aQAh!h^&^zaQtq*Mst zxk}E)BlFCDxf9j>OzRZ(*Mh|@4~~DrEd7wcc<4oT9FN{X4-y0#;dg}qs!VunMV`J^ zK|kMtfQx7zQ^ZnIZv{~aaS}nl1L(?`vp>7!=DKg0bmTauLxEE*1<=0>7&Euu$j+ND2K8G0TYxmgMx(@$vZ8xZ1?{SGOusNl(auW*Aqp5YVDJ+06E1ch!KR^K@QHMe!ZO+s%u-(u8yt=7~Xu>#Gz zG1hB0!u&;y>+J`bP^S8pmF!(-PP+CDPR6O~ScgYQ;mgFR|K*It14@*i)Um}04*kU2 z8_uzmlYH3@mhEi0By+~)a%bD0<3k9#+l~NX&fy@)1aGl9)KWaxfEzF4LDsZELHBzD zwz`tKL-(roRVBqSCtctt>sesRcKE^84P$=J^r$baw0)wpAylw`A6YmB;nT2TWNt6q`#w zbji@}RbsG|ibh~gY#7({&YjEO#bll;Ak~c4C(u?LX%uTFiUmTb-3}Vx&)z$sTTWLE zz({#C$(7?!nm8>&?F27MXAPwnc0SPE@EqFaxp3WGd2XL1UB1*~Y*L|Xad|~7dV$Vy zbP$z>%hvwU8K=~WPpSF;S6aNQEdjpE9uCU?hE7zqOG9l`8UvMkblzKUH2be^y8jp& zbC771OK}nw)19PaBi-tbjGh$wS@7`7cC0f?gaQ@E#vY0K`GKBBT^l>z`6{-Xat;i` z-hwr^^5L^=@N3$Nr7jJ9y-uOal1a*MD(gUzn!@E~>N?MZHOw!oj7G@~qZOVq@^E@^gVoL`1~+`zrg4GH=q zhUR8rZV6ybF}5Kn|Ijy1xVyqnCbXR|s(F&j6nTT2I&B@6U)Momn zl~40vbNl+;CPGgwrXWGeRz#vo^va=%#z!&v-QX>;r?CzDmF&wICs&t^gjb+HbyAlu zMj$fEW+#&V8gGY(KVE`c>Cwx4@n%%k0e}1*(>b4BUJnY1Zgl-#TGDp0Kkn<2!w5~g zvI66hkuJCqL^qCJr{ynR-v56Ayn?5WKTl%wvo~rR^I$L2G3XIr$!y>eANg-P#SqaU fgzs%Vr*-jYG(YMS<ttdtee# literal 0 HcmV?d00001 diff --git a/docs/static/img/docusaurus.png b/docs/static/img/docusaurus.png new file mode 100644 index 0000000000000000000000000000000000000000..f458149e3c8f53335f28fbc162ae67f55575c881 GIT binary patch literal 5142 zcma)=cTf{R(}xj7f`AaDml%oxrAm_`5IRVc-jPtHML-0kDIiip57LWD@4bW~(nB|) z34|^sbOZqj<;8ct`Tl-)=Jw`pZtiw=e$UR_Mn2b8rM$y@hlq%XQe90+?|Mf68-Ux_ zzTBiDn~3P%oVt>{f$z+YC7A)8ak`PktoIXDkpXod+*gQW4fxTWh!EyR9`L|fi4YlH z{IyM;2-~t3s~J-KF~r-Z)FWquQCfG*TQy6w*9#k2zUWV-+tCNvjrtl9(o}V>-)N!) ziZgEgV>EG+b(j@ex!dx5@@nGZim*UfFe<+e;(xL|j-Pxg(PCsTL~f^br)4{n5?OU@ z*pjt{4tG{qBcDSa3;yKlopENd6Yth=+h9)*lkjQ0NwgOOP+5Xf?SEh$x6@l@ZoHoYGc5~d2>pO43s3R|*yZw9yX^kEyUV2Zw1%J4o`X!BX>CwJ zI8rh1-NLH^x1LnaPGki_t#4PEz$ad+hO^$MZ2 ziwt&AR}7_yq-9Pfn}k3`k~dKCbOsHjvWjnLsP1{)rzE8ERxayy?~{Qz zHneZ2gWT3P|H)fmp>vA78a{0&2kk3H1j|n59y{z@$?jmk9yptqCO%* zD2!3GHNEgPX=&Ibw?oU1>RSxw3;hhbOV77-BiL%qQb1(4J|k=Y{dani#g>=Mr?Uyd z)1v~ZXO_LT-*RcG%;i|Wy)MvnBrshlQoPxoO*82pKnFSGNKWrb?$S$4x+24tUdpb= zr$c3K25wQNUku5VG@A=`$K7%?N*K+NUJ(%%)m0Vhwis*iokN#atyu(BbK?+J+=H z!kaHkFGk+qz`uVgAc600d#i}WSs|mtlkuwPvFp) z1{Z%nt|NwDEKj1(dhQ}GRvIj4W?ipD76jZI!PGjd&~AXwLK*98QMwN&+dQN1ML(6< z@+{1`=aIc z9Buqm97vy3RML|NsM@A>Nw2=sY_3Ckk|s;tdn>rf-@Ke1m!%F(9(3>V%L?w#O&>yn z(*VIm;%bgezYB;xRq4?rY})aTRm>+RL&*%2-B%m; zLtxLTBS=G!bC$q;FQ|K3{nrj1fUp`43Qs&V!b%rTVfxlDGsIt3}n4p;1%Llj5ePpI^R} zl$Jhx@E}aetLO!;q+JH@hmelqg-f}8U=XnQ+~$9RHGUDOoR*fR{io*)KtYig%OR|08ygwX%UqtW81b@z0*`csGluzh_lBP=ls#1bwW4^BTl)hd|IIfa zhg|*M%$yt@AP{JD8y!7kCtTmu{`YWw7T1}Xlr;YJTU1mOdaAMD172T8Mw#UaJa1>V zQ6CD0wy9NEwUsor-+y)yc|Vv|H^WENyoa^fWWX zwJz@xTHtfdhF5>*T70(VFGX#8DU<^Z4Gez7vn&4E<1=rdNb_pj@0?Qz?}k;I6qz@| zYdWfcA4tmI@bL5JcXuoOWp?ROVe*&o-T!><4Ie9@ypDc!^X&41u(dFc$K$;Tv$c*o zT1#8mGWI8xj|Hq+)#h5JToW#jXJ73cpG-UE^tsRf4gKw>&%Z9A>q8eFGC zG@Iv(?40^HFuC_-%@u`HLx@*ReU5KC9NZ)bkS|ZWVy|_{BOnlK)(Gc+eYiFpMX>!# zG08xle)tntYZ9b!J8|4H&jaV3oO(-iFqB=d}hGKk0 z%j)johTZhTBE|B-xdinS&8MD=XE2ktMUX8z#eaqyU?jL~PXEKv!^) zeJ~h#R{@O93#A4KC`8@k8N$T3H8EV^E2 z+FWxb6opZnX-av5ojt@`l3TvSZtYLQqjps{v;ig5fDo^}{VP=L0|uiRB@4ww$Eh!CC;75L%7|4}xN+E)3K&^qwJizphcnn=#f<&Np$`Ny%S)1*YJ`#@b_n4q zi%3iZw8(I)Dzp0yY}&?<-`CzYM5Rp+@AZg?cn00DGhf=4|dBF8BO~2`M_My>pGtJwNt4OuQm+dkEVP4 z_f*)ZaG6@t4-!}fViGNd%E|2%ylnzr#x@C!CrZSitkHQ}?_;BKAIk|uW4Zv?_npjk z*f)ztC$Cj6O<_{K=dPwO)Z{I=o9z*lp?~wmeTTP^DMP*=<-CS z2FjPA5KC!wh2A)UzD-^v95}^^tT<4DG17#wa^C^Q`@f@=jLL_c3y8@>vXDJd6~KP( zurtqU1^(rnc=f5s($#IxlkpnU=ATr0jW`)TBlF5$sEwHLR_5VPTGiO?rSW9*ND`bYN*OX&?=>!@61{Z4)@E;VI9 zvz%NmR*tl>p-`xSPx$}4YcdRc{_9k)>4Jh&*TSISYu+Y!so!0JaFENVY3l1n*Fe3_ zRyPJ(CaQ-cNP^!3u-X6j&W5|vC1KU!-*8qCcT_rQN^&yqJ{C(T*`(!A=))=n%*-zp_ewRvYQoJBS7b~ zQlpFPqZXKCXUY3RT{%UFB`I-nJcW0M>1^*+v)AxD13~5#kfSkpWys^#*hu)tcd|VW zEbVTi`dbaM&U485c)8QG#2I#E#h)4Dz8zy8CLaq^W#kXdo0LH=ALhK{m_8N@Bj=Um zTmQOO*ID(;Xm}0kk`5nCInvbW9rs0pEw>zlO`ZzIGkB7e1Afs9<0Z(uS2g*BUMhp> z?XdMh^k}k<72>}p`Gxal3y7-QX&L{&Gf6-TKsE35Pv%1 z;bJcxPO+A9rPGsUs=rX(9^vydg2q`rU~otOJ37zb{Z{|)bAS!v3PQ5?l$+LkpGNJq zzXDLcS$vMy|9sIidXq$NE6A-^v@)Gs_x_3wYxF%y*_e{B6FvN-enGst&nq0z8Hl0< z*p6ZXC*su`M{y|Fv(Vih_F|83=)A6ay-v_&ph1Fqqcro{oeu99Y0*FVvRFmbFa@gs zJ*g%Gik{Sb+_zNNf?Qy7PTf@S*dTGt#O%a9WN1KVNj`q$1Qoiwd|y&_v?}bR#>fdP zSlMy2#KzRq4%?ywXh1w;U&=gKH%L~*m-l%D4Cl?*riF2~r*}ic9_{JYMAwcczTE`!Z z^KfriRf|_YcQ4b8NKi?9N7<4;PvvQQ}*4YxemKK3U-7i}ap8{T7=7`e>PN7BG-Ej;Uti2$o=4T#VPb zm1kISgGzj*b?Q^MSiLxj26ypcLY#RmTPp+1>9zDth7O?w9)onA%xqpXoKA-`Jh8cZ zGE(7763S3qHTKNOtXAUA$H;uhGv75UuBkyyD;eZxzIn6;Ye7JpRQ{-6>)ioiXj4Mr zUzfB1KxvI{ZsNj&UA`+|)~n}96q%_xKV~rs?k=#*r*7%Xs^Hm*0~x>VhuOJh<2tcb zKbO9e-w3zbekha5!N@JhQm7;_X+J!|P?WhssrMv5fnQh$v*986uWGGtS}^szWaJ*W z6fLVt?OpPMD+-_(3x8Ra^sX~PT1t5S6bfk@Jb~f-V)jHRul#Hqu;0(+ER7Z(Z4MTR z+iG>bu+BW2SNh|RAGR2-mN5D1sTcb-rLTha*@1@>P~u;|#2N{^AC1hxMQ|(sp3gTa zDO-E8Yn@S7u=a?iZ!&&Qf2KKKk7IT`HjO`U*j1~Df9Uxz$~@otSCK;)lbLSmBuIj% zPl&YEoRwsk$8~Az>>djrdtp`PX z`Pu#IITS7lw07vx>YE<4pQ!&Z^7L?{Uox`CJnGjYLh1XN^tt#zY*0}tA*a=V)rf=&-kLgD|;t1D|ORVY}8 F{0H{b<4^zq literal 0 HcmV?d00001 diff --git a/docs/static/img/favicon.ico b/docs/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c01d54bcd39a5f853428f3cd5aa0f383d963c484 GIT binary patch literal 3626 zcmb`Je@s(X6vrR`EK3%b%orErlDW({vnABqA zcfaS{d+xbU5JKp0*;0YOg+;Fl!eT)XRuapIwFLL`=imZCSon$`se`_<%@MB=M~KG+ z=EW^FL`w|Bo>*ktlaS^(fut!95`iG5u=SZ8nfDHO#GaTlH1-XG^;vsjUb^gWTVz0+ z^=WR1wv9-2oeR=_;fL0H7rNWqAzGtO(D;`~cX(RcN0w2v24Y8)6t`cS^_ghs`_ho? z{0ka~1Dgo8TfAP$r*ua?>$_V+kZ!-(TvEJ7O2f;Y#tezt$&R4 zLI}=-y@Z!grf*h3>}DUL{km4R>ya_I5Ag#{h_&?+HpKS!;$x3LC#CqUQ8&nM?X))Q zXAy2?`YL4FbC5CgJu(M&Q|>1st8XXLZ|5MgwgjP$m_2Vt0(J z&Gu7bOlkbGzGm2sh?X`){7w69Y$1#@P@7DF{ZE=4%T0NDS)iH`tiPSKpDNW)zmtn( zw;4$f>k)4$LBc>eBAaTZeCM2(iD+sHlj!qd z2GjRJ>f_Qes(+mnzdA^NH?^NB(^o-%Gmg$c8MNMq&`vm@9Ut;*&$xSD)PKH{wBCEC z4P9%NQ;n2s59ffMn8*5)5AAg4-93gBXBDX`A7S& zH-|%S3Wd%T79fk-e&l`{!?lve8_epXhE{d3Hn$Cg!t=-4D(t$cK~7f&4s?t7wr3ZP z*!SRQ-+tr|e1|hbc__J`k3S!rMy<0PHy&R`v#aJv?`Y?2{avK5sQz%=Us()jcNuZV z*$>auD4cEw>;t`+m>h?f?%VFJZj8D|Y1e_SjxG%J4{-AkFtT2+ZZS5UScS~%;dp!V>)7zi`w(xwSd*FS;Lml=f6hn#jq)2is4nkp+aTrV?)F6N z>DY#SU0IZ;*?Hu%tSj4edd~kYNHMFvS&5}#3-M;mBCOCZL3&;2obdG?qZ>rD|zC|Lu|sny76pn2xl|6sk~Hs{X9{8iBW zwiwgQt+@hi`FYMEhX2 \ No newline at end of file diff --git a/docs/static/img/undraw_docusaurus_mountain.svg b/docs/static/img/undraw_docusaurus_mountain.svg new file mode 100644 index 0000000..af961c4 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/undraw_docusaurus_react.svg b/docs/static/img/undraw_docusaurus_react.svg new file mode 100644 index 0000000..94b5cf0 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/undraw_docusaurus_tree.svg b/docs/static/img/undraw_docusaurus_tree.svg new file mode 100644 index 0000000..d9161d3 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 0000000..27bc13f --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,16 @@ +// This file is not used by "docusaurus start/build" commands. +// It is here to improve your IDE experience (type-checking, autocompletion...), +// and can also run the package.json "typecheck" script manually. +{ + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": ".", + "ignoreDeprecations": "6.0", + "strict": true, + "paths": { + "covertable": ["../typescript/src/index.ts"], + "covertable/pict": ["../typescript/src/pict/index.ts"] + } + }, + "exclude": [".docusaurus", "build"] +} diff --git a/python/covertable/criteria/greedy.py b/python/covertable/criteria/greedy.py index a1dffb0..9960fd5 100644 --- a/python/covertable/criteria/greedy.py +++ b/python/covertable/criteria/greedy.py @@ -1,43 +1,77 @@ from itertools import combinations -from ..lib import unique -def get_num_removable_pairs(indexes, incomplete, length): +def get_num_removable_pairs(indexes, incomplete, strengths, exclude=None): num = 0 - for pair in combinations(sorted(indexes), length): - key = unique(pair) - if key in incomplete: - num += 1 + arr = sorted(indexes) + for s in strengths: + if s == 2: + # Fast path for pairwise: avoid combinations overhead + length = len(arr) + for i in range(length - 1): + ai = arr[i] + for j in range(i + 1, length): + key = (ai, arr[j]) + if key in incomplete and (exclude is None or key not in exclude): + num += 1 + else: + for pair in combinations(arr, s): + if pair in incomplete and (exclude is None or pair not in exclude): + num += 1 return num def extract(ctrl): + has_constraints = bool(ctrl._constraints) while True: max_num_pairs = None efficient_pair = None + # Compute pairs already covered by current row + row_covered = set() + if ctrl.row: + for s in ctrl.all_strengths: + for p in combinations(sorted(ctrl.row.values()), s): + row_covered.add(tuple(p)) + for pair_key, pair in list(ctrl.incomplete.items()): row_size = len(ctrl.row) - if row_size == 0: - yield pair - continue if ctrl.is_filled(): break - storable = ctrl.storable(ctrl.get_candidate(pair)) - if storable is None: + # Skip pairs already covered by current row + if pair_key in row_covered: continue - if storable == 0: - ctrl.consume(pair) + # Skip pairs that failed for this row + if pair_key in ctrl.row.invalid_pairs: continue + # Fast compatibility check + compat = len(pair) if row_size == 0 else ctrl.is_compatible(pair) + if compat is None: + continue + if compat == 0: + continue + + # Full storable check if constraints exist + storable = compat + if has_constraints: + full_storable = ctrl.storable(ctrl.get_candidate(pair)) + if full_storable is None: + continue + if full_storable == 0: + continue + storable = full_storable + storable_abs = abs(storable) + num_pairs = get_num_removable_pairs( set(list(ctrl.row.values()) + list(pair)), ctrl.incomplete, - ctrl.length, + ctrl.all_strengths, + row_covered, ) if num_pairs + ctrl.tolerance > row_size * storable_abs: diff --git a/python/covertable/evaluate.py b/python/covertable/evaluate.py new file mode 100644 index 0000000..7542f21 --- /dev/null +++ b/python/covertable/evaluate.py @@ -0,0 +1,135 @@ +"""Three-valued (Kleene) constraint evaluation engine. + +Condition types (plain dicts with an ``operator`` key): + +Comparison: + {"operator": "eq"|"ne"|"gt"|"lt"|"gte"|"lte", "field": str, "value": any} + {"operator": "eq"|"ne"|"gt"|"lt"|"gte"|"lte", "field": str, "target": str} + {"operator": "in", "field": str, "values": list} + +Logical: + {"operator": "not", "condition": Condition} + {"operator": "and", "conditions": [Condition, ...]} + {"operator": "or", "conditions": [Condition, ...]} + +Custom (escape hatch): + {"operator": "custom", "keys": [str, ...], "evaluate": callable(row)->bool} + +``evaluate()`` returns ``True``, ``False``, or ``None`` (unknown/deferred). +""" + +_SENTINEL = object() + +DEFAULT_COMPARER = { + "eq": lambda a, b: a == b, + "ne": lambda a, b: a != b, + "gt": lambda a, b: a > b, + "lt": lambda a, b: a < b, + "gte": lambda a, b: a >= b, + "lte": lambda a, b: a <= b, + "in": lambda value, values: value in values, +} + + +def resolve(row, field): + """Resolve a dot-separated field path against a row dict. + + Returns ``_SENTINEL`` if any segment is missing. + """ + parts = field.split(".") + current = row + for part in parts: + if current is None or not isinstance(current, dict): + return _SENTINEL + current = current.get(part, _SENTINEL) + if current is _SENTINEL: + return _SENTINEL + return current + + +def extract_keys(condition): + """Return the set of top-level factor keys a condition depends on.""" + op = condition["operator"] + if op == "not": + return extract_keys(condition["condition"]) + if op in ("and", "or"): + keys = set() + for sub in condition["conditions"]: + keys.update(extract_keys(sub)) + return keys + if op == "custom": + return set(condition["keys"]) + # comparison / in + keys = {condition["field"].split(".")[0]} + target = condition.get("target") + if isinstance(target, str): + keys.add(target.split(".")[0]) + return keys + + +def evaluate(condition, row, comparer=None): + """Evaluate *condition* against *row* under Kleene three-valued logic. + + Returns ``True`` (satisfied), ``False`` (violated), or ``None`` (unknown). + """ + if comparer is None: + comparer = {} + op = condition["operator"] + + # -- logical -- + if op == "not": + r = evaluate(condition["condition"], row, comparer) + if r is None: + return None + return not r + + if op == "and": + has_unknown = False + for sub in condition["conditions"]: + r = evaluate(sub, row, comparer) + if r is False: + return False + if r is None: + has_unknown = True + return None if has_unknown else True + + if op == "or": + has_unknown = False + for sub in condition["conditions"]: + r = evaluate(sub, row, comparer) + if r is True: + return True + if r is None: + has_unknown = True + return None if has_unknown else False + + # -- custom -- + if op == "custom": + for k in condition["keys"]: + if resolve(row, k) is _SENTINEL: + return None + return condition["evaluate"](row) + + # -- in -- + if op == "in": + v = resolve(row, condition["field"]) + if v is _SENTINEL: + return None + fn = comparer.get("in", DEFAULT_COMPARER["in"]) + return fn(v, condition["values"]) + + # -- comparison -- + v = resolve(row, condition["field"]) + if v is _SENTINEL: + return None + + target = condition.get("target") + if target is not None: + t = resolve(row, target) + if t is _SENTINEL: + return None + else: + t = condition["value"] + + fn = comparer.get(op, DEFAULT_COMPARER[op]) + return fn(v, t) diff --git a/python/covertable/lib.py b/python/covertable/lib.py index 41795f2..09e339a 100644 --- a/python/covertable/lib.py +++ b/python/covertable/lib.py @@ -1,7 +1,3 @@ -from functools import reduce -from operator import mul - - def get_items(container): if isinstance(container, list): return list(enumerate(container)) @@ -9,26 +5,3 @@ def get_items(container): return list(container.items()) else: raise TypeError("factors must be list or dict.") - - -def prime_generator(): - yield 2 - cand = 3 - while True: - is_prime = True - i = 3 - while i * i <= cand: - if cand % i == 0: - is_prime = False - break - i += 2 - if is_prime: - yield cand - cand += 2 - - -def unique(pair): - total = reduce(mul, pair, 1) - if total <= 2**53: - return total - return str(tuple(sorted(pair))) diff --git a/python/covertable/main.py b/python/covertable/main.py index 4300912..2700b0f 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -3,7 +3,8 @@ from . import sorters from . import criteria from .exceptions import NotReady, NeverMatch -from .lib import get_items, prime_generator, unique +from .evaluate import evaluate as eval_condition, extract_keys +from .lib import get_items class ProxyRow(dict): @@ -18,23 +19,28 @@ class Row(dict): def __init__(self, entries=None): super().__init__(entries or {}) self.consumed = {} + self.invalid_pairs = set() def get_pair_key(self, *new_pair): - pair = list(self.values()) + list(new_pair) - return unique(pair) + return tuple(sorted(list(self.values()) + list(new_pair))) def copy_from(self, other): self.update(other) class Controller: - def __init__(self, factors, length=2, sorter=None, criterion=None, - seed="", tolerance=0, pre_filter=None, post_filter=None): + def __init__(self, factors, strength=2, sorter=None, criterion=None, + salt="", tolerance=0, pre_filter=None, post_filter=None, + sub_models=None, presets=None, weights=None, + constraints=None, comparer=None): self.factors = factors - self.length = length + self.strength = strength + self.sub_models = sub_models or [] + self.presets = presets or [] + self.weights = weights or {} self.sorter = sorter or sorters.hash self.criterion = criterion or criteria.greedy - self.seed = seed + self.salt = salt self.tolerance = tolerance self.pre_filter = pre_filter self.post_filter = post_filter @@ -49,88 +55,360 @@ def __init__(self, factors, length=2, sorter=None, criterion=None, self.factor_length = len(factors) self.factor_is_list = isinstance(factors, list) + # Declarative constraints + self.comparer = comparer or {} + self._constraints = [] # list of {"condition": ..., "keys": set} + self._constraints_by_key = {} # key -> set of constraint indices + self._passed_indexes = set() # constraint indices satisfied on current row + + # Stats + self._total_pairs = 0 + self._pruned_pairs = 0 + self._row_count = 0 + self._uncovered_pairs = [] + self._completions = {} + self._serialize(factors) + self._resolve_constraints(constraints) self._set_incomplete() - self._num_all_chunks = len(self.incomplete) + self._total_pairs = len(self.incomplete) - # Delete initial pairs that do not satisfy pre_filter + # Delete initial pairs that cannot satisfy constraints. + # Two-pass: first direct violations, then forward checking. for pair_key in list(self.incomplete.keys()): - pair = self.incomplete[pair_key] - cand = self.get_candidate(pair) - s = self.storable(cand) - if s is None: + cand = self.get_candidate(pair_key) + if self._storable_check(cand) is False: self.incomplete.pop(pair_key, None) + elif self._constraints: + snapshot = dict(cand) + if not self._forward_check(snapshot): + self.incomplete.pop(pair_key, None) + self._pruned_pairs = self._total_pairs - len(self.incomplete) + self._num_all_chunks = len(self.incomplete) + + def _resolve_constraints(self, constraints): + """Build resolved constraints and per-key index.""" + if not constraints: + return + for i, cond in enumerate(constraints): + keys = extract_keys(cond) + self._constraints.append({"condition": cond, "keys": keys}) + for k in keys: + if k not in self._constraints_by_key: + self._constraints_by_key[k] = set() + self._constraints_by_key[k].add(i) def _serialize(self, factors): origin = 0 - primer = prime_generator() + serial = 0 for subscript, elements in get_items(factors): length = len(elements) serial_list = [] for index in range(origin, origin + length): - serial = next(primer) serial_list.append(serial) self.parents[serial] = subscript self.indices[serial] = index + serial += 1 self.serials[subscript] = serial_list origin += length def _set_incomplete(self): pairs = [] all_keys = [k for k, _ in get_items(self.serials)] - for keys in combinations(all_keys, self.length): - comb = [self.serials[keys[i]] for i in range(self.length)] + sub_model_key_sets = [set(sm["keys"]) for sm in self.sub_models] + + def is_within_sub_model(keys): + return any(all(k in ks for k in keys) for ks in sub_model_key_sets) + + # Default strength pairs, excluding combinations fully within a sub-model + for keys in combinations(all_keys, self.strength): + if is_within_sub_model(keys): + continue + comb = [self.serials[keys[i]] for i in range(self.strength)] for pair in product(*comb): - pair = tuple(sorted(pair)) - pairs.append(pair) + pairs.append(tuple(sorted(pair))) - sorted_pairs = self.sorter.sort(pairs, seed=self.seed, indices=self.indices) + # Sub-model pairs at their own strength + for sm in self.sub_models: + for keys in combinations(sm["keys"], sm["strength"]): + comb = [self.serials[keys[i]] for i in range(sm["strength"])] + for pair in product(*comb): + pairs.append(tuple(sorted(pair))) + + sorted_pairs = self.sorter.sort(pairs, salt=self.salt, indices=self.indices) for pair in sorted_pairs: - self.incomplete[unique(pair)] = pair + self.incomplete[pair] = pair + + # -- constraint evaluation helpers -- + + def _storable_check(self, candidate, row=None): + """Check constraints on (row + candidate). + + Returns True (OK), False (violated), or None (deferred). + Falls back to pre_filter when no declarative constraints exist. + """ + if row is None: + row = self.row + + if self._constraints: + nxt_obj = None + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + if nxt_obj is None: + nxt = dict(row) + nxt.update(candidate) + nxt_obj = self._to_map_from_dict(nxt) + result = eval_condition(rc["condition"], nxt_obj, self.comparer) + if result is False: + return False + return True + + # Legacy pre_filter path + if self.pre_filter is None: + return True + nxt = dict(row) + nxt.update(candidate) + nxt_row = Row(nxt) + proxy = self._to_proxy(nxt_row) + try: + ok = self.pre_filter(proxy) + if not ok: + return False + except NotReady: + return None + except Exception: + raise + return True + + def _mark_passed_constraints(self, row): + """Mark constraints that are satisfied on *row*. Returns False if any fails.""" + if not self._constraints: + return True + obj = None + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + if obj is None: + obj = self._to_map_from_dict(row) + result = eval_condition(rc["condition"], obj, self.comparer) + if result is True: + self._passed_indexes.add(i) + elif result is False: + return False + return True def _set_pair(self, pair): + """Legacy: directly set pair into row (used when no constraints).""" for key, value in self.get_candidate(pair): self.row[key] = value - for p in combinations(sorted(self.row.values()), self.length): - self.consume(p) + for s in self.all_strengths: + for p in combinations(sorted(self.row.values()), s): + self.consume(p) + + def set_pair(self, pair): + """Snapshot-based pair addition with constraint checking. + + Returns True if the pair was committed, False if rejected. + """ + candidate = self.get_candidate(pair) + + # Build snapshot + snapshot = dict(self.row) + snapshot.update(candidate) + snapshot_obj = self._to_map_from_dict(snapshot) + + # Evaluate all non-passed constraints + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + result = eval_condition(rc["condition"], snapshot_obj, self.comparer) + if result is False: + return False + + # Forward check before committing + if not self._forward_check(snapshot): + return False + + # Commit + for key, value in candidate: + self.row[key] = value + self._mark_passed_constraints(self.row) + return True + + def _forward_check(self, snapshot): + """Propagate constraints to prune domains of unfilled factors. + + *snapshot* is a dict of {key: serial}. Read-only — does not modify self.row. + Returns False if any domain becomes empty (unsolvable). + """ + if not self._constraints: + return True + + # Build initial domains for unfilled factors + domains = {} + for key, serials in self.serials.items(): + if key not in snapshot: + domains[key] = list(serials) + if not domains: + return True + + relevant_set = set(range(len(self._constraints))) + + temp_row = dict(snapshot) + changed = True + while changed: + changed = False + for key in list(domains.keys()): + domain = domains.get(key) + if domain is None: + continue + if len(domain) == 0: + return False + + key_constraints = self._constraints_by_key.get(key) + if not key_constraints: + continue + has_relevant = any(ci in relevant_set for ci in key_constraints) + if not has_relevant: + continue + + surviving = [] + for serial in domain: + temp_row[key] = serial + obj = self._to_map_from_dict(temp_row) + viable = True + for ci in key_constraints: + if ci in self._passed_indexes: + continue + if eval_condition(self._constraints[ci]["condition"], obj, self.comparer) is False: + viable = False + break + if viable: + surviving.append(serial) + del temp_row[key] + + if len(surviving) == 0: + return False + if len(surviving) < len(domain): + domains[key] = surviving + changed = True + if len(surviving) == 1: + temp_row[key] = surviving[0] + del domains[key] + nc = self._constraints_by_key.get(key) + if nc: + relevant_set.update(nc) + + # Peer propagation for multi-value domains + if len(surviving) > 1: + for peer_key in list(domains.keys()): + if peer_key == key: + continue + peer_domain = domains.get(peer_key) + if peer_domain is None: + continue + peer_constraints = self._constraints_by_key.get(peer_key) + if not peer_constraints: + continue + # Check if peer shares constraints with this factor + if not (peer_constraints & key_constraints): + continue + + peer_viable = set() + for serial in surviving: + temp_row[key] = serial + for ps in peer_domain: + if ps in peer_viable: + continue + temp_row[peer_key] = ps + obj = self._to_map_from_dict(temp_row) + ok = True + for ci in peer_constraints: + if ci in self._passed_indexes: + continue + if eval_condition(self._constraints[ci]["condition"], obj, self.comparer) is False: + ok = False + break + if ok: + peer_viable.add(ps) + if peer_key in temp_row: + del temp_row[peer_key] + if key in temp_row: + del temp_row[key] + + narrowed = [v for v in peer_domain if v in peer_viable] + if len(narrowed) == 0: + return False + if len(narrowed) < len(peer_domain): + domains[peer_key] = narrowed + changed = True + if len(narrowed) == 1: + temp_row[peer_key] = narrowed[0] + del domains[peer_key] + nc = self._constraints_by_key.get(peer_key) + if nc: + relevant_set.update(nc) + return True def consume(self, pair): - pair_key = unique(pair) - if pair_key in self.incomplete: - del self.incomplete[pair_key] - self.row.consumed[pair_key] = pair + if pair in self.incomplete: + del self.incomplete[pair] + self.row.consumed[pair] = pair + + def consume_pairs(self, row): + for s in self.all_strengths: + for pair in combinations(sorted(row.values()), s): + p = tuple(pair) + self.incomplete.pop(p, None) def consume_row(self, row): - for pair in combinations(sorted(row.values()), self.length): - self.consume(pair) + for s in self.all_strengths: + for pair in combinations(sorted(row.values()), s): + self.consume(pair) + + @property + def all_strengths(self): + strengths = {self.strength} + for sm in self.sub_models: + strengths.add(sm["strength"]) + return strengths def get_candidate(self, pair): return [(self.parents[p], p) for p in pair] - def storable(self, candidate): + def is_compatible(self, pair): + """Return new-key count or None if incompatible.""" num = 0 - for key, el in candidate: + for serial in pair: + key = self.parents[serial] existing = self.row.get(key) if existing is None: num += 1 - elif existing != el: + elif existing != serial: return None + return num - if self.pre_filter is None: - return num - - candidates = list(self.row.items()) + candidate - nxt = Row(candidates) - proxy = self._to_proxy(nxt) - try: - ok = self.pre_filter(proxy) - if not ok: - self.consume_row(nxt) + def storable(self, candidate, row=None): + if row is None: + row = self.row + num = 0 + for key, el in candidate: + existing = row.get(key) + if existing is None: + num += 1 + elif existing != el: return None - except NotReady: - return -num - except Exception: - raise + + check = self._storable_check(candidate, row) + if check is False: + # Consume violated pairs when using legacy pre_filter + if not self._constraints and self.pre_filter is not None: + nxt = dict(row) + nxt.update(candidate) + nxt_row = Row(nxt) + self.consume_row(nxt_row) + return None return num def is_filled(self, row=None): @@ -146,6 +424,15 @@ def _to_map(self, row): result[key] = self.factors[key][index - first] return result + def _to_map_from_dict(self, d): + """Convert a {key: serial} dict to {key: value}.""" + result = {} + for key, serial in d.items(): + index = self.indices[serial] + first = self.indices[self.serials[key][0]] + result[key] = self.factors[key][index - first] + return result + def _to_proxy(self, row): return ProxyRow(self._to_map(row)) @@ -156,113 +443,354 @@ def _reset(self): for pair_key, pair in self.row.consumed.items(): self.incomplete[pair_key] = pair self.row = Row() + self._passed_indexes.clear() def _discard(self): pair_key = self.row.get_pair_key() self.rejected.add(pair_key) - for pk, pair in self.row.consumed.items(): - self.incomplete[pk] = pair self.row = Row() + self._passed_indexes.clear() def _restore(self): row = self.row self.row = Row() + self._passed_indexes.clear() if self.factor_is_list: m = self._to_map(row) return [v for _, v in sorted(m.items())] return self._to_object(row) + def _order_by_weight(self, key, serials): + factor_weights = self.weights.get(key) if self.weights else None + if not factor_weights: + return serials + first = self.indices[serials[0]] + return sorted( + serials, + key=lambda s: -factor_weights.get(self.indices[s] - first, 1), + ) + def _close(self): + """Fill unfilled factors via depth-first backtracking. + + Returns True on success, or a dict {"conflict_keys": set|None} on failure. + """ + kvs = list(get_items(self.serials)) + + unfilled = [] + for k, vs in kvs: + if k not in self.row: + unfilled.append({"key": k, "values": self._order_by_weight(k, vs)}) + + if not unfilled: + self._passed_indexes.clear() + self._mark_passed_constraints(self.row) + if self.is_complete: + return True + return {"conflict_keys": self._find_conflict_keys()} + trier = Row(self.row.items()) - for k, vs in get_items(self.serials): - for v in vs: - pair_key = trier.get_pair_key(v) - if pair_key in self.rejected: - continue - cand = [(k, v)] - s = self.storable(cand) - if s is None: - self.rejected.add(pair_key) + depth = len(unfilled) + idx = [0] * depth + d = 0 + last_conflict_keys = None + + trier[unfilled[0]["key"]] = unfilled[0]["values"][0] + + while True: + entry = unfilled[d] + v = entry["values"][idx[d]] + cand = [(entry["key"], v)] + s = self.storable(cand, trier) + + if s is not None: + if d == depth - 1: + self.row.copy_from(trier) + self._passed_indexes.clear() + self._mark_passed_constraints(self.row) + if self.is_complete: + return True + last_conflict_keys = self._find_conflict_keys() + else: + d += 1 + idx[d] = 0 + trier[unfilled[d]["key"]] = unfilled[d]["values"][0] continue - trier[k] = v - break - self.row.copy_from(trier) - if self.is_complete: - return True - if len(trier) == 0: - return False - pair_key = trier.get_pair_key() - if pair_key in self.rejected: - raise NeverMatch() - self.rejected.add(pair_key) - self._reset() - return False + + while True: + idx[d] += 1 + if idx[d] < len(unfilled[d]["values"]): + trier[unfilled[d]["key"]] = unfilled[d]["values"][idx[d]] + break + if unfilled[d]["key"] in trier: + del trier[unfilled[d]["key"]] + d -= 1 + if d < 0: + self._reset() + return {"conflict_keys": last_conflict_keys} + + def _find_conflict_keys(self): + """Find keys of first failing constraint on current row.""" + if not self.is_filled(): + return None + obj = self._to_object(self.row) + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + if eval_condition(rc["condition"], obj, self.comparer) is False: + return rc["keys"] + return None + + def _diagnose_uncovered_pairs(self): + """Analyse remaining pairs and identify failing constraints.""" + result = [] + for pair in self.incomplete.values(): + cand = self.get_candidate(pair) + pair_obj = {} + for key, serial in cand: + idx = self.indices[serial] + first = self.indices[self.serials[key][0]] + pair_obj[key] = self.factors[key][idx - first] + + snapshot = dict(cand) + snapshot_obj = self._to_map_from_dict(snapshot) + failing = [] + for i, rc in enumerate(self._constraints): + r = eval_condition(rc["condition"], snapshot_obj, self.comparer) + if r is False: + failing.append(i) + if not failing: + pair_keys = set(pair_obj.keys()) + for i, rc in enumerate(self._constraints): + for k in rc["keys"]: + if k in pair_keys: + failing.append(i) + break + result.append({"pair": pair_obj, "constraints": failing}) + return result + + def _record_completions(self, row, greedy_keys): + """Record factor values filled by close() rather than greedy.""" + for key, serial in row.items(): + if key in greedy_keys: + continue + idx = self.indices[serial] + first = self.indices[self.serials[key][0]] + value = str(self.factors[key][idx - first]) + key_str = str(key) + if key_str not in self._completions: + self._completions[key_str] = {} + self._completions[key_str][value] = self._completions[key_str].get(value, 0) + 1 @property def is_complete(self): if not self.is_filled(): return False + if self._constraints: + obj = self._to_object(self.row) + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + result = eval_condition(rc["condition"], obj, self.comparer) + # null (None) = referenced key doesn't exist — treat as satisfied + if result is False: + return False + return True if self.pre_filter is None: return True proxy = self._to_proxy(self.row) try: return bool(self.pre_filter(proxy)) except NotReady: - return False + return True # null tolerance: treat unknown as satisfied + + @property + def stats(self): + return { + "total_pairs": self._total_pairs, + "pruned_pairs": self._pruned_pairs, + "covered_pairs": self._total_pairs - self._pruned_pairs - len(self.incomplete), + "progress": 0 if self._total_pairs == 0 else 1 - len(self.incomplete) / self._total_pairs, + "row_count": self._row_count, + "uncovered_pairs": self._uncovered_pairs, + "completions": self._completions, + } @property def progress(self): - if self._num_all_chunks == 0: - return 0 - return 1 - len(self.incomplete) / self._num_all_chunks + return self.stats["progress"] + + def _value_to_serial(self, key, value): + try: + factor_values = self.factors[key] + except (KeyError, IndexError, TypeError): + return None + try: + idx = factor_values.index(value) + except (ValueError, AttributeError): + return None + serial_list = self.serials.get(key) + if not serial_list: + return None + return serial_list[idx] + + def _apply_preset(self, preset): + entries = [] + for key, value in get_items(preset): + serial = self._value_to_serial(key, value) + if serial is None: + return False + entries.append((key, serial)) + if not entries: + return False + for key, serial in entries: + self.row[key] = serial + for s in self.all_strengths: + for pair in combinations(sorted(self.row.values()), s): + self.consume(pair) + return True def make_async(self): - while True: - for pair in self.criterion.extract(self): - if self.is_filled(): - break - self._set_pair(pair) + has_constraints = bool(self._constraints) + + # Process presets + for preset in self.presets: + if not self._apply_preset(preset): + continue + preset_keys = set(self.row.keys()) + try: + result = self._close() + if result is True: + self._record_completions(self.row, preset_keys) + self.consume_pairs(self.row) + self._row_count += 1 + if self.post_filter is None or self.post_filter(self._to_object(self.row)): + yield self._restore() + else: + self._discard() + else: + self._reset() + except NeverMatch: + self.row = Row() + self._passed_indexes.clear() + + consecutive_failures = 0 + while self.incomplete: + # Phase 1: greedy selects pairs, setPair validates via snapshot + if has_constraints: + for pair in self.criterion.extract(self): + if self.is_filled(): + break + pk = pair + if pk in self.row.invalid_pairs: + continue + if not self.set_pair(pair): + self.row.invalid_pairs.add(pk) + else: + for pair in self.criterion.extract(self): + if self.is_filled(): + break + self._set_pair(pair) + + greedy_keys = set(self.row.keys()) + + # Phase 2: close try: - complete = self._close() - if complete: + result = self._close() + if result is True: + self._record_completions(self.row, greedy_keys) + self.consume_pairs(self.row) + self._row_count += 1 if self.post_filter is None or self.post_filter(self._to_object(self.row)): yield self._restore() else: self._discard() + consecutive_failures = 0 + else: + consecutive_failures += 1 + if consecutive_failures > len(self.incomplete): + break + # Carry invalidPairs into next attempt + failed_pairs = set(self.row.invalid_pairs) + for s in self.all_strengths: + for p in combinations(sorted(self.row.values()), s): + failed_pairs.add(tuple(p)) + self._reset() + self.rejected.clear() + self.row.invalid_pairs.update(failed_pairs) except NeverMatch: + if has_constraints: + self._reset() + self.rejected.clear() + continue break if not self.incomplete: break + + # Phase 3 (rescue): try remaining pairs individually + for pair in list(self.incomplete.values()): + self._reset() + if has_constraints: + if not self.set_pair(pair): + continue + else: + self._set_pair(pair) + rescue_keys = set(self.row.keys()) + result = self._close() + if result is True: + self._record_completions(self.row, rescue_keys) + self.consume_pairs(self.row) + self._row_count += 1 + if self.post_filter is None or self.post_filter(self._to_object(self.row)): + yield self._restore() + else: + self._discard() + else: + self._reset() + + if self.incomplete and self._constraints: + self._uncovered_pairs = self._diagnose_uncovered_pairs() + self.incomplete.clear() def make_async( factors, - length=2, + strength=2, progress=False, sorter=sorters.hash, criterion=criteria.greedy, pre_filter=None, post_filter=None, - seed="", + salt="", tolerance=0, + sub_models=None, + presets=None, + weights=None, + constraints=None, + comparer=None, **params, ): - # backwards compat: extract seed/tolerance from options dict + # backwards compat: extract salt/tolerance from options dict options = params.pop("options", {}) if isinstance(options, dict): - seed = options.get("seed", seed) + salt = options.get("salt", salt) tolerance = options.get("tolerance", tolerance) ctrl = Controller( factors, - length=length, + strength=strength, sorter=sorter, criterion=criterion, - seed=seed, + salt=salt, tolerance=tolerance, pre_filter=pre_filter, post_filter=post_filter, + sub_models=sub_models, + presets=presets, + weights=weights, + constraints=constraints, + comparer=comparer, ) for row in ctrl.make_async(): if progress: @@ -272,25 +800,35 @@ def make_async( def make( factors, - length=2, + strength=2, progress=False, sorter=sorters.hash, criterion=criteria.greedy, pre_filter=None, post_filter=None, - seed="", + salt="", tolerance=0, + sub_models=None, + presets=None, + weights=None, + constraints=None, + comparer=None, **params, ): return list(make_async( factors, - length=length, + strength=strength, progress=progress, sorter=sorter, criterion=criterion, pre_filter=pre_filter, post_filter=post_filter, - seed=seed, + salt=salt, tolerance=tolerance, + sub_models=sub_models, + presets=presets, + weights=weights, + constraints=constraints, + comparer=comparer, **params, )) diff --git a/python/covertable/pict/__init__.py b/python/covertable/pict/__init__.py new file mode 100644 index 0000000..d7035bb --- /dev/null +++ b/python/covertable/pict/__init__.py @@ -0,0 +1,10 @@ +"""PICT-compatible model parser and runner. + +This package mirrors the TypeScript ``covertable/pict`` entry point. It can +parse a PICT-format model (parameters, sub-models, constraints, invalid +values, weights, aliases) and generate rows that satisfy it. +""" +from .model import PictModel +from .weights import weights_by_value + +__all__ = ["PictModel", "weights_by_value"] diff --git a/python/covertable/pict/lexer.py b/python/covertable/pict/lexer.py new file mode 100644 index 0000000..d29a3d3 --- /dev/null +++ b/python/covertable/pict/lexer.py @@ -0,0 +1,441 @@ +"""Tokenize and compile PICT constraint expressions into row-filter callables.""" +import re + + +# Token types +_REF = "REF" +_STRING = "STRING" +_NUMBER = "NUMBER" +_BOOLEAN = "BOOLEAN" +_NULL = "NULL" +_IF = "IF" +_ELSE = "ELSE" +_THEN = "THEN" +_COMPARER = "COMPARER" +_OPERATOR = "OPERATOR" +_LPAREN = "LPAREN" +_RPAREN = "RPAREN" +_LBRACE = "LBRACE" +_RBRACE = "RBRACE" +_COMMA = "COMMA" +_COLON = "COLON" +_SEMICOLON = "SEMICOLON" +_WHITESPACE = "WHITESPACE" +_UNKNOWN = "UNKNOWN" + + +def _classify_token(token): + if token.startswith("[") and token.endswith("]"): + return {"type": _REF, "value": token} + if token.startswith('"') and token.endswith('"'): + return {"type": _STRING, "value": token} + try: + float(token) + return {"type": _NUMBER, "value": token} + except ValueError: + pass + upper = token.upper() + if upper in ("TRUE", "FALSE"): + return {"type": _BOOLEAN, "value": upper} + if upper == "NULL": + return {"type": _NULL, "value": upper} + if upper in (_IF, _ELSE, _THEN): + return {"type": upper, "value": upper} + if upper in ("=", "<>", ">", "<", ">=", "<=", "IN", "LIKE"): + return {"type": _COMPARER, "value": upper} + if upper in ("AND", "OR", "NOT"): + return {"type": _OPERATOR, "value": upper} + if token == "(": + return {"type": _LPAREN, "value": token} + if token == ")": + return {"type": _RPAREN, "value": token} + if token == "{": + return {"type": _LBRACE, "value": token} + if token == "}": + return {"type": _RBRACE, "value": token} + if token == ",": + return {"type": _COMMA, "value": token} + if token == ":": + return {"type": _COLON, "value": token} + if token == ";": + return {"type": _SEMICOLON, "value": token} + return {"type": _UNKNOWN, "value": token} + + +def _is_white_space(ch): + return ch in (" ", "\n", "\t") + + +class PictConstraintsLexer: + """Tokenize and compile a PICT constraints text into row-filter callables.""" + + def __init__(self, input_str, debug=False, aliases=None, case_insensitive=False): + self._input = input_str + self._debug = debug + self._aliases = aliases or {} + self._case_insensitive = case_insensitive + self._tokens = [] + self.filters = [] + self.filter_keys = [] + self.errors = [] + try: + self._tokenize() + except Exception as e: + if self._debug: + print("Tokenize error:", str(e)) + self.errors.append(str(e)) + return + self._analyze() + + # -- tokenizer -- + + def _tokenize(self): + constraints = self._input + tokens = [] + buffer = "" + inside_quotes = False + inside_braces = False + inside_brackets = False + + i = 0 + n = len(constraints) + while i < n: + ch = constraints[i] + + if ch == '"': + inside_quotes = not inside_quotes + buffer += ch + if not inside_quotes: + tokens.append({"type": _STRING, "value": buffer}) + buffer = "" + elif inside_quotes: + buffer += ch + elif ch == "[": + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + inside_brackets = True + buffer += ch + elif ch == "]" and inside_brackets: + buffer += ch + tokens.append(_classify_token(buffer)) + inside_brackets = False + buffer = "" + elif ch == "{": + inside_braces = True + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + tokens.append({"type": _LBRACE, "value": ch}) + elif ch == "}": + inside_braces = False + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + tokens.append({"type": _RBRACE, "value": ch}) + elif ch == "," and inside_braces: + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + tokens.append({"type": _COMMA, "value": ch}) + elif ch in "[]=<>!();:" and not inside_braces and not inside_brackets: + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + if ch in ("<", ">", "!", "="): + next_ch = constraints[i + 1] if i + 1 < n else "" + if next_ch == "=": + tokens.append(_classify_token(ch + "=")) + i += 1 + elif ch == "<" and next_ch == ">": + tokens.append(_classify_token("<>")) + i += 1 + else: + tokens.append(_classify_token(ch)) + else: + tokens.append(_classify_token(ch)) + elif _is_white_space(ch) and not inside_braces and not inside_brackets: + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + ws = ch + while i + 1 < n and _is_white_space(constraints[i + 1]): + i += 1 + ws += constraints[i] + tokens.append({"type": _WHITESPACE, "value": ws}) + elif _is_white_space(ch) and (inside_braces or inside_brackets): + buffer += ch + else: + buffer += ch + i += 1 + + if inside_quotes: + raise ValueError("Unterminated string literal: {}".format(buffer)) + if inside_brackets: + raise ValueError("Unterminated field reference: {}".format(buffer)) + if inside_braces: + raise ValueError('Unterminated set (missing closing "}}")') + if buffer: + tokens.append(_classify_token(buffer)) + self._tokens = tokens + + # -- analyzer -- + + def _analyze(self): + tokens = self._tokens + ci = self._case_insensitive + aliases = self._aliases + + def norm(v): + if ci and isinstance(v, str): + return v.lower() + return v + + # We use a single-element list for the index so closures can mutate it. + idx = [0] + current_keys = [set()] + + def next_token(): + while idx[0] < len(tokens) and tokens[idx[0]]["type"] == _WHITESPACE: + idx[0] += 1 + if idx[0] < len(tokens): + t = tokens[idx[0]] + idx[0] += 1 + return t + return None + + def parse_expression(): + left = parse_term() + tok = next_token() + if tok and tok["type"] == _UNKNOWN: + raise ValueError("Unexpected token: {}".format(tok["value"])) + while tok and tok["type"] == _OPERATOR and tok["value"] == "OR": + l = left + r = parse_term() + left = (lambda l, r: lambda row: l(row) or r(row))(l, r) + tok = next_token() + idx[0] -= 1 + return left + + def parse_term(): + left = parse_factor() + tok = next_token() + if tok and tok["type"] == _UNKNOWN: + raise ValueError("Unexpected token: {}".format(tok["value"])) + while tok and tok["type"] == _OPERATOR and tok["value"] == "AND": + l = left + r = parse_factor() + left = (lambda l, r: lambda row: l(row) and r(row))(l, r) + tok = next_token() + idx[0] -= 1 + return left + + def parse_factor(): + tok = next_token() + if tok is not None: + if tok["type"] == _OPERATOR and tok["value"] == "NOT": + operand = parse_factor() + return lambda row: not operand(row) + if tok["type"] == _LPAREN: + expr = parse_expression() + tok = next_token() + if not tok or tok["type"] != _RPAREN: + raise ValueError("Expected closing parenthesis") + return expr + if tok["type"] == _BOOLEAN: + val = tok["value"].upper() == "TRUE" + return lambda row: val + if tok["type"] == _UNKNOWN: + raise ValueError("Unexpected token: {}".format(tok["value"])) + idx[0] -= 1 + return parse_condition() + + def parse_condition(): + left = parse_operand() + if left is None: + raise ValueError('Expected field or value after "IF", "THEN", "ELSE"') + comparer_token = next_token() + if comparer_token and comparer_token["type"] in (_NUMBER, _STRING, _BOOLEAN, _NULL): + raise ValueError( + "Expected comparison operator but found value: {}".format(comparer_token["value"]) + ) + if comparer_token and comparer_token["type"] == _THEN: + raise ValueError("A comparison operator and value are required after the field.") + if comparer_token and comparer_token["type"] == _OPERATOR: + raise ValueError( + "Expected comparison operator but found operator: {}".format(comparer_token["value"]) + ) + if not comparer_token or comparer_token["type"] != _COMPARER: + if comparer_token and comparer_token.get("value") == "!=": + raise ValueError('"!=" is not supported. Use "<>" for inequality comparison') + value = comparer_token["value"] if comparer_token else None + raise ValueError("Unknown comparison operator: {}".format(value)) + comparer = comparer_token["value"] + + if comparer == "IN": + values = parse_set() + return lambda row: norm(left(row)) in values + if comparer == "LIKE": + right = parse_operand() + if right is None: + raise ValueError("Expected string pattern after LIKE") + pattern_str = right({}) + if not isinstance(pattern_str, str): + raise ValueError("Expected string pattern after LIKE") + regex_pattern = re.escape(pattern_str) + # Escape protects * and ? — restore them as wildcards + regex_pattern = regex_pattern.replace(r"\*", ".*").replace(r"\?", ".") + flags = re.IGNORECASE if ci else 0 + regex = re.compile("^" + regex_pattern + "$", flags) + return lambda row: bool(regex.match(str(left(row)))) + right = parse_operand() + if right is None: + raise ValueError("Expected field or value") + if comparer == "=": + return lambda row: norm(left(row)) == norm(right(row)) + if comparer == "<>": + return lambda row: norm(left(row)) != norm(right(row)) + if comparer == ">": + return lambda row: left(row) > right(row) + if comparer == "<": + return lambda row: left(row) < right(row) + if comparer == ">=": + return lambda row: left(row) >= right(row) + if comparer == "<=": + return lambda row: left(row) <= right(row) + raise ValueError("Unknown comparison operator: {}".format(comparer)) + + def parse_set(): + elements = [] + tok = next_token() + if tok and tok["type"] == _LBRACE: + tok = next_token() + while tok and tok["type"] != _RBRACE: + if tok["type"] == _STRING: + raw = tok["value"][1:-1] + lookup = raw.lower() if ci else raw + resolved = aliases.get(lookup, raw) + elements.append(norm(resolved)) + elif tok["type"] not in (_COMMA, _WHITESPACE): + raise ValueError("Unexpected token in array: {}".format(tok["value"])) + tok = next_token() + else: + value = tok["value"] if tok else "NULL" + raise ValueError("Expected '{{' but found {}".format(value)) + if not elements: + raise ValueError("Empty set in IN clause") + return set(elements) + + def parse_operand(): + tok = next_token() + if tok is None: + return None + if tok["type"] == _REF: + key = tok["value"][1:-1] + current_keys[0].add(key) + return lambda row: row.get(key) if isinstance(row, dict) else row[key] + if tok["type"] == _STRING: + raw = tok["value"][1:-1] + lookup = raw.lower() if ci else raw + value = aliases.get(lookup, raw) + return lambda row: value + if tok["type"] == _NUMBER: + value = float(tok["value"]) + if value.is_integer(): + value = int(value) + return lambda row: value + if tok["type"] == _BOOLEAN: + value = tok["value"] == "TRUE" + return lambda row: value + if tok["type"] == _NULL: + return lambda row: None + return None + + def abandon(): + while idx[0] < len(tokens) and tokens[idx[0]]["type"] != _SEMICOLON: + idx[0] += 1 + + def close(evaluator, error): + if evaluator is None: + if self._debug: + print("Error[{}]: {}".format(len(self.errors), error)) + self.filters.append(None) + self.errors.append(error) + else: + if self._debug: + print("Filter[{}]: compiled".format(len(self.filters))) + self.filters.append(evaluator) + self.errors.append(None) + self.filter_keys.append(current_keys[0]) + current_keys[0] = set() + + def read(): + try: + expr = parse_expression() + return expr + except Exception as e: + close(None, str(e)) + # If the conditional expression ends with "ELSE", current index has + # advanced past the semicolon, so step back one before abandoning. + idx[0] -= 1 + abandon() + return None + + while idx[0] < len(tokens) and tokens[idx[0]] is not None: + tok = next_token() + if tok is None: + break + if tok["type"] == _IF: + condition = read() + if condition is None: + continue + then_token = next_token() + if not then_token or then_token["type"] != _THEN: + found = then_token["value"] if then_token else "end of input" + close(None, 'Expected "THEN" but found {}'.format(found)) + abandon() + continue + then_eval = read() + if then_eval is None: + continue + + else_token = next_token() + else_eval = lambda row: True + if else_token and else_token["type"] == _ELSE: + parsed = read() + if parsed is None: + continue + else_eval = parsed + else: + idx[0] -= 1 + + close( + (lambda c, t, e: lambda row: t(row) if c(row) else e(row))( + condition, then_eval, else_eval + ), + None, + ) + elif tok["type"] == _SEMICOLON: + pass + elif tok["type"] == _UNKNOWN: + close(None, "Unknown token: {}".format(tok["value"])) + abandon() + else: + # Unconditional constraint: e.g. [A] <> [B] AND [C] = "x"; + idx[0] -= 1 + expr = read() + if expr is not None: + close(expr, None) + + # -- public -- + + def filter(self, row, *additional_filters): + for f in self.filters: + if f is None: + continue + if not f(row): + return False + for f in additional_filters: + if not f(row): + return False + return True diff --git a/python/covertable/pict/model.py b/python/covertable/pict/model.py new file mode 100644 index 0000000..74862e4 --- /dev/null +++ b/python/covertable/pict/model.py @@ -0,0 +1,248 @@ +"""PictModel: parse a PICT-format model and generate rows from it.""" +from ..main import make as _make, make_async as _make_async +from .lexer import PictConstraintsLexer +from .parser import ( + SUB_MODEL_PATTERN, + is_parameter_line, + parse_pict_model, + parse_sub_model, +) + + +def _split_sections(input_str): + """Split input into parameter, sub-model, and constraint sections.""" + lines = input_str.split("\n") + param_lines = [] + sub_model_lines = [] + constraint_start = len(lines) + + for i, line in enumerate(lines): + trimmed = line.strip() + if trimmed == "" or trimmed.startswith("#"): + param_lines.append(line) + continue + if is_parameter_line(trimmed): + param_lines.append(line) + elif SUB_MODEL_PATTERN.match(trimmed): + sub_model_lines.append(trimmed) + else: + constraint_start = i + break + + return { + "parameter_text": "\n".join(param_lines), + "sub_model_lines": sub_model_lines, + "constraint_text": "\n".join(lines[constraint_start:]), + } + + +class PictModel: + """Parse a PICT-format model and generate rows from it. + + The input string is split into three sections: + + 1. Parameters: ``Name: value1, value2, ...`` + 2. Sub-models: ``{ A, B, C } @ N`` + 3. Constraints: ``IF [P] = "x" THEN [Q] = "y";`` or ``[P] <> [Q];`` + + Errors are collected in :attr:`errors` instead of being raised so that a + partially-valid model can still be inspected. + + Parameters + ---------- + input_str : str + The PICT-format model text. + case_insensitive : bool, optional + When ``True`` (default, matching PICT), constraint comparisons and + alias lookups ignore the case of string values. + """ + + def __init__(self, input_str, case_insensitive=True): + sections = _split_sections(input_str) + parsed = parse_pict_model(sections["parameter_text"]) + + self._parameters = parsed["factors"] + self._invalids = parsed["invalids"] + self._weights = parsed["weights"] + self.errors = list(parsed["errors"]) + + # Normalize alias keys for case-insensitive lookup + if case_insensitive: + lexer_aliases = {k.lower(): v for k, v in parsed["aliases"].items()} + else: + lexer_aliases = parsed["aliases"] + + self._sub_models = [] + for line in sections["sub_model_lines"]: + sub = parse_sub_model(line) + if sub: + self._sub_models.append(sub) + else: + self.errors.append("Invalid sub-model definition: {}".format(line)) + + self._lexer = None + ct = sections["constraint_text"].strip() + # Filter out comment lines from constraint text + if ct: + filtered_lines = [] + for line in ct.split("\n"): + stripped = line.strip() + if stripped.startswith("#"): + continue + filtered_lines.append(line) + ct = "\n".join(filtered_lines) + if ct.strip(): + self._lexer = PictConstraintsLexer( + ct, + debug=False, + aliases=lexer_aliases, + case_insensitive=case_insensitive, + ) + self.errors.extend(e for e in self._lexer.errors if e is not None) + + self._controller = None + + # -- properties -- + + @property + def parameters(self): + return self._parameters + + @property + def sub_models(self): + return self._sub_models + + @property + def constraints(self): + return self._lexer.filters if self._lexer else [] + + @property + def invalids(self): + return self._invalids + + @property + def weights(self): + return self._weights + + @property + def progress(self): + return self._controller.progress if self._controller else 0 + + @property + def stats(self): + return self._controller.stats if self._controller else None + + # -- methods -- + + def filter(self, row): + """Return True if the row satisfies all constraints and the + invalid-value rule (at most one invalid value per row).""" + if self._invalids: + invalid_count = 0 + for key, invalid_set in self._invalids.items(): + if row.get(key) in invalid_set: + invalid_count += 1 + if invalid_count > 1: + return False + if not self._lexer: + return True + return self._lexer.filter(row) + + def _model_constraints(self): + """Convert model constraints into Condition dicts for the controller.""" + result = [] + + if self._lexer: + filters = self._lexer.filters + filter_keys = self._lexer.filter_keys + for i, f in enumerate(filters): + if f is None: + continue + result.append({ + "operator": "custom", + "keys": list(filter_keys[i]), + "evaluate": f, + }) + + if self._invalids: + negative_keys = list(self._invalids.keys()) + invalids = self._invalids + + def eval_negatives(row): + seen = False + for key, neg_set in invalids.items(): + val = row.get(key) + if val in neg_set: + if seen: + return False + seen = True + return True + + result.append({ + "operator": "custom", + "keys": negative_keys, + "evaluate": eval_negatives, + }) + + return result + + def _build_kwargs(self, kwargs): + kwargs = dict(kwargs) + user_constraints = kwargs.pop("constraints", None) + user_filter = kwargs.pop("pre_filter", None) + user_sub_models = kwargs.pop("sub_models", None) + user_weights = kwargs.pop("weights", None) + + # Build constraints list (model + user) + constraints = list(self._model_constraints()) + if user_constraints: + constraints.extend(user_constraints) + if user_filter: + # Wrap legacy pre_filter as a custom constraint + constraints.append({ + "operator": "custom", + "keys": list(self._parameters.keys()), + "evaluate": user_filter, + }) + kwargs["constraints"] = constraints + + if user_sub_models is not None: + kwargs["sub_models"] = user_sub_models + elif self._sub_models: + kwargs["sub_models"] = self._sub_models + + if user_weights is not None: + kwargs["weights"] = user_weights + elif self._weights: + kwargs["weights"] = self._weights + + return kwargs + + def _apply_negative_prefix(self, row): + """Prefix negative values with ``~`` in the output.""" + if not self._invalids: + return row + if isinstance(row, list): + return row + result = dict(row) + for key, neg_set in self._invalids.items(): + if result.get(key) in neg_set: + result[key] = "~{}".format(result[key]) + return result + + def make(self, **kwargs): + """Generate rows that satisfy this model. Accepts the same keyword + arguments as :func:`covertable.make`.""" + built = self._build_kwargs(kwargs) + from ..main import Controller + self._controller = Controller(self._parameters, **built) + return [self._apply_negative_prefix(row) + for row in self._controller.make_async()] + + def make_async(self, **kwargs): + """Generator version of :meth:`make`.""" + built = self._build_kwargs(kwargs) + from ..main import Controller + self._controller = Controller(self._parameters, **built) + for row in self._controller.make_async(): + yield self._apply_negative_prefix(row) diff --git a/python/covertable/pict/parser.py b/python/covertable/pict/parser.py new file mode 100644 index 0000000..217f02f --- /dev/null +++ b/python/covertable/pict/parser.py @@ -0,0 +1,175 @@ +"""Parameter and sub-model parsing for PICT-format model files.""" +import re + + +def split_values(input_str): + """Split comma-separated values respecting quoted strings.""" + values = [] + current = "" + in_quotes = False + for ch in input_str: + if ch == '"': + in_quotes = not in_quotes + current += ch + elif ch == "," and not in_quotes: + if current.strip(): + values.append(current.strip()) + current = "" + else: + current += ch + if current.strip(): + values.append(current.strip()) + return values + + +def strip_quotes(s): + if s.startswith('"') and s.endswith('"'): + return s[1:-1] + return s + + +def to_number_if_possible(token): + """Convert a string token to int/float if it parses, otherwise return the string.""" + if token == "": + return token + try: + if "." in token or "e" in token or "E" in token: + return float(token) + return int(token) + except ValueError: + return token + + +_WEIGHT_PATTERN = re.compile(r"\s*\((\d+)\)\s*$") + + +def parse_value(raw, existing, aliases): + """Parse a single value token. + + Handles ``~``, ``(weight)``, ``|aliases``, ````, and ``"quotes"``. + Returns ``(values, is_invalid, weight)``. + """ + trimmed = raw.strip() + + # Parameter reference: + if trimmed.startswith("<") and trimmed.endswith(">"): + ref_name = trimmed[1:-1] + if ref_name not in existing: + raise ValueError('Unknown parameter reference: "{}"'.format(ref_name)) + return list(existing[ref_name]), False, 1 + + token = trimmed + is_invalid = False + weight = 1 + + # Negative prefix: ~ + if token.startswith("~"): + token = token[1:] + is_invalid = True + + # Weight suffix: (N) + weight_match = _WEIGHT_PATTERN.search(token) + if weight_match: + weight = int(weight_match.group(1)) + token = token[:token.rfind("(")].strip() + + # Aliases: take canonical (first) value, record the rest + if "|" in token: + parts = [p.strip() for p in token.split("|")] + canonical = strip_quotes(parts[0]) + for alias in parts[1:]: + aliases[strip_quotes(alias)] = canonical + token = parts[0] + + # Quoted string + if token.startswith('"') and token.endswith('"'): + return [token[1:-1]], is_invalid, weight + + return [to_number_if_possible(token)], is_invalid, weight + + +def is_parameter_line(trimmed): + colon_idx = trimmed.find(":") + if colon_idx <= 0: + return False + if trimmed.startswith("["): + return False + if re.match(r"^IF\s", trimmed, re.IGNORECASE): + return False + return True + + +def parse_pict_model(input_str): + """Parse the parameter section of a PICT model. + + Returns a dict with keys ``factors``, ``aliases``, ``invalids``, + ``weights``, ``errors``. + """ + factors = {} + aliases = {} + invalids = {} + weights = {} + errors = [] + for line in input_str.split("\n"): + trimmed = line.strip() + if trimmed == "" or trimmed.startswith("#"): + continue + + colon_index = trimmed.find(":") + if colon_index == -1: + errors.append('Invalid line (missing ":"): {}'.format(trimmed)) + continue + + key = trimmed[:colon_index].strip() + if key == "": + errors.append("Empty parameter name in line: {}".format(trimmed)) + continue + + try: + raw_values = split_values(trimmed[colon_index + 1:]) + values = [] + invalid_set = set() + factor_weights = {} + for raw in raw_values: + parsed_values, is_invalid, weight = parse_value(raw, factors, aliases) + start_index = len(values) + values.extend(parsed_values) + if is_invalid: + for v in parsed_values: + invalid_set.add(v) + if weight != 1: + for i in range(len(parsed_values)): + factor_weights[start_index + i] = weight + + if len(values) == 0: + errors.append('No values for parameter "{}"'.format(key)) + continue + + factors[key] = values + if invalid_set: + invalids[key] = invalid_set + if factor_weights: + weights[key] = factor_weights + except Exception as e: + errors.append(str(e)) + + return { + "factors": factors, + "aliases": aliases, + "invalids": invalids, + "weights": weights, + "errors": errors, + } + + +# Sub-model line: { P1, P2, P3 } @ N +SUB_MODEL_PATTERN = re.compile(r"^\{\s*(.+?)\s*\}\s*@\s*(\d+)\s*$") + + +def parse_sub_model(line): + match = SUB_MODEL_PATTERN.match(line) + if not match: + return None + keys = [k.strip() for k in match.group(1).split(",") if k.strip()] + strength = int(match.group(2)) + return {"keys": keys, "strength": strength} diff --git a/python/covertable/pict/weights.py b/python/covertable/pict/weights.py new file mode 100644 index 0000000..36907c7 --- /dev/null +++ b/python/covertable/pict/weights.py @@ -0,0 +1,31 @@ +"""Helpers for converting human-friendly weight specifications.""" + + +def weights_by_value(factors, value_weights): + """Convert value-keyed weights to index-keyed weights. + + Useful when you want to specify weights by value rather than by index + position. + + Example:: + + weights_by_value( + {"Browser": ["Chrome", "Firefox", "Safari"]}, + {"Browser": {"Chrome": 10, "Safari": 5}}, + ) + # → {"Browser": {0: 10, 2: 5}} + """ + result = {} + for key, vw in value_weights.items(): + values = factors.get(key) + if values is None: + continue + index_weights = {} + for value, weight in vw.items(): + for i, v in enumerate(values): + if str(v) == str(value): + index_weights[i] = weight + break + if index_weights: + result[key] = index_weights + return result diff --git a/python/covertable/sorters/hash.py b/python/covertable/sorters/hash.py index 98ab799..60ccdd3 100644 --- a/python/covertable/sorters/hash.py +++ b/python/covertable/sorters/hash.py @@ -10,12 +10,12 @@ def fnv1a32(s): return format(h, '08x') -def sort(pairs, seed="", indices=None, **kwargs): +def sort(pairs, salt="", indices=None, **kwargs): def comparer(pair): if indices: - key = "{} {}".format(",".join(str(indices[n]) for n in pair), seed) + key = "{} {}".format(",".join(str(indices[n]) for n in pair), salt) else: - key = "{} {}".format(",".join(str(n) for n in pair), seed) + key = "{} {}".format(",".join(str(n) for n in pair), salt) return fnv1a32(key) return sorted(pairs, key=comparer) diff --git a/python/test_pict.py b/python/test_pict.py new file mode 100644 index 0000000..1b9004e --- /dev/null +++ b/python/test_pict.py @@ -0,0 +1,393 @@ +"""Tests for the PictModel parser ported from the TypeScript version.""" + +import pytest + +from covertable.pict import PictModel, weights_by_value + + +# --------------------------------------------------------------------------- +# Parameter parsing +# --------------------------------------------------------------------------- + +class TestParameters: + def test_basic_definition(self): + model = PictModel(""" +Type: Single, Span, Stripe, Mirror, RAID-5 +Size: 10, 100, 500, 1000, 5000, 10000, 40000 +Format method: Quick, Slow +File system: FAT, FAT32, NTFS +Cluster size: 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 +Compression: On, Off +""") + assert model.parameters == { + "Type": ["Single", "Span", "Stripe", "Mirror", "RAID-5"], + "Size": [10, 100, 500, 1000, 5000, 10000, 40000], + "Format method": ["Quick", "Slow"], + "File system": ["FAT", "FAT32", "NTFS"], + "Cluster size": [512, 1024, 2048, 4096, 8192, 16384, 32768, 65536], + "Compression": ["On", "Off"], + } + + def test_skips_empty_lines_and_comments(self): + model = PictModel(""" +# This is a comment +A: 1, 2, 3 + +# Another comment +B: x, y +""") + assert model.parameters == {"A": [1, 2, 3], "B": ["x", "y"]} + + def test_quoted_strings_with_commas(self): + model = PictModel('Msg: "hello, world", "foo, bar", normal') + assert model.parameters == {"Msg": ["hello, world", "foo, bar", "normal"]} + + def test_negative_prefix(self): + model = PictModel("Type: Valid, ~Invalid, ~Bad") + assert model.parameters == {"Type": ["Valid", "Invalid", "Bad"]} + + def test_weight_suffix(self): + model = PictModel("Size: 10, 100 (10), 500") + assert model.parameters == {"Size": [10, 100, 500]} + + def test_aliases(self): + model = PictModel("OS: Windows | Win, Linux | GNU/Linux") + assert model.parameters == {"OS": ["Windows", "Linux"]} + + def test_parameter_reference(self): + model = PictModel("A: 1, 2, 3\nB: , 4") + assert model.parameters == {"A": [1, 2, 3], "B": [1, 2, 3, 4]} + + def test_unknown_reference_collected_as_error(self): + model = PictModel("A: ") + assert any("Unknown parameter reference" in e for e in model.errors) + + def test_combined_features(self): + model = PictModel('OS: "Windows 10" | Win10, ~"Bad OS" (5), Linux') + assert model.parameters == {"OS": ["Windows 10", "Bad OS", "Linux"]} + + def test_no_values_collected_as_error(self): + model = PictModel("Key:") + assert any('No values for parameter "Key"' in e for e in model.errors) + + +# --------------------------------------------------------------------------- +# Constraints +# --------------------------------------------------------------------------- + +class TestConstraints: + def test_parses_parameters_and_constraints(self): + model = PictModel(""" +Type: Single, Span, Stripe +Size: 10, 100, 500 + +IF [Type] = "Single" THEN [Size] > 10; +""") + assert model.parameters == { + "Type": ["Single", "Span", "Stripe"], + "Size": [10, 100, 500], + } + assert len(model.constraints) == 1 + assert model.errors == [] + + def test_filter_checks_constraint(self): + model = PictModel(""" +Type: A, B +Size: 10, 100 + +IF [Type] = "A" THEN [Size] = 100; +""") + assert model.filter({"Type": "A", "Size": 100}) is True + assert model.filter({"Type": "A", "Size": 10}) is False + assert model.filter({"Type": "B", "Size": 10}) is True + + def test_filter_returns_true_when_no_constraints(self): + model = PictModel("X: 1, 2\nY: a, b") + assert model.filter({"X": 1, "Y": "a"}) is True + + def test_make_generates_rows_satisfying_constraints(self): + model = PictModel(""" +Type: A, B +Size: 10, 100 +Flag: On, Off + +IF [Type] = "A" THEN [Size] = 100; +""") + rows = model.make() + for row in rows: + if row["Type"] == "A": + assert row["Size"] == 100 + + def test_unconditional_constraint(self): + model = PictModel(""" +A: x, y +B: x, y + +[A] <> [B]; +""") + assert model.errors == [] + assert model.filter({"A": "x", "B": "y"}) is True + assert model.filter({"A": "x", "B": "x"}) is False + + def test_unconditional_with_and(self): + model = PictModel(""" +A: x, y +B: x, y +C: yes, no + +[A] <> [B] AND [C] = "yes"; +""") + assert model.filter({"A": "x", "B": "y", "C": "yes"}) is True + assert model.filter({"A": "x", "B": "x", "C": "yes"}) is False + assert model.filter({"A": "x", "B": "y", "C": "no"}) is False + + +# --------------------------------------------------------------------------- +# Aliases +# --------------------------------------------------------------------------- + +class TestAliases: + def test_alias_resolves_to_canonical(self): + model = PictModel(""" +OS: Windows | Win, Linux +Browser: Chrome, Firefox + +IF [OS] = "Win" THEN [Browser] = "Chrome"; +""") + assert model.errors == [] + assert model.filter({"OS": "Windows", "Browser": "Chrome"}) is True + assert model.filter({"OS": "Windows", "Browser": "Firefox"}) is False + assert model.filter({"OS": "Linux", "Browser": "Firefox"}) is True + + def test_alias_in_in_clause(self): + model = PictModel(""" +OS: "Windows 10" | Win10, "Mac OS" | Mac, Linux +Result: pass, fail + +IF [OS] IN {"Win10", "Mac"} THEN [Result] = "pass"; +""") + assert model.errors == [] + assert model.filter({"OS": "Windows 10", "Result": "pass"}) is True + assert model.filter({"OS": "Windows 10", "Result": "fail"}) is False + assert model.filter({"OS": "Mac OS", "Result": "pass"}) is True + assert model.filter({"OS": "Linux", "Result": "fail"}) is True + + +# --------------------------------------------------------------------------- +# Invalid values (~) +# --------------------------------------------------------------------------- + +class TestInvalidValues: + def test_records_invalid_values(self): + model = PictModel(""" +Age: 20, 30, ~-1, ~999 +Country: Japan, USA, ~"Mars" +""") + assert model.errors == [] + assert model.invalids["Age"] == {-1, 999} + assert model.invalids["Country"] == {"Mars"} + + def test_filter_allows_zero_invalid_values(self): + model = PictModel("Age: 20, ~-1\nCountry: Japan, ~\"Mars\"") + assert model.filter({"Age": 20, "Country": "Japan"}) is True + + def test_filter_allows_one_invalid_value(self): + model = PictModel("Age: 20, ~-1\nCountry: Japan, ~\"Mars\"") + assert model.filter({"Age": -1, "Country": "Japan"}) is True + assert model.filter({"Age": 20, "Country": "Mars"}) is True + + def test_filter_rejects_two_invalid_values(self): + model = PictModel("Age: 20, ~-1\nCountry: Japan, ~\"Mars\"") + assert model.filter({"Age": -1, "Country": "Mars"}) is False + + def test_make_never_combines_two_invalid_values(self): + model = PictModel(""" +Age: 20, 30, ~-1, ~999 +Country: Japan, USA, ~"Mars" +""") + rows = model.make() + for row in rows: + age_invalid = row["Age"] in (-1, 999) + country_invalid = row["Country"] == "Mars" + assert not (age_invalid and country_invalid) + + +# --------------------------------------------------------------------------- +# Sub-models +# --------------------------------------------------------------------------- + +class TestSubModels: + def test_parses_sub_model_definition(self): + model = PictModel(""" +A: 1, 2, 3 +B: 4, 5, 6 +C: 7, 8, 9 + +{ A, B, C } @ 3 +""") + assert model.sub_models == [{"keys": ["A", "B", "C"], "strength": 3}] + assert model.errors == [] + + def test_sub_model_increases_coverage(self): + model = PictModel(""" +A: a1, a2, a3 +B: b1, b2, b3 +C: c1, c2, c3 +D: d1, d2 + +{ A, B, C } @ 3 +""") + rows = model.make() + for a in ["a1", "a2", "a3"]: + for b in ["b1", "b2", "b3"]: + for c in ["c1", "c2", "c3"]: + found = any(r["A"] == a and r["B"] == b and r["C"] == c for r in rows) + assert found, "missing combination ({}, {}, {})".format(a, b, c) + + +# --------------------------------------------------------------------------- +# Weights +# --------------------------------------------------------------------------- + +class TestWeights: + def test_parses_weight_syntax(self): + model = PictModel("Browser: Chrome (10), Firefox, Safari (5)") + assert model.errors == [] + assert model.weights == {"Browser": {0: 10, 2: 5}} + + def test_no_weights_when_none_specified(self): + model = PictModel("Browser: Chrome, Firefox") + assert model.weights == {} + + def test_weighted_value_is_preferred(self): + from covertable import make + factors = { + "A": ["a1", "a2", "a3"], + "B": ["b1", "b2", "b3"], + "C": ["c1", "c2", "c3"], + } + rows_no_weight = make(factors, salt=1) + rows_with_weight = make(factors, salt=1, weights={"C": {0: 100}}) + c1_no = sum(1 for r in rows_no_weight if r["C"] == "c1") + c1_with = sum(1 for r in rows_with_weight if r["C"] == "c1") + assert c1_with >= c1_no + + +class TestWeightsByValue: + def test_basic_conversion(self): + result = weights_by_value( + {"Browser": ["Chrome", "Firefox", "Safari"]}, + {"Browser": {"Chrome": 10, "Safari": 5}}, + ) + assert result == {"Browser": {0: 10, 2: 5}} + + def test_skips_unknown_keys(self): + result = weights_by_value( + {"A": ["x", "y"]}, + {"A": {"x": 10}, "Unknown": {"foo": 5}}, + ) + assert result == {"A": {0: 10}} + + def test_skips_unknown_values(self): + result = weights_by_value( + {"A": ["x", "y"]}, + {"A": {"x": 10, "z": 99}}, + ) + assert result == {"A": {0: 10}} + + def test_matches_numeric_via_string(self): + result = weights_by_value( + {"Size": [10, 100, 1000]}, + {"Size": {"100": 5}}, + ) + assert result == {"Size": {1: 5}} + + +# --------------------------------------------------------------------------- +# Case insensitivity +# --------------------------------------------------------------------------- + +class TestCaseInsensitive: + def test_default_case_insensitive(self): + model = PictModel(""" +OS: iOS, Android +Browser: Chrome, Firefox + +IF [OS] = "ios" THEN [Browser] = "chrome"; +""") + assert model.filter({"OS": "iOS", "Browser": "Chrome"}) is True + assert model.filter({"OS": "iOS", "Browser": "Firefox"}) is False + + def test_in_clause(self): + model = PictModel(""" +Color: Red, Blue, Green, Yellow +Category: Primary, Secondary + +IF [Color] IN {"red", "blue"} THEN [Category] = "Primary"; +""") + assert model.filter({"Color": "Red", "Category": "Primary"}) is True + assert model.filter({"Color": "Blue", "Category": "Primary"}) is True + assert model.filter({"Color": "Green", "Category": "Secondary"}) is True + assert model.filter({"Color": "Red", "Category": "Secondary"}) is False + + def test_like_clause(self): + model = PictModel(""" +Name: Alice, alice, Bob +Status: Active, Inactive + +IF [Name] LIKE "ALIC*" THEN [Status] = "Active"; +""") + assert model.filter({"Name": "Alice", "Status": "Active"}) is True + assert model.filter({"Name": "alice", "Status": "Active"}) is True + assert model.filter({"Name": "Alice", "Status": "Inactive"}) is False + assert model.filter({"Name": "Bob", "Status": "Inactive"}) is True + + def test_explicit_case_sensitive(self): + model = PictModel( + """ +OS: iOS, Android +Browser: Chrome, Firefox + +IF [OS] = "ios" THEN [Browser] = "chrome"; +""", + case_insensitive=False, + ) + # No row matches "ios" because comparison is case-sensitive + assert model.filter({"OS": "iOS", "Browser": "Firefox"}) is True + + +# --------------------------------------------------------------------------- +# Pass-through options +# --------------------------------------------------------------------------- + +class TestOptions: + def test_make_accepts_strength(self): + model = PictModel("A: 1, 2, 3\nB: a, b, c") + rows = model.make(strength=2) + assert len(rows) > 0 + + def test_make_accepts_salt(self): + model = PictModel("A: 1, 2, 3\nB: a, b, c\nC: x, y") + rows1 = model.make(salt=1) + rows2 = model.make(salt=2) + assert len(rows1) > 0 + assert len(rows2) > 0 + + def test_make_accepts_presets(self): + model = PictModel("A: 1, 2\nB: a, b") + rows = model.make(presets=[{"A": 1, "B": "a"}]) + assert any(r["A"] == 1 and r["B"] == "a" for r in rows) + + def test_make_async_yields_rows(self): + model = PictModel("A: 1, 2\nB: a, b") + rows = list(model.make_async()) + assert len(rows) > 0 + + def test_user_pre_filter_combines_with_model_filter(self): + model = PictModel(""" +OS: iOS, Android +Browser: Chrome, Safari +""") + rows = model.make(pre_filter=lambda row: row["OS"] != "iOS") + for row in rows: + assert row["OS"] != "iOS" diff --git a/python/tests.py b/python/tests.py index 753193f..f32ea98 100644 --- a/python/tests.py +++ b/python/tests.py @@ -6,7 +6,7 @@ def call( factors, - length, + strength, sorter="hash", criterion="greedy", options={}, @@ -17,7 +17,7 @@ def call( return make( factors=factors, - length=length, + strength=strength, sorter=getattr(sorters, sorter), criterion=getattr(criteria, criterion), options=options, @@ -28,17 +28,17 @@ def call( class Test_covertable: - def _get_pairs(self, factors, length=2): + def _get_pairs(self, factors, strength=2): from covertable.main import get_items all_keys = [k for k, _ in get_items(factors)] - for keys in combinations(all_keys, length): - factors_list = [factors[keys[i]] for i in range(length)] + for keys in combinations(all_keys, strength): + factors_list = [factors[keys[i]] for i in range(strength)] for pair in product(*factors_list): yield pair - @pytest.mark.parametrize("length", [2, 3, 4]) - def test_all_pairs_must_be_in_rows(self, length): + @pytest.mark.parametrize("strength", [2, 3, 4]) + def test_all_pairs_must_be_in_rows(self, strength): factors = [ ["a", "b", "c"], ["d", "e"], @@ -47,8 +47,8 @@ def test_all_pairs_must_be_in_rows(self, length): ["i", "j"], ["k", "l", "m", "n"], ] - rows = call(factors, length) - for pair in self._get_pairs(factors, length): + rows = call(factors, strength) + for pair in self._get_pairs(factors, strength): for row in rows: if all(p in row for p in pair): break @@ -65,7 +65,7 @@ def pre_filter(row): return False return True - rows = call(factors, length=2, pre_filter=pre_filter) + rows = call(factors, strength=2, pre_filter=pre_filter) unexpected_pairs = [("a", "d"), ("b", "e")] for pair in unexpected_pairs: for row in rows: @@ -79,7 +79,7 @@ def pre_filter(row): return False return True - rows = call(factors, length=2, pre_filter=pre_filter) + rows = call(factors, strength=2, pre_filter=pre_filter) assert not rows def test_post_filter_never_matching_makes_no_rows(self): @@ -90,7 +90,7 @@ def post_filter(row): return False return True - rows = call(factors, length=2, post_filter=post_filter) + rows = call(factors, strength=2, post_filter=post_filter) assert not rows def test_greedy_sorter_should_make_rows_less_than_hashs_one_with2(self): @@ -104,12 +104,12 @@ def test_greedy_sorter_should_make_rows_less_than_hashs_one_with2(self): ] len1, len2 = 0, 0 for _ in range(0, 10): - options = {"seed": random.randint(0, 100000)} + options = {"salt": random.randint(0, 100000)} rows1 = call( - factors, length=2, sorter="hash", criterion="greedy", options=options + factors, strength=2, sorter="hash", criterion="greedy", options=options ) rows2 = call( - factors, length=2, sorter="hash", criterion="simple", options=options + factors, strength=2, sorter="hash", criterion="simple", options=options ) len1 += len(rows1) len2 += len(rows2) @@ -125,12 +125,12 @@ def test_greedy_sorter_should_make_rows_less_than_hashs_one_with3(self): ] len1, len2 = 0, 0 for _ in range(0, 10): - options = {"seed": random.randint(0, 100000)} + options = {"salt": random.randint(0, 100000)} rows1 = call( - factors, length=3, sorter="hash", criterion="greedy", options=options + factors, strength=3, sorter="hash", criterion="greedy", options=options ) rows2 = call( - factors, length=3, sorter="hash", criterion="simple", options=options + factors, strength=3, sorter="hash", criterion="simple", options=options ) len1 += len(rows1) len2 += len(rows2) @@ -145,15 +145,68 @@ def test_random_sorter_makes_different_rows_everytime(self): ["m", "n", "o"], ] for seed in range(0, 5): - rows1 = call(factors, length=2, sorter="random") - rows2 = call(factors, length=2, sorter="random") + rows1 = call(factors, strength=2, sorter="random") + rows2 = call(factors, strength=2, sorter="random") assert rows1 != rows2 def test_invalid_type_factors_raise_an_exception(self): factors = [["a", "b", "c"], ["d", "e"], ["f"]] with pytest.raises(TypeError): - call(iter(factors), length=2) + call(iter(factors), strength=2) + + def test_presets_full_row_is_included(self): + from covertable import make + factors = {"A": ["a1", "a2"], "B": ["b1", "b2"], "C": ["c1", "c2"]} + rows = make(factors, presets=[{"A": "a1", "B": "b1", "C": "c1"}]) + assert any(r["A"] == "a1" and r["B"] == "b1" and r["C"] == "c1" for r in rows) + + def test_presets_partial_row_is_completed(self): + from covertable import make + factors = {"A": ["a1", "a2"], "B": ["b1", "b2"]} + rows = make(factors, presets=[{"A": "a1"}]) + assert rows[0]["A"] == "a1" + assert "B" in rows[0] + + def test_presets_violating_pre_filter_are_dropped(self): + from covertable import make + factors = {"OS": ["iOS", "Android"], "Browser": ["Safari", "Chrome"]} + + def pre_filter(row): + return not (row["OS"] == "iOS" and row["Browser"] == "Chrome") + + rows = make( + factors, + pre_filter=pre_filter, + presets=[ + {"OS": "iOS", "Browser": "Chrome"}, # rejected + {"OS": "Android", "Browser": "Safari"}, # accepted + ], + ) + assert not any(r["OS"] == "iOS" and r["Browser"] == "Chrome" for r in rows) + assert any(r["OS"] == "Android" and r["Browser"] == "Safari" for r in rows) + + def test_presets_unknown_values_are_ignored(self): + from covertable import make + factors = {"A": ["a1", "a2"], "B": ["b1", "b2"]} + rows = make(factors, presets=[{"A": "unknown", "B": "b1"}]) + # Coverage of known values should still be satisfied + for a in ["a1", "a2"]: + for b in ["b1", "b2"]: + assert any(r["A"] == a and r["B"] == b for r in rows) + + def test_weights_via_options(self): + from covertable import make + factors = { + "A": ["a1", "a2", "a3"], + "B": ["b1", "b2", "b3"], + "C": ["c1", "c2", "c3"], + } + rows_no_weight = make(factors, salt=1) + rows_with_weight = make(factors, salt=1, weights={"C": {0: 100}}) + c1_no = sum(1 for r in rows_no_weight if r["C"] == "c1") + c1_with = sum(1 for r in rows_with_weight if r["C"] == "c1") + assert c1_with >= c1_no def test_dict_type_factors_make_dict_row(self): factors = { @@ -163,6 +216,6 @@ def test_dict_type_factors_make_dict_row(self): "key4": ["j", "k", "l"], "key5": ["m", "n", "o"], } - rows = call(factors, length=2) + rows = call(factors, strength=2) for row in rows: assert sorted(row.keys()) == sorted(factors.keys()) diff --git a/typescript/.npmrc b/typescript/.npmrc new file mode 100644 index 0000000..e941d13 --- /dev/null +++ b/typescript/.npmrc @@ -0,0 +1 @@ +package-manager-strict=false diff --git a/typescript/jest.config.ts b/typescript/jest.config.ts new file mode 100644 index 0000000..d9d23f5 --- /dev/null +++ b/typescript/jest.config.ts @@ -0,0 +1,8 @@ +export default { + testPathIgnorePatterns: ['node_modules/', 'dist/'], + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], + }, + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', + moduleFileExtensions: ['js', 'ts', 'json', 'node'], +}; diff --git a/typescript/package-lock.json b/typescript/package-lock.json deleted file mode 100644 index 7924fcd..0000000 --- a/typescript/package-lock.json +++ /dev/null @@ -1,16766 +0,0 @@ -{ - "name": "covertable", - "version": "2.5.2", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "covertable", - "version": "2.5.2", - "license": "Apache-2.0", - "devDependencies": { - "@types/jest": "^25.2.3", - "@types/node": "^14.0.9", - "codecov": "^3.7.1", - "jest": "^26.0.1", - "nyc": "^15.1.0", - "ts-jest": "^26.1.0", - "ts-loader": "^9.5.1", - "ts-node": "^10.9.2", - "typescript": "^4.9.3", - "webpack": "^5.93.0", - "webpack-cli": "^5.1.4" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.8.tgz", - "integrity": "sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/core": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.8.tgz", - "integrity": "sha512-oYapIySGw1zGhEFRd6lzWNLWFX2s5dA/jm+Pw/+59ZdXtjyIuwlXbrId22Md0rgZVop+aVoqow2riXhBLNyuQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.0", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helpers": "^7.13.0", - "@babel/parser": "^7.13.4", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.13.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz", - "integrity": "sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz", - "integrity": "sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", - "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.0.tgz", - "integrity": "sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0", - "lodash": "^4.17.19" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz", - "integrity": "sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", - "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/helpers": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.0.tgz", - "integrity": "sha512-aan1MeFPxFacZeSz6Ld7YZo5aPuqnKlD7+HZY75xQsueczFccP9A7V05+oe0XpLwHK3oLorPe9eaAUljL7WEaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", - "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.9.tgz", - "integrity": "sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw==", - "dev": true, - "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", - "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/traverse": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz", - "integrity": "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.0", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.0", - "@babel/types": "^7.13.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "node_modules/@babel/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz", - "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/console/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/environment/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/environment/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/fake-timers/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/fake-timers/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/globals/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-result/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/test-result/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", - "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/babel__core": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", - "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", - "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", - "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "14.14.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prettier": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.2.tgz", - "integrity": "sha512-i99hy7Ki19EqVOl77WplDrvgNugHnsSjECVR/wUrzw2TJXz1zlUfT2ngGckR6xN7yFYaijsMAqPkOLx9HgUqHg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.11.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true, - "license": "MIT" - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", - "dev": true, - "engines": { - "node": ">=0.6.10" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-jest/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "license": "MIT", - "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" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "license": "MIT" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "license": "ISC", - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/codecov": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.1.tgz", - "integrity": "sha512-Qm7ltx1pzLPsliZY81jyaQ80dcNR4/JpcX0IHCIWrHBXgseySqbdbYfkdiXd7o/xmzQpGRVCKGYeTrHUpn6Dcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "argv": "0.0.2", - "ignore-walk": "3.0.3", - "js-yaml": "3.14.0", - "teeny-request": "6.0.1", - "urlgrey": "0.4.4" - }, - "bin": { - "codecov": "bin/codecov" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true, - "license": "MIT" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", - "dev": true, - "license": "MIT" - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", - "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", - "dev": true, - "license": "MIT" - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "license": "MIT" - }, - "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/expect/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/expect/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/expect/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/expect/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/foreground-child/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "5", - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/https-proxy-agent/node_modules/agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minimatch": "^3.0.4" - } - }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true, - "license": "MIT" - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true, - "license": "MIT" - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true, - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "dev": true, - "license": "ISC", - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-changed-files/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-changed-files/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-changed-files/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-config/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-each/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-environment-jsdom/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-environment-node/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-haste-map/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-jasmine2/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-jasmine2/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-leak-detector/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-leak-detector/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-message-util/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-message-util/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-mock/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-mock/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-util/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-util/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest/node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsdom/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true, - "license": "MIT" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.x" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true, - "license": "MIT" - }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-notifier": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "node_modules/node-notifier/node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-notifier/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/node-notifier/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "license": "ISC", - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true, - "license": "ISC" - }, - "node_modules/repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "license": "ISC" - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true, - "license": "MIT" - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "6.* || >= 7.*" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "license": "ISC", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "license": "MIT", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "license": "ISC" - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "license": "MIT" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true, - "license": "MIT" - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/spawn-wrap/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "dev": true, - "license": "MIT", - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "dev": true, - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/teeny-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz", - "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.2.0", - "stream-events": "^1.0.5", - "uuid": "^3.3.2" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.31.5", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz", - "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true, - "license": "MIT" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-jest": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.3.tgz", - "integrity": "sha512-nBiiFGNvtujdLryU7MiMQh1iPmnZ/QvOskBbD2kURiI1MwqvxlxNnaAB/z9TbslMqCsSbu5BXvSSQPc5tvHGeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": ">= 10" - }, - "peerDependencies": { - "jest": ">=26 <27", - "typescript": ">=3.8 <5.0" - } - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-jest/node_modules/yargs-parser": { - "version": "20.2.6", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", - "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ts-loader/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "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" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true, - "license": "MIT" - }, - "node_modules/urlgrey": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", - "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", - "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", - "dev": true, - "license": "ISC", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.x" - } - }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-cli/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/webpack-cli/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-cli/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-cli/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-cli/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true, - "license": "ISC" - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/compat-data": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.8.tgz", - "integrity": "sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog==", - "dev": true - }, - "@babel/core": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.8.tgz", - "integrity": "sha512-oYapIySGw1zGhEFRd6lzWNLWFX2s5dA/jm+Pw/+59ZdXtjyIuwlXbrId22Md0rgZVop+aVoqow2riXhBLNyuQg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.0", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helpers": "^7.13.0", - "@babel/parser": "^7.13.4", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", - "dev": true, - "requires": { - "@babel/types": "^7.13.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz", - "integrity": "sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - } - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz", - "integrity": "sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==", - "dev": true, - "requires": { - "@babel/types": "^7.13.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", - "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-module-transforms": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.0.tgz", - "integrity": "sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0", - "lodash": "^4.17.19" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz", - "integrity": "sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", - "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.0.tgz", - "integrity": "sha512-aan1MeFPxFacZeSz6Ld7YZo5aPuqnKlD7+HZY75xQsueczFccP9A7V05+oe0XpLwHK3oLorPe9eaAUljL7WEaQ==", - "dev": true, - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "@babel/highlight": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", - "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.9.tgz", - "integrity": "sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", - "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz", - "integrity": "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.0", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.0", - "@babel/types": "^7.13.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "@babel/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz", - "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "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": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dev": true, - "requires": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - } - }, - "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@sinonjs/commons": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", - "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", - "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", - "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", - "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", - "dev": true, - "requires": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" - } - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "@types/node": { - "version": "14.14.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", - "dev": true - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true - }, - "@types/prettier": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.2.tgz", - "integrity": "sha512-i99hy7Ki19EqVOl77WplDrvgNugHnsSjECVR/wUrzw2TJXz1zlUfT2ngGckR6xN7yFYaijsMAqPkOLx9HgUqHg==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "requires": {} - }, - "@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "requires": {} - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "requires": { - "type-fest": "^0.11.0" - }, - "dependencies": { - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dev": true, - "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@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": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", - "dev": true - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "requires": { - "rsvp": "^4.8.4" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "codecov": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.1.tgz", - "integrity": "sha512-Qm7ltx1pzLPsliZY81jyaQ80dcNR4/JpcX0IHCIWrHBXgseySqbdbYfkdiXd7o/xmzQpGRVCKGYeTrHUpn6Dcw==", - "dev": true, - "requires": { - "argv": "0.0.2", - "ignore-walk": "3.0.3", - "js-yaml": "3.14.0", - "teeny-request": "6.0.1", - "urlgrey": "0.4.4" - } - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "requires": { - "strip-bom": "^4.0.0" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "electron-to-chromium": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", - "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", - "dev": true - }, - "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", - "dev": true - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "optional": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - } - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "dev": true, - "requires": { - "agent-base": "5", - "debug": "4" - }, - "dependencies": { - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true - } - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", - "dev": true, - "optional": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - } - } - } - }, - "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dev": true, - "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dev": true, - "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "requires": { - "tmpl": "1.0.x" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - }, - "dependencies": { - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-notifier": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", - "dev": true, - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - }, - "dependencies": { - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "optional": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - } - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@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" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "requires": { - "fromentries": "^1.2.0" - } - }, - "prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "dev": true, - "requires": { - "stubs": "^3.0.0" - } - }, - "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, - "teeny-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz", - "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==", - "dev": true, - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.2.0", - "stream-events": "^1.0.5", - "uuid": "^3.3.2" - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "terser": { - "version": "5.31.5", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz", - "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "ts-jest": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.3.tgz", - "integrity": "sha512-nBiiFGNvtujdLryU7MiMQh1iPmnZ/QvOskBbD2kURiI1MwqvxlxNnaAB/z9TbslMqCsSbu5BXvSSQPc5tvHGeA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "dependencies": { - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yargs-parser": { - "version": "20.2.6", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", - "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", - "dev": true - } - } - }, - "ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } - } - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "requires": { - "@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" - }, - "dependencies": { - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true - }, - "acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, - "requires": { - "acorn": "^8.11.0" - } - } - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "requires": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "urlgrey": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", - "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8-to-istanbul": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", - "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "requires": { - "makeerror": "1.0.x" - } - }, - "watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true - }, - "acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "dev": true, - "requires": {} - } - } - }, - "webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/typescript/package.json b/typescript/package.json index c17747b..03a200b 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "2.5.2", + "version": "3.0.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://docs.walkframe.com/covertable", "repository": { @@ -33,43 +33,43 @@ "covering-arrays", "pict" ], - "main": "dist/index.js", + "type": "module", + "main": "dist/index.cjs", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./pict": { + "types": "./dist/pict.d.ts", + "import": "./dist/pict.js", + "require": "./dist/pict.cjs" + } + }, + "files": [ + "dist" + ], "scripts": { "test": "jest", - "build": "rm -rf dist/ && $(npm bin)/webpack", - "watch": "$(npm bin)/webpack --watch", - "codecov": "$(npm bin)/codecov" - }, - "jest": { - "testPathIgnorePatterns": [ - "node_modules/", - "dist/" - ], - "transform": { - "^.+\\.tsx?$": "ts-jest" - }, - "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", - "moduleFileExtensions": [ - "js", - "ts", - "json", - "node" - ] + "build": "vite build && tsc --emitDeclarationOnly" }, "author": "righ", "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^25.2.3", - "@types/node": "^14.0.9", - "codecov": "^3.7.1", - "jest": "^26.0.1", - "nyc": "^15.1.0", - "ts-jest": "^26.1.0", - "ts-loader": "^9.5.1", + "@types/jest": "^29.5.0", + "@types/node": "^22.0.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.0", "ts-node": "^10.9.2", - "typescript": "^4.9.3", - "webpack": "^5.93.0", - "webpack-cli": "^5.1.4" + "typescript": "^5.7.0", + "vite": "^6.3.0", + "vite-plugin-dts": "^4.5.0" }, - "dependencies": {} + "dependencies": {}, + "pnpm": { + "onlyBuiltDependencies": ["esbuild"] + } } diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml new file mode 100644 index 0000000..25bfed5 --- /dev/null +++ b/typescript/pnpm-lock.yaml @@ -0,0 +1,3862 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/jest': + specifier: ^29.5.0 + version: 29.5.14 + '@types/node': + specifier: ^22.0.0 + version: 22.19.17 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + ts-jest: + specifier: ^29.2.0 + version: 29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)))(typescript@5.9.3) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@22.19.17)(typescript@5.9.3) + typescript: + specifier: ^5.7.0 + version: 5.9.3 + vite: + specifier: ^6.3.0 + version: 6.4.2(@types/node@22.19.17) + vite-plugin-dts: + specifier: ^4.5.0 + version: 4.5.4(@types/node@22.19.17)(rollup@4.60.1)(typescript@5.9.3)(vite@6.4.2(@types/node@22.19.17)) + +packages: + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@microsoft/api-extractor-model@7.33.6': + resolution: {integrity: sha512-E9iI4yGEVVusbTAqSLetVFxDuBVCVqCigcoQwdJuOjsLq5Hry3MkBgUQhSZNzLCu17pgjk58MI80GRDJLht/1A==} + + '@microsoft/api-extractor@7.58.2': + resolution: {integrity: sha512-qmqWa0Fx1xn3irQy8MyuAKUs8e3CdwMJOujaPkM8gx5v/V7RcLhTjBU0/uL2kdhmROpW+5WG1FD98O441kkvQQ==} + hasBin: true + + '@microsoft/tsdoc-config@0.18.1': + resolution: {integrity: sha512-9brPoVdfN9k9g0dcWkFeA7IH9bbcttzDJlXvkf8b2OBzd5MueR1V2wkKBL0abn0otvmkHJC6aapBOTJDDeMCZg==} + + '@microsoft/tsdoc@0.16.0': + resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.60.1': + resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.1': + resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.1': + resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.1': + resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.1': + resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.1': + resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.1': + resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.1': + resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.1': + resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.1': + resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.1': + resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.1': + resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.1': + resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.1': + resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.1': + resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.1': + resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.1': + resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.1': + resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.1': + resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.1': + resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==} + cpu: [x64] + os: [win32] + + '@rushstack/node-core-library@5.22.0': + resolution: {integrity: sha512-S/Dm/N+8tkbasS6yM5cF6q4iDFt14mQQniiVIwk1fd0zpPwWESspO4qtPyIl8szEaN86XOYC1HRRzZrOowxjtw==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/problem-matcher@0.2.1': + resolution: {integrity: sha512-gulfhBs6n+I5b7DvjKRfhMGyUejtSgOHTclF/eONr8hcgF1APEDjhxIsfdUYYMzC3rvLwGluqLjbwCFZ8nxrog==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/rig-package@0.7.2': + resolution: {integrity: sha512-9XbFWuqMYcHUso4mnETfhGVUSaADBRj6HUAAEYk50nMPn8WRICmBuCphycQGNB3duIR6EEZX3Xj3SYc2XiP+9A==} + + '@rushstack/terminal@0.22.5': + resolution: {integrity: sha512-umej8J6A+WRbfQV1G/uNfnz4bMa8CzFU9IJzQb/ZcH4j7Ybg3BQ8UBKOCF3o5U3/2yah1TDU/zE71ugg2JJv+Q==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/ts-command-line@5.3.5': + resolution: {integrity: sha512-ToJQu3+o6aEdDoApGrwb/RsbwDi/NSC7jIEaAezzWM470TRrsXfSHoYAm1eWkhh34xJ+kZxU1ZzKSHiOMlOFPA==} + + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/argparse@1.0.38': + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/node@22.19.17': + resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} + + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} + + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} + + '@vue/compiler-core@3.5.32': + resolution: {integrity: sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==} + + '@vue/compiler-dom@3.5.32': + resolution: {integrity: sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/language-core@2.2.0': + resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/shared@3.5.32': + resolution: {integrity: sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==} + + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + alien-signals@0.4.14: + resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.16: + resolution: {integrity: sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.3: + resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} + engines: {node: '>=0.3.1'} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + electron-to-chromium@1.5.334: + resolution: {integrity: sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + engines: {node: '>=14.14'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@10.2.3: + resolution: {integrity: sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + engines: {node: ^10 || ^12 || >=14} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + rollup@4.60.1: + resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-jest@29.4.9: + resolution: {integrity: sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + esbuild: '*' + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: '>=4.3 <7' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + vite-plugin-dts@4.5.4: + resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==} + peerDependencies: + typescript: '*' + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@6.4.2: + resolution: {integrity: sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bcoe/v8-coverage@0.2.3': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.2 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3))': + 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': 22.19.17 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + 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.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.19.17 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + 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.31 + '@types/node': 22.19.17 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.17 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@microsoft/api-extractor-model@7.33.6(@types/node@22.19.17)': + dependencies: + '@microsoft/tsdoc': 0.16.0 + '@microsoft/tsdoc-config': 0.18.1 + '@rushstack/node-core-library': 5.22.0(@types/node@22.19.17) + transitivePeerDependencies: + - '@types/node' + + '@microsoft/api-extractor@7.58.2(@types/node@22.19.17)': + dependencies: + '@microsoft/api-extractor-model': 7.33.6(@types/node@22.19.17) + '@microsoft/tsdoc': 0.16.0 + '@microsoft/tsdoc-config': 0.18.1 + '@rushstack/node-core-library': 5.22.0(@types/node@22.19.17) + '@rushstack/rig-package': 0.7.2 + '@rushstack/terminal': 0.22.5(@types/node@22.19.17) + '@rushstack/ts-command-line': 5.3.5(@types/node@22.19.17) + diff: 8.0.4 + lodash: 4.18.1 + minimatch: 10.2.3 + resolve: 1.22.11 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/node' + + '@microsoft/tsdoc-config@0.18.1': + dependencies: + '@microsoft/tsdoc': 0.16.0 + ajv: 8.18.0 + jju: 1.4.0 + resolve: 1.22.11 + + '@microsoft/tsdoc@0.16.0': {} + + '@rollup/pluginutils@5.3.0(rollup@4.60.1)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.1 + + '@rollup/rollup-android-arm-eabi@4.60.1': + optional: true + + '@rollup/rollup-android-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-x64@4.60.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.1': + optional: true + + '@rushstack/node-core-library@5.22.0(@types/node@22.19.17)': + dependencies: + ajv: 8.18.0 + ajv-draft-04: 1.0.0(ajv@8.18.0) + ajv-formats: 3.0.1(ajv@8.18.0) + fs-extra: 11.3.4 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.11 + semver: 7.5.4 + optionalDependencies: + '@types/node': 22.19.17 + + '@rushstack/problem-matcher@0.2.1(@types/node@22.19.17)': + optionalDependencies: + '@types/node': 22.19.17 + + '@rushstack/rig-package@0.7.2': + dependencies: + resolve: 1.22.11 + strip-json-comments: 3.1.1 + + '@rushstack/terminal@0.22.5(@types/node@22.19.17)': + dependencies: + '@rushstack/node-core-library': 5.22.0(@types/node@22.19.17) + '@rushstack/problem-matcher': 0.2.1(@types/node@22.19.17) + supports-color: 8.1.1 + optionalDependencies: + '@types/node': 22.19.17 + + '@rushstack/ts-command-line@5.3.5(@types/node@22.19.17)': + dependencies: + '@rushstack/terminal': 0.22.5(@types/node@22.19.17) + '@types/argparse': 1.0.38 + argparse: 1.0.10 + string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' + + '@sinclair/typebox@0.27.10': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@tsconfig/node10@1.0.12': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/argparse@1.0.38': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/estree@1.0.8': {} + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.19.17 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/node@22.19.17': + dependencies: + undici-types: 6.21.0 + + '@types/stack-utils@2.0.3': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@volar/language-core@2.4.28': + dependencies: + '@volar/source-map': 2.4.28 + + '@volar/source-map@2.4.28': {} + + '@volar/typescript@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/compiler-core@3.5.32': + dependencies: + '@babel/parser': 7.29.2 + '@vue/shared': 3.5.32 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.32': + dependencies: + '@vue/compiler-core': 3.5.32 + '@vue/shared': 3.5.32 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/language-core@2.2.0(typescript@5.9.3)': + dependencies: + '@volar/language-core': 2.4.28 + '@vue/compiler-dom': 3.5.32 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.32 + alien-signals: 0.4.14 + minimatch: 9.0.9 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.9.3 + + '@vue/shared@3.5.32': {} + + acorn-walk@8.3.5: + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv-draft-04@1.0.0(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + alien-signals@0.4.14: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + babel-jest@29.7.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.29.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.28.6 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) + + babel-preset-jest@29.6.3(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.16: {} + + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.3: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.16 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.334 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001787: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + ci-info@3.9.0: {} + + cjs-module-lexer@1.4.3: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + co@4.6.0: {} + + collect-v8-coverage@1.0.3: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + compare-versions@6.1.1: {} + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + convert-source-map@2.0.0: {} + + create-jest@29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + de-indent@1.0.2: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + dedent@1.7.2: {} + + deepmerge@4.3.1: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.4: {} + + diff@8.0.4: {} + + electron-to-chromium@1.5.334: {} + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + entities@7.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + escalade@3.2.0: {} + + escape-string-regexp@2.0.0: {} + + esprima@4.0.1: {} + + estree-walker@2.0.2: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + 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 + + exsolve@1.0.8: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-uri@3.1.0: {} + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-package-type@0.1.0: {} + + get-stream@6.0.1: {} + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + graceful-fs@4.2.11: {} + + handlebars@4.7.9: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + html-escaper@2.0.2: {} + + human-signals@2.1.0: {} + + import-lazy@4.0.0: {} + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arrayish@0.2.1: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-number@7.0.0: {} + + is-stream@2.0.1: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.7.2 + is-generator-fn: 2.1.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.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + 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.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.19.17 + ts-node: 10.9.2(@types/node@22.19.17)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.19.17 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.11 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@29.7.0: + 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': 22.19.17 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + 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 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + 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': 22.19.17 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + 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 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + 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.7.4 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.2 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.17 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@29.7.0: + dependencies: + '@types/node': 22.19.17 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jju@1.4.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + jsesc@3.1.0: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@1.0.0: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + kleur@3.0.3: {} + + kolorist@1.8.0: {} + + leven@3.1.0: {} + + lines-and-columns@1.2.4: {} + + local-pkg@1.1.2: + dependencies: + mlly: 1.8.2 + pkg-types: 2.3.0 + quansync: 0.2.11 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.memoize@4.1.2: {} + + lodash@4.18.1: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-dir@4.0.0: + dependencies: + semver: 7.7.4 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + merge-stream@2.0.0: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mimic-fn@2.1.0: {} + + minimatch@10.2.3: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.3 + + minimist@1.2.8: {} + + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + neo-async@2.6.2: {} + + node-int64@0.4.0: {} + + node-releases@2.0.37: {} + + normalize-path@3.0.0: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + pirates@4.0.7: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + postcss@8.5.9: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + pure-rand@6.1.0: {} + + quansync@0.2.11: {} + + react-is@18.3.1: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@5.0.0: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + rollup@4.60.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.1 + '@rollup/rollup-android-arm64': 4.60.1 + '@rollup/rollup-darwin-arm64': 4.60.1 + '@rollup/rollup-darwin-x64': 4.60.1 + '@rollup/rollup-freebsd-arm64': 4.60.1 + '@rollup/rollup-freebsd-x64': 4.60.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.1 + '@rollup/rollup-linux-arm-musleabihf': 4.60.1 + '@rollup/rollup-linux-arm64-gnu': 4.60.1 + '@rollup/rollup-linux-arm64-musl': 4.60.1 + '@rollup/rollup-linux-loong64-gnu': 4.60.1 + '@rollup/rollup-linux-loong64-musl': 4.60.1 + '@rollup/rollup-linux-ppc64-gnu': 4.60.1 + '@rollup/rollup-linux-ppc64-musl': 4.60.1 + '@rollup/rollup-linux-riscv64-gnu': 4.60.1 + '@rollup/rollup-linux-riscv64-musl': 4.60.1 + '@rollup/rollup-linux-s390x-gnu': 4.60.1 + '@rollup/rollup-linux-x64-gnu': 4.60.1 + '@rollup/rollup-linux-x64-musl': 4.60.1 + '@rollup/rollup-openbsd-x64': 4.60.1 + '@rollup/rollup-openharmony-arm64': 4.60.1 + '@rollup/rollup-win32-arm64-msvc': 4.60.1 + '@rollup/rollup-win32-ia32-msvc': 4.60.1 + '@rollup/rollup-win32-x64-gnu': 4.60.1 + '@rollup/rollup-win32-x64-msvc': 4.60.1 + fsevents: 2.3.3 + + semver@6.3.1: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + string-argv@0.3.2: {} + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.5 + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tmpl@1.0.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-jest@29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.9 + jest: 29.7.0(@types/node@22.19.17)(ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.4 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + jest-util: 29.7.0 + + ts-node@10.9.2(@types/node@22.19.17)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.19.17 + acorn: 8.16.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + type-fest@4.41.0: {} + + typescript@5.9.3: {} + + ufo@1.6.3: {} + + uglify-js@3.19.3: + optional: true + + undici-types@6.21.0: {} + + universalify@2.0.1: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + vite-plugin-dts@4.5.4(@types/node@22.19.17)(rollup@4.60.1)(typescript@5.9.3)(vite@6.4.2(@types/node@22.19.17)): + dependencies: + '@microsoft/api-extractor': 7.58.2(@types/node@22.19.17) + '@rollup/pluginutils': 5.3.0(rollup@4.60.1) + '@volar/typescript': 2.4.28 + '@vue/language-core': 2.2.0(typescript@5.9.3) + compare-versions: 6.1.1 + debug: 4.4.3 + kolorist: 1.8.0 + local-pkg: 1.1.2 + magic-string: 0.30.21 + typescript: 5.9.3 + optionalDependencies: + vite: 6.4.2(@types/node@22.19.17) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + + vite@6.4.2(@types/node@22.19.17): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.9 + rollup: 4.60.1 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 22.19.17 + fsevents: 2.3.3 + + vscode-uri@3.1.0: {} + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wordwrap@1.0.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/typescript/src/__tests__/bench.test.ts b/typescript/src/__tests__/bench.test.ts new file mode 100644 index 0000000..04c4a79 --- /dev/null +++ b/typescript/src/__tests__/bench.test.ts @@ -0,0 +1,100 @@ +import { Controller } from '../controller'; +import { criteria, sorters } from '../index'; +import { PictModel } from '../pict'; +import * as fs from 'fs'; +import * as path from 'path'; + +const bench = (name: string, fn: () => any, iterations = 5) => { + const times: number[] = []; + let result: any; + for (let i = 0; i < iterations; i++) { + const t0 = Date.now(); + result = fn(); + times.push(Date.now() - t0); + } + times.sort((a, b) => a - b); + const median = times[Math.floor(times.length / 2)]; + const min = times[0]; + const max = times[times.length - 1]; + console.log(`${name}: median=${median}ms min=${min}ms max=${max}ms`); + return result; +}; + +describe('benchmarks', () => { + it('20x10 no constraints (greedy)', () => { + const factors: Record = {}; + for (let i = 0; i < 20; i++) { + factors[`f${i}`] = Array.from({ length: 10 }, (_, j) => j); + } + const result = bench('20x10 greedy', () => { + const ctrl = new Controller(factors, { criterion: criteria.greedy }); + const rows = ctrl.make(); + return { rows: rows.length, stats: ctrl.stats }; + }); + console.log(` rows: ${result.rows}`); + }); + + it('20x10 no constraints (simple)', () => { + const factors: Record = {}; + for (let i = 0; i < 20; i++) { + factors[`f${i}`] = Array.from({ length: 10 }, (_, j) => j); + } + const result = bench('20x10 simple', () => { + const ctrl = new Controller(factors, { criterion: criteria.simple }); + const rows = ctrl.make(); + return { rows: rows.length, stats: ctrl.stats }; + }); + console.log(` rows: ${result.rows}`); + }); + + it('heavy.pict (greedy)', () => { + const modelText = fs.readFileSync( + path.resolve(__dirname, '../../../heavy.pict'), 'utf-8', + ); + const result = bench('heavy.pict greedy', () => { + const model = new PictModel(modelText); + const rows = model.make(); + return { rows: rows.length, stats: model.stats }; + }); + console.log(` rows: ${result.rows}, progress: ${result.stats?.progress}`); + }); + + it('heavy.pict (simple)', () => { + const modelText = fs.readFileSync( + path.resolve(__dirname, '../../../heavy.pict'), 'utf-8', + ); + const result = bench('heavy.pict simple', () => { + const model = new PictModel(modelText); + const ctrl = new Controller(model.parameters, { + ...(model as any)._buildOptions(), + criterion: criteria.simple, + }); + const rows = ctrl.make(); + return { rows: rows.length, stats: ctrl.stats }; + }); + console.log(` rows: ${result.rows}, progress: ${result.stats?.progress}`); + }); + + it('5x5 all-different (greedy)', () => { + const vals = [1, 2, 3, 4, 5]; + const factors = { A: vals, B: vals, C: vals, D: vals, E: vals }; + const constraints = [ + { operator: 'ne' as const, field: 'A', target: 'B' }, + { operator: 'ne' as const, field: 'A', target: 'C' }, + { operator: 'ne' as const, field: 'A', target: 'D' }, + { operator: 'ne' as const, field: 'A', target: 'E' }, + { operator: 'ne' as const, field: 'B', target: 'C' }, + { operator: 'ne' as const, field: 'B', target: 'D' }, + { operator: 'ne' as const, field: 'B', target: 'E' }, + { operator: 'ne' as const, field: 'C', target: 'D' }, + { operator: 'ne' as const, field: 'C', target: 'E' }, + { operator: 'ne' as const, field: 'D', target: 'E' }, + ]; + const result = bench('5x5 all-diff greedy', () => { + const ctrl = new Controller(factors, { constraints, criterion: criteria.greedy }); + const rows = ctrl.make(); + return { rows: rows.length, stats: ctrl.stats }; + }); + console.log(` rows: ${result.rows}, pruned: ${result.stats.prunedPairs}`); + }); +}); diff --git a/typescript/src/__tests__/contradictory.test.ts b/typescript/src/__tests__/contradictory.test.ts new file mode 100644 index 0000000..f115462 --- /dev/null +++ b/typescript/src/__tests__/contradictory.test.ts @@ -0,0 +1,77 @@ +import { Controller } from '../controller'; +import type { Condition } from '../types'; + +describe('contradictory constraints', () => { + + // The forward check's weakness: two unfilled factors jointly constrained. + // A=1 → B∈{10,20}, each B value forces a different C, + // and D has a constraint that depends on both B and C together. + // IF B+C is odd THEN D=1000 (expressed via custom or structural constraint) + it('joint dependency: B and C together determine D', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: [1000, 2000], + E: ['x', 'y', 'z'], + }; + const constraints: Condition[] = [ + // A=1 → B∈{10,20} + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'in', field: 'B', values: [10, 20] }, + ]}, + // B=10 → C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + // B=20 → C=200 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 20 }, + { operator: 'eq', field: 'C', value: 200 }, + ]}, + // B=10 AND C=100 → D=1000 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'ne', field: 'C', value: 100 }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + // B=20 AND C=200 → D=1000 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 20 }, + { operator: 'ne', field: 'C', value: 200 }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + // So when A=1, D must be 1000. Pair (A=1, D=2000) is infeasible. + // But also add: D=1000 → E='x' + { operator: 'or', conditions: [ + { operator: 'ne', field: 'D', value: 1000 }, + { operator: 'eq', field: 'E', value: 'x' }, + ]}, + // Now (A=1, E='y') and (A=1, E='z') are also infeasible + // because A=1 → B∈{10,20} → (B,C) forces D=1000 → E='x' + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + + console.log('Joint dependency:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs.map(u => u.pair)); + } + + // Verify no constraint violations + for (const r of rows as any[]) { + if (r.A === 1) expect([10, 20]).toContain(r.B); + if (r.B === 10) expect(r.C).toBe(100); + if (r.B === 20) expect(r.C).toBe(200); + if (r.B === 10 && r.C === 100) expect(r.D).toBe(1000); + if (r.B === 20 && r.C === 200) expect(r.D).toBe(1000); + if (r.D === 1000) expect(r.E).toBe('x'); + } + }); +}); diff --git a/typescript/src/__tests__/coverage-bench.test.ts b/typescript/src/__tests__/coverage-bench.test.ts new file mode 100644 index 0000000..9b0c427 --- /dev/null +++ b/typescript/src/__tests__/coverage-bench.test.ts @@ -0,0 +1,77 @@ +import { Controller } from '../controller'; +import type { Condition } from '../types'; + +describe('coverage benchmark', () => { + it('constraint chain coverage', () => { + const factors = { + Language: ['de', 'en', 'ja', 'fr', 'es', 'pt', 'zh', 'ko', 'ru', 'ar'], + Region: ['EU', 'NA', 'AP', 'SA', 'AF'], + Currency: ['EUR', 'USD', 'GBP', 'JPY', 'BRL', 'CNY', 'KRW', 'RUB', 'AED'], + OS: ['Windows', 'macOS', 'Linux', 'iOS', 'Android'], + Browser: ['Chrome', 'Firefox', 'Safari', 'Edge'], + Screen: ['1080p', '1440p', '4K', 'Mobile'], + Theme: ['Light', 'Dark', 'Auto'], + Auth: ['OAuth', 'SAML', 'Password', 'MFA'], + }; + + const constraints: Condition[] = [ + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Language', value: 'de' }, + { operator: 'eq', field: 'Region', value: 'EU' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Language', value: 'ja' }, + { operator: 'eq', field: 'Region', value: 'AP' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Language', value: 'pt' }, + { operator: 'eq', field: 'Region', value: 'SA' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Region', value: 'EU' }, + { operator: 'in', field: 'Currency', values: ['EUR', 'GBP'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Region', value: 'AP' }, + { operator: 'in', field: 'Currency', values: ['JPY', 'CNY', 'KRW'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Region', value: 'SA' }, + { operator: 'in', field: 'Currency', values: ['BRL'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'OS', value: 'iOS' }, + { operator: 'in', field: 'Browser', values: ['Safari', 'Chrome'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Screen', value: 'Mobile' }, + { operator: 'in', field: 'OS', values: ['iOS', 'Android'] }, + ]}, + ]; + + const t0 = Date.now(); + const ctrl = new Controller(factors, { constraints }); + const rows = [...ctrl.makeAsync()]; + const t1 = Date.now(); + + let violations = 0; + for (const r of rows as any[]) { + if (r.Language === 'de' && r.Region !== 'EU') violations++; + if (r.Language === 'ja' && r.Region !== 'AP') violations++; + if (r.Language === 'pt' && r.Region !== 'SA') violations++; + if (r.Region === 'EU' && !['EUR','GBP'].includes(r.Currency)) violations++; + if (r.Region === 'AP' && !['JPY','CNY','KRW'].includes(r.Currency)) violations++; + if (r.Region === 'SA' && !['BRL'].includes(r.Currency)) violations++; + if (r.OS === 'iOS' && !['Safari','Chrome'].includes(r.Browser)) violations++; + if (r.Screen === 'Mobile' && !['iOS','Android'].includes(r.OS)) violations++; + } + + console.log(`Rows: ${rows.length}`); + console.log(`Time: ${t1 - t0}ms`); + console.log(`Progress: ${(ctrl.progress * 100).toFixed(1)}%`); + console.log(`Violations: ${violations}`); + + expect(violations).toBe(0); + expect(ctrl.progress).toBeGreaterThan(0.95); + }); +}); diff --git a/typescript/src/__tests__/filter.test.ts b/typescript/src/__tests__/filter.test.ts index d6ccad1..e7d6f0a 100644 --- a/typescript/src/__tests__/filter.test.ts +++ b/typescript/src/__tests__/filter.test.ts @@ -1,18 +1,24 @@ import { make, DictType, SuggestRowType } from "../"; - + const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; const os = ["iOS", "Android"]; const browser = ["FireFox", "Chrome", "Safari"]; test('exclude impossible combinations', () => { const factors = {machine, os, browser}; - const preFilter = (row: DictType) => { - return !( - (row.machine === 'iPhone' && row.os !== 'iOS') || - (row.machine !== 'iPhone' && row.os === 'iOS') - ); - }; - const rows = make(factors, { preFilter }); + const rows = make(factors, { + constraints: [ + // machine=iPhone ↔ os=iOS (bidirectional) + { operator: 'or', conditions: [ + { operator: 'ne', field: 'machine', value: 'iPhone' }, + { operator: 'eq', field: 'os', value: 'iOS' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'eq', field: 'machine', value: 'iPhone' }, + { operator: 'ne', field: 'os', value: 'iOS' }, + ]}, + ], + }); expect(rows.filter(row => row.machine === 'iPhone' && row.os === 'iOS').length).toBe(browser.length); expect(rows.filter(row => row.machine === 'iPhone' && row.os !== 'iOS').length).toBe(0); expect(rows.filter(row => row.machine !== 'iPhone' && row.os === 'iOS').length).toBe(0); @@ -25,7 +31,7 @@ test('exclude impossible combinations', () => { expect(rows.filter(row => row.machine === 'iPhone' && row.browser === 'FireFox').length).toBeGreaterThanOrEqual(1); expect(rows.filter(row => row.machine === 'iPhone' && row.browser === 'Chrome').length).toBeGreaterThanOrEqual(1); expect(rows.filter(row => row.machine === 'iPhone' && row.browser === 'Safari').length).toBeGreaterThanOrEqual(1); - + expect(rows.filter(row => row.machine === 'Pixel' && row.browser === 'FireFox').length).toBeGreaterThanOrEqual(1); expect(rows.filter(row => row.machine === 'Pixel' && row.browser === 'Chrome').length).toBeGreaterThanOrEqual(1); expect(rows.filter(row => row.machine === 'Pixel' && row.browser === 'Safari').length).toBeGreaterThanOrEqual(1); @@ -37,8 +43,12 @@ test('exclude impossible combinations', () => { test('Limited to iphone and iOS combinations only.', () => { const factors = {machine, os, browser}; - const preFilter = (row: SuggestRowType) => row.machine === 'iPhone' && row.os === 'iOS'; - const rows = make(factors, { preFilter }); + const rows = make(factors, { + constraints: [ + { operator: 'eq', field: 'machine', value: 'iPhone' }, + { operator: 'eq', field: 'os', value: 'iOS' }, + ], + }); expect(rows.length).toBe(browser.length); expect(rows.filter(row => row.machine === 'iPhone' && row.os === 'iOS').length).toBe(browser.length); expect(rows.filter(row => row.machine === 'Pixel').length).toBe(0); @@ -46,16 +56,13 @@ test('Limited to iphone and iOS combinations only.', () => { }); -test('Use a constant-false function for preFilter', () => { - const factors = {machine, os, browser}; - const preFilter = (row: DictType) => false; - const rows = make(factors, { preFilter }); - expect(rows).toEqual([]); -}); - -test('Use the wrong conditional function for preFilter', () => { +test('Use a constant-false constraint', () => { const factors = {machine, os, browser}; - const preFilter = (row: DictType) => row.machine === 'WindowsPhone'; - const rows = make(factors, { preFilter }); + const rows = make(factors, { + constraints: [ + // No machine value equals 'WindowsPhone', so this rejects everything + { operator: 'eq', field: 'machine', value: 'WindowsPhone' }, + ], + }); expect(rows).toEqual([]); }); diff --git a/typescript/src/__tests__/forward-check-complex.test.ts b/typescript/src/__tests__/forward-check-complex.test.ts new file mode 100644 index 0000000..bfcd78c --- /dev/null +++ b/typescript/src/__tests__/forward-check-complex.test.ts @@ -0,0 +1,327 @@ +import { Controller } from '../controller'; +import type { Condition } from '../types'; + +describe('forward check complex cases', () => { + + // Case 1: Deep chain (6 levels) with mixed narrowing. + // A=1→B∈{10,20}→C∈{100,200}→D∈{1000}→E∈{α,β}→F=X + // Many intermediate 2-value domains. + it('6-level deep chain with mixed narrowing', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: [1000, 2000, 3000], + E: ['α', 'β', 'γ'], + F: ['X', 'Y', 'Z'], + }; + + const constraints: Condition[] = [ + // A=1 → B∈{10,20} + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'in', field: 'B', values: [10, 20] }, + ]}, + // B∈{10,20} → C∈{100,200} + { operator: 'or', conditions: [ + { operator: 'in', field: 'B', values: [30] }, + { operator: 'in', field: 'C', values: [100, 200] }, + ]}, + // C∈{100,200} → D=1000 + { operator: 'or', conditions: [ + { operator: 'in', field: 'C', values: [300] }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + // D=1000 → E∈{α,β} + { operator: 'or', conditions: [ + { operator: 'ne', field: 'D', value: 1000 }, + { operator: 'in', field: 'E', values: ['α', 'β'] }, + ]}, + // E∈{α,β} → F=X + { operator: 'or', conditions: [ + { operator: 'in', field: 'E', values: ['γ'] }, + { operator: 'eq', field: 'F', value: 'X' }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + console.log('Case 1 - 6-level:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + for (const r of rows as any[]) { + if (r.A === 1) expect([10, 20]).toContain(r.B); + if ([10, 20].includes(r.B)) expect([100, 200]).toContain(r.C); + if ([100, 200].includes(r.C)) expect(r.D).toBe(1000); + if (r.D === 1000) expect(['α', 'β']).toContain(r.E); + if (['α', 'β'].includes(r.E)) expect(r.F).toBe('X'); + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 2: Multiple independent constraint chains crossing the same factors. + // Chain 1: A=1→B=10→C=100 + // Chain 2: D=α→B=20→E=X + // B is shared: A=1 forces B=10, D=α forces B=20. (A=1, D=α) is infeasible. + it('crossing chains sharing a factor', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: ['α', 'β', 'γ'], + E: ['X', 'Y', 'Z'], + }; + + const constraints: Condition[] = [ + // A=1 → B=10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + // B=10 → C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + // D=α → B=20 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'D', value: 'α' }, + { operator: 'eq', field: 'B', value: 20 }, + ]}, + // B=20 → E=X + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 20 }, + { operator: 'eq', field: 'E', value: 'X' }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + console.log('Case 2 - crossing chains:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + for (const r of rows as any[]) { + if (r.A === 1) expect(r.B).toBe(10); + if (r.B === 10) expect(r.C).toBe(100); + if (r.D === 'α') expect(r.B).toBe(20); + if (r.B === 20) expect(r.E).toBe('X'); + // A=1 and D=α can't coexist + expect(!(r.A === 1 && r.D === 'α')).toBe(true); + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 3: Web of mutual exclusions creating a Sudoku-like constraint. + // 4 factors, each with values {1,2,3,4}. No two factors may have the same value. + it('all-different: 4 factors must have distinct values', () => { + const vals = [1, 2, 3, 4]; + const factors = { A: vals, B: vals, C: vals, D: vals }; + + const constraints: Condition[] = [ + { operator: 'ne', field: 'A', target: 'B' }, + { operator: 'ne', field: 'A', target: 'C' }, + { operator: 'ne', field: 'A', target: 'D' }, + { operator: 'ne', field: 'B', target: 'C' }, + { operator: 'ne', field: 'B', target: 'D' }, + { operator: 'ne', field: 'C', target: 'D' }, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + console.log('Case 3 - all-different:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + for (const r of rows as any[]) { + const vs = [r.A, r.B, r.C, r.D]; + expect(new Set(vs).size).toBe(4); + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 4: Bidirectional implications creating equivalence classes. + // A=1↔B=10, B=10↔C=100, forming equivalence: {A=1, B=10, C=100} or none. + // Plus D and E as free factors to make pairs interesting. + it('bidirectional equivalence class', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: ['x', 'y'], + E: ['p', 'q'], + }; + + const constraints: Condition[] = [ + // A=1 → B=10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + // B=10 → A=1 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'A', value: 1 }, + ]}, + // B=10 → C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + // C=100 → B=10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'C', value: 100 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + console.log('Case 4 - bidirectional:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + for (const r of rows as any[]) { + // Equivalence: A=1 ↔ B=10 ↔ C=100 + if (r.A === 1) { expect(r.B).toBe(10); expect(r.C).toBe(100); } + if (r.B === 10) { expect(r.A).toBe(1); expect(r.C).toBe(100); } + if (r.C === 100) { expect(r.A).toBe(1); expect(r.B).toBe(10); } + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 5: Cascading exclusions — each factor value excludes multiple + // values from the next factor, creating a narrowing funnel. + // 5 factors with 5 values each. Heavy constraint web. + it('cascading exclusion funnel (5x5)', () => { + const factors = { + A: [1, 2, 3, 4, 5], + B: [1, 2, 3, 4, 5], + C: [1, 2, 3, 4, 5], + D: [1, 2, 3, 4, 5], + E: [1, 2, 3, 4, 5], + }; + + const constraints: Condition[] = [ + // A excludes its own value from B + { operator: 'ne', field: 'A', target: 'B' }, + // B excludes its own value from C + { operator: 'ne', field: 'B', target: 'C' }, + // C excludes its own value from D + { operator: 'ne', field: 'C', target: 'D' }, + // D excludes its own value from E + { operator: 'ne', field: 'D', target: 'E' }, + // Additionally: A value also can't equal C (skip one) + { operator: 'ne', field: 'A', target: 'C' }, + // B value also can't equal D + { operator: 'ne', field: 'B', target: 'D' }, + // C value also can't equal E + { operator: 'ne', field: 'C', target: 'E' }, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + console.log('Case 5 - cascading exclusion:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + for (const r of rows as any[]) { + expect(r.A).not.toBe(r.B); + expect(r.B).not.toBe(r.C); + expect(r.C).not.toBe(r.D); + expect(r.D).not.toBe(r.E); + expect(r.A).not.toBe(r.C); + expect(r.B).not.toBe(r.D); + expect(r.C).not.toBe(r.E); + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 6: Mix of IF-THEN chains and field-to-field comparisons. + // Simulates a realistic scenario with both kinds. + it('mixed chains and field comparisons', () => { + const factors = { + Priority: ['low', 'medium', 'high', 'critical'], + Assignee: ['alice', 'bob', 'carol'], + Reviewer: ['alice', 'bob', 'carol'], + Environment: ['dev', 'staging', 'prod'], + Approval: ['none', 'lead', 'director'], + }; + + const constraints: Condition[] = [ + // Assignee != Reviewer + { operator: 'ne', field: 'Assignee', target: 'Reviewer' }, + // critical → prod + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'critical' }, + { operator: 'eq', field: 'Environment', value: 'prod' }, + ]}, + // prod → director approval + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Environment', value: 'prod' }, + { operator: 'eq', field: 'Approval', value: 'director' }, + ]}, + // high → staging or prod + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'high' }, + { operator: 'in', field: 'Environment', values: ['staging', 'prod'] }, + ]}, + // staging → lead or director approval + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Environment', value: 'staging' }, + { operator: 'in', field: 'Approval', values: ['lead', 'director'] }, + ]}, + // low → no approval needed + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'low' }, + { operator: 'eq', field: 'Approval', value: 'none' }, + ]}, + // low → dev only + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'low' }, + { operator: 'eq', field: 'Environment', value: 'dev' }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + console.log('Case 6 - mixed:', JSON.stringify({ + ...ctrl.stats, completions: undefined, + })); + + for (const r of rows as any[]) { + expect(r.Assignee).not.toBe(r.Reviewer); + if (r.Priority === 'critical') expect(r.Environment).toBe('prod'); + if (r.Environment === 'prod') expect(r.Approval).toBe('director'); + if (r.Priority === 'high') expect(['staging', 'prod']).toContain(r.Environment); + if (r.Environment === 'staging') expect(['lead', 'director']).toContain(r.Approval); + if (r.Priority === 'low') { expect(r.Approval).toBe('none'); expect(r.Environment).toBe('dev'); } + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } + expect(ctrl.stats.progress).toBe(1); + }); +}); diff --git a/typescript/src/__tests__/forward-check-weakness.test.ts b/typescript/src/__tests__/forward-check-weakness.test.ts new file mode 100644 index 0000000..b2c35c3 --- /dev/null +++ b/typescript/src/__tests__/forward-check-weakness.test.ts @@ -0,0 +1,243 @@ +import { make, Controller, NeverMatch } from '../index'; +import type { Condition } from '../types'; + +describe('forward check weakness cases', () => { + + // Case 1: Domain stays at 2 values, but both conflict with a third factor. + // A=1 → B∈{10,20}, B=10 → C=100, B=20 → C=200 + // Pair (A=1, C=300) is infeasible: B must be 10 or 20, but both force C≠300. + // Forward check can't detect this because B doesn't narrow to 1 value. + it('two-branch: A=1→B∈{10,20}, B=10→C=100, B=20→C=200', () => { + const factors = { + A: [1, 2], + B: [10, 20, 30], + C: [100, 200, 300], + }; + + const constraints: Condition[] = [ + // IF A=1 THEN B IN {10, 20} + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'in', field: 'B', values: [10, 20] }, + ]}, + // IF B=10 THEN C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + // IF B=20 THEN C=200 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 20 }, + { operator: 'eq', field: 'C', value: 200 }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + + console.log('Case 1 - two-branch:'); + console.log(' stats:', JSON.stringify(ctrl.stats, null, 2)); + + // Verify constraints + for (const r of rows as any[]) { + if (r.A === 1) expect([10, 20]).toContain(r.B); + if (r.B === 10) expect(r.C).toBe(100); + if (r.B === 20) expect(r.C).toBe(200); + } + + // (A=1, C=300) is infeasible — should be pruned or reported + // Either progress is 100% or uncoveredPairs reports the infeasible pair + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + // The only uncoverable pair should involve A=1,C=300 + for (const up of ctrl.stats.uncoveredPairs) { + expect(up.pair).toHaveProperty('A'); + expect(up.pair).toHaveProperty('C'); + } + } else { + expect(ctrl.stats.progress).toBe(1); + } + }); + + // Case 2: Two unfilled factors jointly constrained. + // IF A=1 AND B=10 THEN C=100 + // Pair (A=1, C=200) is feasible (just need B≠10), but forward check + // might not see the interaction since B is unfilled. + it('joint condition: IF A=1 AND B=10 THEN C=100', () => { + const factors = { + A: [1, 2], + B: [10, 20], + C: [100, 200], + }; + + const constraints: Condition[] = [ + // IF A=1 AND B=10 THEN C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + + console.log('Case 2 - joint condition:'); + console.log(' stats:', JSON.stringify({ + ...ctrl.stats, + completions: undefined, + })); + + for (const r of rows as any[]) { + if (r.A === 1 && r.B === 10) expect(r.C).toBe(100); + } + + // (A=1, C=200) IS feasible (with B=20), so it must be covered + const a1c200 = (rows as any[]).some(r => r.A === 1 && r.C === 200); + expect(a1c200).toBe(true); + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 3: Diamond dependency. + // A=1 → B=10, A=1 → C=100, B=10 AND C=100 → D=1000 + // Pair (A=1, D=2000) is infeasible because A=1 forces B=10 and C=100, + // which together force D=1000. + it('diamond: A→B, A→C, B+C→D', () => { + const factors = { + A: [1, 2], + B: [10, 20], + C: [100, 200], + D: [1000, 2000], + }; + + const constraints: Condition[] = [ + // IF A=1 THEN B=10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + // IF A=1 THEN C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + // IF B=10 AND C=100 THEN D=1000 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'ne', field: 'C', value: 100 }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + + console.log('Case 3 - diamond:'); + console.log(' stats:', JSON.stringify({ + ...ctrl.stats, + completions: undefined, + })); + + for (const r of rows as any[]) { + if (r.A === 1) { expect(r.B).toBe(10); expect(r.C).toBe(100); } + if (r.B === 10 && r.C === 100) expect(r.D).toBe(1000); + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } else { + expect(ctrl.stats.progress).toBe(1); + } + }); + + // Case 4: Mutual exclusion via separate constraints. + // IF A=1 THEN B≠10, IF A=1 THEN B≠20 → B must be 30 when A=1. + // Forward check should narrow B to {30} via elimination. + it('elimination: A=1 excludes B=10 and B=20, forcing B=30', () => { + const factors = { + A: [1, 2], + B: [10, 20, 30], + C: [100, 200], + }; + + const constraints: Condition[] = [ + // IF A=1 THEN B<>10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'ne', field: 'B', value: 10 }, + ]}, + // IF A=1 THEN B<>20 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'ne', field: 'B', value: 20 }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + + console.log('Case 4 - elimination:'); + console.log(' stats:', JSON.stringify({ + ...ctrl.stats, + completions: undefined, + })); + + for (const r of rows as any[]) { + if (r.A === 1) expect(r.B).toBe(30); + } + + expect(ctrl.stats.progress).toBe(1); + }); + + // Case 5: Longer chain with 2-value domain at intermediate step. + // A=1 → B∈{10,20}, B∈{10,20} → C∈{100,200}, C∈{100,200} → D=1000 + // Pair (A=1, D=2000) is infeasible through the chain. + // B narrows to {10,20} (not 1), so standard forward check can't propagate further. + it('chain with 2-value bottleneck', () => { + const factors = { + A: [1, 2], + B: [10, 20, 30], + C: [100, 200, 300], + D: [1000, 2000], + }; + + const constraints: Condition[] = [ + // IF A=1 THEN B IN {10, 20} + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'in', field: 'B', values: [10, 20] }, + ]}, + // IF B IN {10, 20} THEN C IN {100, 200} + { operator: 'or', conditions: [ + { operator: 'in', field: 'B', values: [30] }, + { operator: 'in', field: 'C', values: [100, 200] }, + ]}, + // IF C IN {100, 200} THEN D=1000 + { operator: 'or', conditions: [ + { operator: 'in', field: 'C', values: [300] }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + ]; + + const ctrl = new Controller(factors, { constraints }); + const rows = ctrl.make(); + + console.log('Case 5 - chain with bottleneck:'); + console.log(' stats:', JSON.stringify({ + ...ctrl.stats, + completions: undefined, + })); + + for (const r of rows as any[]) { + if (r.A === 1) expect([10, 20]).toContain(r.B); + if ([10, 20].includes(r.B)) expect([100, 200]).toContain(r.C); + if ([100, 200].includes(r.C)) expect(r.D).toBe(1000); + } + + if (ctrl.stats.uncoveredPairs.length > 0) { + console.log(' uncovered:', ctrl.stats.uncoveredPairs); + } else { + expect(ctrl.stats.progress).toBe(1); + } + }); +}); diff --git a/typescript/src/__tests__/forward-check.test.ts b/typescript/src/__tests__/forward-check.test.ts new file mode 100644 index 0000000..970ac68 --- /dev/null +++ b/typescript/src/__tests__/forward-check.test.ts @@ -0,0 +1,103 @@ +import { make } from '../index'; +import type { Condition } from '../types'; + +describe('forward checking (constraint chain propagation)', () => { + it('respects transitive constraint chain: Language=de → Region=EU → Currency∈{EUR,GBP}', () => { + const factors = { + Language: ['de', 'en', 'ja', 'fr', 'es'], + Region: ['EU', 'NA', 'AP', 'SA'], + Currency: ['EUR', 'USD', 'GBP', 'JPY', 'BRL'], + OS: ['Windows', 'macOS', 'Linux'], + Browser: ['Chrome', 'Firefox', 'Safari', 'Edge'], + }; + + const constraints: Condition[] = [ + // IF Language=de THEN Region=EU + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Language', value: 'de' }, + { operator: 'eq', field: 'Region', value: 'EU' }, + ]}, + // IF Region=EU THEN Currency IN {EUR, GBP} + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Region', value: 'EU' }, + { operator: 'in', field: 'Currency', values: ['EUR', 'GBP'] }, + ]}, + ]; + + const rows = make(factors, { constraints }); + + expect(rows.length).toBeGreaterThan(0); + + for (const r of rows) { + if (r.Language === 'de') { + expect(r.Region).toBe('EU'); + } + if (r.Region === 'EU') { + expect(['EUR', 'GBP']).toContain(r.Currency); + } + } + }); + + it('handles 3-level chain: A→B→C→D', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: [1000, 2000, 3000], + }; + + const constraints: Condition[] = [ + // IF A=1 THEN B=10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + // IF B=10 THEN C=100 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + // IF C=100 THEN D=1000 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'C', value: 100 }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + ]; + + const rows = make(factors, { constraints }); + expect(rows.length).toBeGreaterThan(0); + + for (const r of rows) { + if (r.A === 1) expect(r.B).toBe(10); + if (r.B === 10) expect(r.C).toBe(100); + if (r.C === 100) expect(r.D).toBe(1000); + } + }); + + it('does not over-prune: unconstrained combinations remain valid', () => { + const factors = { + A: [1, 2], + B: [10, 20], + C: [100, 200], + }; + + const constraints: Condition[] = [ + // IF A=1 THEN B=10 + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + ]; + + const rows = make(factors, { constraints }); + + // A=2 should still pair freely with B=20 and any C + const a2b20 = rows.some(r => r.A === 2 && r.B === 20); + expect(a2b20).toBe(true); + + // A=1 must always have B=10 + for (const r of rows) { + if (r.A === 1) expect(r.B).toBe(10); + } + }); +}); diff --git a/typescript/src/__tests__/heavy-coverage.test.ts b/typescript/src/__tests__/heavy-coverage.test.ts new file mode 100644 index 0000000..834f54f --- /dev/null +++ b/typescript/src/__tests__/heavy-coverage.test.ts @@ -0,0 +1,149 @@ +import { PictModel } from '../pict'; +import * as fs from 'fs'; +import * as path from 'path'; + +describe('heavy.pict coverage check', () => { + it('checks pairwise coverage of PICT output', () => { + const modelText = fs.readFileSync( + path.resolve(__dirname, '../../../heavy.pict'), + 'utf-8', + ); + const model = new PictModel(modelText); + const factors = model.parameters; + const keys = Object.keys(factors); + + // The 65 rows from PICT output + const rawRows = `EU fr EUR Tablet Chrome Guest PayPal PickupPoint None Single Fashion InStock Reject Exclusive Home Evening Message None None New No No +US en USD Desktop Chrome Premium DebitCard Express BULK20 Bulk Grocery InStock Pass Exclusive Hotel Morning WrapAndMessage Partial Plus Established Yes Yes +US zh USD iOSApp Safari Guest CreditCard Standard FREESHIP Large Electronics BackOrder Review Exclusive POBox Night Wrap None None Recent No Yes +JP en JPY MobileWeb Chrome Member BankTransfer StorePickup Welcome10 Small Furniture BackOrder Review Inclusive Home None None Partial Basic New Yes No +US zh USD AndroidApp Chrome Member BankTransfer Standard None Medium Subscription LowStock Pass Exclusive Office Afternoon Message None Basic Old Yes No +JP ja JPY iOSApp Safari Corporate DebitCard Standard FREESHIP Single Subscription LowStock Pass Inclusive Office Evening WrapAndMessage Partial None Established No Yes +APAC en JPY AndroidApp Chrome Corporate Invoice Standard Welcome10 Single Grocery PreOrder Review Inclusive POBox Afternoon Wrap None Basic New No Yes +EU fr EUR iOSApp Safari Premium ApplePay Express VIP15 Large Grocery LowStock Review Inclusive Office None None Partial Plus Recent Yes Yes +JP ja JPY MobileWeb Chrome Premium CreditCard Standard None Medium Fashion PreOrder Review Inclusive Hotel Night Message Full Plus Old No No +APAC zh JPY AndroidApp Chrome Premium GooglePay Express VIP15 Small Furniture InStock Pass Exclusive Hotel Evening None None None Old No Yes +JP ja JPY Desktop Chrome Corporate Invoice SameDay None Large Electronics InStock Reject Inclusive Home Afternoon WrapAndMessage None Basic Recent Yes No +EU zh EUR MobileWeb Chrome Corporate Invoice Standard BULK20 Bulk Digital BackOrder Pass Exclusive Home Night None None None Established Yes No +JP ja JPY AndroidApp Chrome Premium GooglePay StorePickup VIP15 Bulk Electronics BackOrder Pass Inclusive POBox Morning Message Partial Plus New No No +EU de EUR Tablet Chrome Member CreditCard Standard BULK20 Bulk Subscription LowStock Review Inclusive POBox None Wrap Partial Basic Old Yes Yes +JP zh JPY Desktop Chrome Guest CreditCard SameDay Welcome10 Small Fashion LowStock Pass Inclusive Office Morning Wrap None None New No Yes +EU de EUR iOSApp Safari Member ApplePay PickupPoint FREESHIP Medium Fashion InStock Review Exclusive Hotel Morning WrapAndMessage Partial Basic New Yes No +EU en EUR AndroidApp Chrome Premium GooglePay PickupPoint None Medium Furniture LowStock Reject Inclusive Office Night Wrap None Plus Recent Yes Yes +EU fr EUR Desktop Chrome Guest PayPal Standard Welcome10 Medium Subscription BackOrder Pass Exclusive Hotel Night WrapAndMessage None None New No Yes +EU de EUR MobileWeb Chrome Guest PayPal Standard None Small Electronics PreOrder Reject Exclusive Office None None None None Established No Yes +EU de EUR Tablet Chrome Premium DebitCard Standard Welcome10 Large Digital PreOrder Pass Inclusive Home Evening None Partial Plus New Yes Yes +APAC en JPY iOSApp Safari Premium DebitCard Standard None Bulk Digital LowStock Review Exclusive Home Afternoon None Full None Recent Yes No +JP en JPY MobileWeb Chrome Guest PayPal SameDay FREESHIP Large Grocery LowStock Review Inclusive Home Morning Message None None Old No No +JP zh JPY iOSApp Safari Premium ApplePay StorePickup None Single Furniture BackOrder Review Inclusive POBox Evening Wrap Full Basic Established Yes Yes +EU fr EUR MobileWeb Chrome Member BankTransfer PickupPoint Welcome10 Bulk Electronics InStock Pass Inclusive POBox Evening Wrap None None New Yes No +JP en JPY Tablet Chrome Premium CreditCard StorePickup VIP15 Medium Grocery LowStock Pass Inclusive Hotel Evening WrapAndMessage None Basic Recent Yes Yes +US zh USD iOSApp Safari Corporate ApplePay Standard None Small Digital PreOrder Reject Exclusive Home None None None Basic Old No Yes +APAC zh JPY Tablet Chrome Corporate Invoice Standard None Small Subscription BackOrder Reject Inclusive Office Morning Message None None Recent Yes Yes +EU fr EUR Desktop Chrome Member BankTransfer Standard FREESHIP Single Digital InStock Review Inclusive Home Morning None None Basic Established Yes Yes +EU fr EUR AndroidApp Chrome Premium GooglePay PickupPoint None Small Fashion InStock Pass Inclusive Office None WrapAndMessage Full Plus Established Yes Yes +APAC zh JPY iOSApp Safari Premium ApplePay Express VIP15 Medium Electronics LowStock Pass Inclusive Home Night Message Partial Basic Established Yes Yes +EU fr EUR Desktop Chrome Corporate CreditCard PickupPoint BULK20 Bulk Furniture BackOrder Pass Inclusive Office Afternoon None Partial None Old No Yes +EU de EUR MobileWeb Chrome Premium DebitCard Express VIP15 Single Fashion BackOrder Pass Inclusive Hotel Afternoon Wrap None Plus Recent Yes Yes +APAC zh JPY Tablet Chrome Member BankTransfer Standard None Large Furniture PreOrder Pass Inclusive Hotel Night WrapAndMessage Partial None Recent Yes Yes +JP ja JPY iOSApp Safari Guest PayPal SameDay Welcome10 Medium Fashion InStock Pass Inclusive Hotel None None None None New No Yes +APAC en JPY AndroidApp Chrome Guest CreditCard Standard FREESHIP Single Digital InStock Pass Inclusive Home None None None None Old No Yes +EU de EUR AndroidApp Chrome Premium GooglePay Standard None Large Subscription PreOrder Review Inclusive Home Morning Wrap Full Plus New Yes Yes +EU de EUR Desktop Chrome Member DebitCard Express None Medium Furniture InStock Reject Inclusive POBox None Message None Basic New No Yes +US zh USD MobileWeb Chrome Premium DebitCard Express None Single Electronics InStock Pass Exclusive Hotel Night WrapAndMessage Full Plus Old Yes Yes +APAC en JPY iOSApp Safari Premium ApplePay Standard FREESHIP Small Subscription InStock Pass Inclusive POBox Afternoon None None Plus Established Yes Yes +JP ja JPY Tablet Chrome Member BankTransfer SameDay BULK20 Bulk Electronics InStock Pass Inclusive Home Evening Message Partial None Established Yes Yes +JP en JPY Desktop Chrome Corporate Invoice StorePickup None Large Fashion InStock Reject Inclusive Hotel Evening None None None Old Yes Yes +US zh USD Tablet Chrome Guest PayPal Express Welcome10 Single Fashion InStock Pass Exclusive POBox Afternoon Wrap None None New No Yes +JP ja JPY AndroidApp Chrome Premium DebitCard SameDay None Small Grocery InStock Pass Inclusive Home Night Wrap Full Plus New Yes Yes +EU de EUR AndroidApp Chrome Member GooglePay Standard None Bulk Grocery BackOrder Reject Inclusive POBox Afternoon WrapAndMessage None Basic New Yes Yes +JP ja JPY Tablet Chrome Corporate Invoice Express FREESHIP Medium Furniture LowStock Pass Inclusive Home None None Partial None New Yes Yes +APAC en JPY iOSApp Safari Member BankTransfer Standard BULK20 Bulk Fashion PreOrder Pass Inclusive Home None None None None Recent Yes Yes +US en USD Desktop Chrome Corporate Invoice Standard Welcome10 Single Furniture PreOrder Pass Exclusive Home Evening Message None None New Yes Yes +EU de EUR Desktop Chrome Member BankTransfer Express FREESHIP Bulk Grocery InStock Pass Inclusive Home Night None None None New Yes Yes +APAC en JPY Desktop Chrome Guest PayPal Standard None Single Furniture InStock Pass Inclusive Home Morning None None None Recent No Yes +JP en JPY Desktop Chrome Guest DebitCard StorePickup None Large Electronics InStock Pass Inclusive Office Night None None None Established No Yes +JP ja JPY iOSApp Safari Premium ApplePay Standard VIP15 Medium Digital PreOrder Pass Inclusive Home None None None None New Yes Yes +JP zh JPY AndroidApp Chrome Corporate GooglePay StorePickup BULK20 Bulk Grocery InStock Pass Inclusive Home Afternoon None None None New Yes Yes +JP ja JPY AndroidApp Chrome Guest GooglePay SameDay FREESHIP Single Electronics InStock Pass Inclusive Home None None None None New No Yes +JP ja JPY AndroidApp Chrome Guest PayPal StorePickup None Single Electronics InStock Pass Inclusive Home None None None None New No Yes +EU fr EUR iOSApp Safari Corporate Invoice Standard None Single Electronics PreOrder Pass Inclusive Home None None None None New Yes Yes +APAC en JPY MobileWeb Chrome Guest PayPal Standard None Single Digital InStock Pass Inclusive Home None None None None New No Yes +EU zh EUR Desktop Chrome Premium DebitCard PickupPoint VIP15 Large Electronics InStock Pass Inclusive Home None None None None New Yes Yes +US en USD AndroidApp Chrome Premium GooglePay Standard VIP15 Single Subscription InStock Pass Exclusive Home None None None None New Yes Yes +EU de EUR Desktop Chrome Corporate Invoice PickupPoint None Single Electronics InStock Pass Inclusive Home None None None None New Yes Yes +JP ja JPY MobileWeb Chrome Guest CreditCard Standard None Single Subscription InStock Reject Inclusive Home None None None None Established No Yes +JP ja JPY AndroidApp Chrome Guest GooglePay Standard Welcome10 Single Digital InStock Pass Inclusive Home None None None None New No Yes +JP ja JPY iOSApp Safari Premium ApplePay SameDay VIP15 Single Electronics InStock Pass Inclusive Home None None None None New Yes Yes +EU fr EUR Desktop Chrome Premium DebitCard Standard None Single Electronics InStock Pass Inclusive Home None None Full None New Yes Yes +JP ja JPY iOSApp Safari Guest ApplePay Standard Welcome10 Single Electronics InStock Pass Inclusive Home None None None None New No Yes +JP ja JPY Tablet Chrome Premium CreditCard Express None Single Electronics InStock Pass Inclusive Home None None Full None New Yes Yes`; + + const rows = rawRows.split('\n').map(line => { + const vals = line.split('\t'); + const obj: Record = {}; + keys.forEach((k, i) => { obj[k] = vals[i]; }); + return obj; + }); + + console.log(`Rows: ${rows.length}`); + + // Check constraint violations + let violations = 0; + for (const r of rows) { + if (!model.filter(r)) { + violations++; + } + } + console.log(`Constraint violations: ${violations}`); + + // Compute pairwise coverage + // Total possible pairs = sum over all factor pairs of |fi| * |fj| + // Covered = pairs that appear in at least one row + const covered = new Set(); + let totalPossible = 0; + + for (let i = 0; i < keys.length; i++) { + for (let j = i + 1; j < keys.length; j++) { + const ki = keys[i]; + const kj = keys[j]; + const vi = factors[ki]; + const vj = factors[kj]; + totalPossible += vi.length * vj.length; + + for (const row of rows) { + covered.add(`${ki}=${row[ki]}|${kj}=${row[kj]}`); + } + } + } + + // Count how many of the "possible" pairs actually appear + // But some pairs are impossible due to constraints, so we also + // count "feasible" pairs + let coveredCount = 0; + let infeasibleCount = 0; + for (let i = 0; i < keys.length; i++) { + for (let j = i + 1; j < keys.length; j++) { + const ki = keys[i]; + const kj = keys[j]; + for (const vi of factors[ki]) { + for (const vj of factors[kj]) { + const pairKey = `${ki}=${vi}|${kj}=${vj}`; + if (covered.has(pairKey)) { + coveredCount++; + } + } + } + } + } + + const rawCoverage = coveredCount / totalPossible; + console.log(`Total possible pairs: ${totalPossible}`); + console.log(`Covered pairs: ${coveredCount}`); + console.log(`Raw coverage: ${(rawCoverage * 100).toFixed(1)}%`); + console.log(`Uncovered: ${totalPossible - coveredCount}`); + + // This is PICT's output, so coverage should be high + expect(rawCoverage).toBeGreaterThan(0.5); + }); +}); diff --git a/typescript/src/__tests__/heavy-covertable.test.ts b/typescript/src/__tests__/heavy-covertable.test.ts new file mode 100644 index 0000000..fba3248 --- /dev/null +++ b/typescript/src/__tests__/heavy-covertable.test.ts @@ -0,0 +1,85 @@ +import { PictModel } from '../pict'; +import * as fs from 'fs'; +import * as path from 'path'; + +describe('heavy.pict covertable generation', () => { + it('generates with forward checking and measures coverage', () => { + const modelText = fs.readFileSync( + path.resolve(__dirname, '../../../heavy.pict'), + 'utf-8', + ); + const model = new PictModel(modelText); + const factors = model.parameters; + const keys = Object.keys(factors); + + const t0 = Date.now(); + const rows = model.make(); + const t1 = Date.now(); + + const stats = model.stats!; + console.log(`Rows: ${rows.length}`); + console.log(`Time: ${t1 - t0}ms`); + console.log(`Stats:`, JSON.stringify({ + totalPairs: stats.totalPairs, + prunedPairs: stats.prunedPairs, + coveredPairs: stats.coveredPairs, + progress: `${(stats.progress * 100).toFixed(1)}%`, + rowCount: stats.rowCount, + uncoveredPairs: stats.uncoveredPairs.length, + }, null, 2)); + // Show top completions (factors most filled by close) + const compEntries = Object.entries(stats.completions) + .map(([k, v]) => [k, Object.values(v).reduce((a, b) => a + b, 0)] as [string, number]) + .sort((a, b) => b[1] - a[1]); + console.log(`Top completions:`, compEntries.slice(0, 5)); + console.log(`All completions:`, JSON.stringify(stats.completions, null, 2)); + + // Check constraint violations + let violations = 0; + for (const r of rows) { + if (!model.filter(r)) { + violations++; + } + } + console.log(`Constraint violations: ${violations}`); + + // Compute pairwise coverage + const covered = new Set(); + let totalPossible = 0; + + for (let i = 0; i < keys.length; i++) { + for (let j = i + 1; j < keys.length; j++) { + const ki = keys[i]; + const kj = keys[j]; + totalPossible += factors[ki].length * factors[kj].length; + + for (const row of rows) { + covered.add(`${ki}=${(row as any)[ki]}|${kj}=${(row as any)[kj]}`); + } + } + } + + let coveredCount = 0; + for (let i = 0; i < keys.length; i++) { + for (let j = i + 1; j < keys.length; j++) { + const ki = keys[i]; + const kj = keys[j]; + for (const vi of factors[ki]) { + for (const vj of factors[kj]) { + if (covered.has(`${ki}=${vi}|${kj}=${vj}`)) { + coveredCount++; + } + } + } + } + } + + const rawCoverage = coveredCount / totalPossible; + console.log(`Total possible pairs: ${totalPossible}`); + console.log(`Covered pairs: ${coveredCount}`); + console.log(`Raw coverage: ${(rawCoverage * 100).toFixed(1)}%`); + + expect(violations).toBe(0); + expect(rawCoverage).toBeGreaterThan(0.5); + }, 120000); +}); diff --git a/typescript/src/__tests__/index.test.ts b/typescript/src/__tests__/index.test.ts index db68b71..7caeae2 100644 --- a/typescript/src/__tests__/index.test.ts +++ b/typescript/src/__tests__/index.test.ts @@ -1,12 +1,12 @@ -import { default as make, sorters, criteria } from '../index'; +import { make, sorters, criteria } from '../index'; import { product, combinations, range, len, all, getItems } from '../lib'; import { FactorsType, ScalarType, DictType, PairType } from '../types'; -const getPairs = function* (factors: FactorsType, length = 2) { +const getPairs = function* (factors: FactorsType, strength = 2) { const allKeys = getItems(factors).map(([k, _]) => k); - for (let keys of combinations(allKeys, length)) { + for (let keys of combinations(allKeys, strength)) { // @ts-ignore TS7015 - const factorsList = range(0, length).map(i => factors[keys[i]]); + const factorsList = range(0, strength).map(i => factors[keys[i]]); for (let pair of product(...factorsList)) { yield pair as string[]; } @@ -22,9 +22,9 @@ test('2pair', () => { ["i", "j"], ["k", "l", "m", "n"], ]; - const length = 2; - const rows = make(factors, { length, criterion: criteria.simple }); - for (let pair of getPairs(factors, length)) { + const strength = 2; + const rows = make(factors, { strength, criterion: criteria.simple }); + for (let pair of getPairs(factors, strength)) { let final = true; for (let row of rows) { if (all(pair.map(p => row.indexOf(p) !== -1))) { @@ -47,9 +47,9 @@ test('3pair', () => { ["i", "j"], ["k", "l", "m", "n"], ]; - const length = 3; - const rows = make(factors, { length }); - for (let pair of getPairs(factors, length)) { + const strength = 3; + const rows = make(factors, { strength }); + for (let pair of getPairs(factors, strength)) { let final = true; for (let row of rows) { if (all(pair.map(p => row.indexOf(p) !== -1))) { @@ -63,22 +63,26 @@ test('3pair', () => { } }); -test('prefilter excludes specified pairs before', () => { +test('constraints exclude specified pairs before', () => { const factors = [ ["a", "b", "c"], ["d", "e"], ["f"], ]; - const preFilter = (row: DictType) => { - if (row[0] === "a" && row[1] === "d") { - return false; - } - if (row[0] === "b" && row[1] === "e") { - return false; - } - return true; - } - const rows = make(factors, { preFilter }); + const rows = make(factors, { + constraints: [ + // NOT (0="a" AND 1="d") + { operator: 'not', condition: { operator: 'and', conditions: [ + { operator: 'eq', field: '0', value: 'a' }, + { operator: 'eq', field: '1', value: 'd' }, + ]}}, + // NOT (0="b" AND 1="e") + { operator: 'not', condition: { operator: 'and', conditions: [ + { operator: 'eq', field: '0', value: 'b' }, + { operator: 'eq', field: '1', value: 'e' }, + ]}}, + ], + }); const unexpectedPairs = [["a", "d"], ["b", "e"]]; for (let pair of unexpectedPairs) { for (let row of rows) { @@ -98,10 +102,10 @@ test("greedy sorter should make rows less than seed's one with 2", () => { ["m", "n", "o"], ]; let len1 = 0, len2 = 0; - const length = 2; + const strength = 2; for (let i of range(0, 10)) { - const rows1 = make(factors, { length, seed: Math.random(), sorter: sorters.hash, criterion: criteria.greedy }); - const rows2 = make(factors, { length, seed: Math.random(), sorter: sorters.hash, criterion: criteria.simple }); + const rows1 = make(factors, { strength, salt: Math.random(), sorter: sorters.hash, criterion: criteria.greedy }); + const rows2 = make(factors, { strength, salt: Math.random(), sorter: sorters.hash, criterion: criteria.simple }); len1 += len(rows1); len2 += len(rows2); } @@ -117,10 +121,10 @@ test("greedy sorter should make rows less than seed's one with 3", () => { ["m", "n", "o"], ]; let len1 = 0, len2 = 0; - const length = 3; + const strength = 3; for (let i of range(0, 10)) { - const rows1 = make(factors, { length, seed: Math.random(), sorter: sorters.hash, criterion: criteria.greedy }); - const rows2 = make(factors, { length, seed: Math.random(), sorter: sorters.hash, criterion: criteria.simple }); + const rows1 = make(factors, { strength, salt: Math.random(), sorter: sorters.hash, criterion: criteria.greedy }); + const rows2 = make(factors, { strength, salt: Math.random(), sorter: sorters.hash, criterion: criteria.simple }); len1 += len(rows1); len2 += len(rows2); } @@ -142,6 +146,127 @@ test('random sorter makes different rows everytime', () => { } }); +test('presets are included in the output (full row)', () => { + const factors = { + A: ['a1', 'a2', 'a3'], + B: ['b1', 'b2', 'b3'], + C: ['c1', 'c2'], + }; + const rows = make(factors, { + presets: [ + { A: 'a1', B: 'b1', C: 'c1' }, + ], + }); + // The full preset row must appear in the output + const found = rows.some((r: any) => r.A === 'a1' && r.B === 'b1' && r.C === 'c1'); + expect(found).toBe(true); +}); + +test('presets are completed when partial', () => { + const factors = { + A: ['a1', 'a2'], + B: ['b1', 'b2'], + C: ['c1', 'c2'], + }; + const rows = make(factors, { + presets: [ + { A: 'a1' }, // partial: B and C will be filled in + ], + }); + // First row should have A === 'a1' and B/C filled in + expect(rows[0]).toBeDefined(); + expect((rows[0] as any).A).toBe('a1'); + expect((rows[0] as any).B).toBeDefined(); + expect((rows[0] as any).C).toBeDefined(); +}); + +test('presets violating constraints are silently dropped', () => { + const factors = { + OS: ['iOS', 'Android'], + Browser: ['Safari', 'Chrome'], + }; + const rows = make(factors, { + constraints: [ + // NOT (OS=iOS AND Browser=Chrome) + { operator: 'not' as const, condition: { operator: 'and' as const, conditions: [ + { operator: 'eq' as const, field: 'OS', value: 'iOS' }, + { operator: 'eq' as const, field: 'Browser', value: 'Chrome' }, + ]}}, + ], + presets: [ + { OS: 'iOS', Browser: 'Chrome' }, // violates constraint — must be dropped + { OS: 'Android', Browser: 'Safari' }, // valid — must appear + ], + }); + // Bad preset should not appear + const bad = rows.some((r: any) => r.OS === 'iOS' && r.Browser === 'Chrome'); + expect(bad).toBe(false); + // Good preset should appear + const good = rows.some((r: any) => r.OS === 'Android' && r.Browser === 'Safari'); + expect(good).toBe(true); + // All output rows must satisfy the constraint + for (const r of rows) { + expect((r as any).OS === 'iOS' && (r as any).Browser === 'Chrome').toBe(false); + } +}); + +test('presets with unknown values are ignored', () => { + const factors = { + A: ['a1', 'a2'], + B: ['b1', 'b2'], + }; + const rows = make(factors, { + presets: [ + { A: 'unknown', B: 'b1' }, + ], + }); + // Pairwise coverage should still be satisfied for known values + for (const a of ['a1', 'a2']) { + for (const b of ['b1', 'b2']) { + const found = rows.some((r: any) => r.A === a && r.B === b); + expect(found).toBe(true); + } + } +}); + +test('presets with array factors use numeric keys', () => { + const factors = [ + ['a1', 'a2'], + ['b1', 'b2'], + ]; + const rows = make(factors, { + presets: [ + { 0: 'a1', 1: 'b1' } as any, + ], + }); + // The preset should appear + const found = rows.some((r: any[]) => r[0] === 'a1' && r[1] === 'b1'); + expect(found).toBe(true); +}); + +test('presets cover pairs and reduce generated rows', () => { + const factors = { + A: ['a1', 'a2', 'a3'], + B: ['b1', 'b2', 'b3'], + }; + const baseRows = make(factors); + const presetRows = make(factors, { + presets: [ + { A: 'a1', B: 'b1' }, + { A: 'a2', B: 'b2' }, + ], + }); + // Total row count should still cover the same pairs + const allPairs = new Set(); + for (const r of presetRows) { + allPairs.add(`${(r as any).A}|${(r as any).B}`); + } + // All 9 pairs covered + expect(allPairs.size).toBe(9); + // Same total count (or close to it) — presets shouldn't bloat the output + expect(presetRows.length).toBe(baseRows.length); +}); + test('dict type factors make dict row', () => { const factors = { 'key1': ["a", "b", "c"], diff --git a/typescript/src/__tests__/pict.test.ts b/typescript/src/__tests__/pict.test.ts index ad75558..c15dfb1 100644 --- a/typescript/src/__tests__/pict.test.ts +++ b/typescript/src/__tests__/pict.test.ts @@ -1,391 +1,1239 @@ -import { PictConstraintsLexer } from "../utils/pict"; +import { PictModel, PictModelError, weightsByValue } from "../pict"; +import { make } from "../index"; + +// Helper: extract just the messages so existing tests can keep using string-based matchers. +const errorMessages = (m: PictModel) => m.issues.map(i => i.message); + +describe('PictModel issues', () => { + it('records source/index/line for parameter errors', () => { + const model = new PictModel(` +A: 1, 2, 3 +Empty: +B: x, y +`); + const factorIssues = model.issues.filter(i => i.source === 'factor'); + expect(factorIssues).toHaveLength(1); + expect(factorIssues[0].severity).toBe('error'); + expect(factorIssues[0].source).toBe('factor'); + expect(factorIssues[0].index).toBe(1); // 0-based: A is 0, Empty is 1, B is 2 + expect(factorIssues[0].line).toBe(3); // leading newline → "A:" is line 2, "Empty:" is line 3 + expect(factorIssues[0].message).toMatch(/No values for parameter "Empty"/); + }); + + it('records line for parameter reference errors', () => { + const model = new PictModel(` +A: 1, 2 +B: , 3 +`); + const factorIssues = model.issues.filter(i => i.source === 'factor'); + expect(factorIssues).toHaveLength(1); + expect(factorIssues[0].index).toBe(1); // B is the second factor (index 1) + expect(factorIssues[0].line).toBe(3); + expect(factorIssues[0].message).toMatch(/Unknown parameter reference/); + }); + + it('records source/index/line for constraint errors', () => { + const model = new PictModel(` +A: 1, 2 +B: 3, 4 + +IF [A] = 1 THEN [B] = 3; +IF [A] @ 2 THEN [B] = 4; +`); + const constraintIssues = model.issues.filter(i => i.source === 'constraint'); + expect(constraintIssues).toHaveLength(1); + expect(constraintIssues[0].source).toBe('constraint'); + // The bad constraint is the second filter (index 1) + expect(constraintIssues[0].index).toBe(1); + expect(constraintIssues[0].line).toBe(6); + expect(constraintIssues[0].message).toMatch(/Unknown comparison operator: @/); + }); + + it('strict mode throws PictModelError on errors', () => { + expect(() => new PictModel('broken line', { strict: true })).toThrow(PictModelError); + }); + + it('strict mode does not throw when there are no errors', () => { + expect(() => new PictModel('A: 1, 2\nB: 3, 4', { strict: true })).not.toThrow(); + }); + + it('PictModelError exposes the issues array', () => { + try { + new PictModel('broken line', { strict: true }); + throw new Error('expected throw'); + } catch (e) { + expect(e).toBeInstanceOf(PictModelError); + expect((e as PictModelError).issues.length).toBeGreaterThan(0); + expect((e as PictModelError).issues[0].severity).toBe('error'); + } + }); + + it('non-strict mode collects issues without throwing', () => { + const model = new PictModel('broken line'); + expect(model.issues.length).toBeGreaterThan(0); + }); +}); + +describe('PictModel parameters', () => { + it('parses basic PICT model definition', () => { + const model = new PictModel(` +Type: Single, Span, Stripe, Mirror, RAID-5 +Size: 10, 100, 500, 1000, 5000, 10000, 40000 +Format method: Quick, Slow +File system: FAT, FAT32, NTFS +Cluster size: 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 +Compression: On, Off + `); + expect(model.parameters).toEqual({ + "Type": ["Single", "Span", "Stripe", "Mirror", "RAID-5"], + "Size": [10, 100, 500, 1000, 5000, 10000, 40000], + "Format method": ["Quick", "Slow"], + "File system": ["FAT", "FAT32", "NTFS"], + "Cluster size": [512, 1024, 2048, 4096, 8192, 16384, 32768, 65536], + "Compression": ["On", "Off"], + }); + }); + + it('skips empty lines and comments', () => { + const model = new PictModel(` +# This is a comment +A: 1, 2, 3 + +# Another comment +B: x, y + `); + expect(model.parameters).toEqual({ + "A": [1, 2, 3], + "B": ["x", "y"], + }); + }); + + it('line without colon is treated as constraint and produces error', () => { + const model = new PictModel('No colon here'); + expect(Object.keys(model.parameters)).toHaveLength(0); + expect(errorMessages(model).length).toBeGreaterThan(0); + }); + + it('line with empty name is treated as constraint and produces error', () => { + const model = new PictModel(': a, b'); + expect(Object.keys(model.parameters)).toHaveLength(0); + expect(errorMessages(model).length).toBeGreaterThan(0); + }); + + it('collects error for no values', () => { + const model = new PictModel('Key:'); + expect(errorMessages(model)).toContainEqual(expect.stringContaining('No values for parameter "Key"')); + }); + + it('handles quoted strings with commas', () => { + const model = new PictModel(`Msg: "hello, world", "foo, bar", normal`); + expect(model.parameters).toEqual({ "Msg": ["hello, world", "foo, bar", "normal"] }); + }); + + it('handles negative prefix ~', () => { + const model = new PictModel(`Type: Valid, ~Invalid, ~Bad`); + expect(model.parameters).toEqual({ "Type": ["Valid", "Invalid", "Bad"] }); + }); + + it('handles weight suffix (N)', () => { + const model = new PictModel(`Size: 10, 100 (10), 500`); + expect(model.parameters).toEqual({ "Size": [10, 100, 500] }); + }); + + it('handles aliases with |', () => { + const model = new PictModel(`OS: Windows | Win, Linux | GNU/Linux`); + expect(model.parameters).toEqual({ "OS": ["Windows", "Linux"] }); + }); + + it('handles parameter reference ', () => { + const model = new PictModel(`A: 1, 2, 3\nB: , 4`); + expect(model.parameters).toEqual({ "A": [1, 2, 3], "B": [1, 2, 3, 4] }); + }); + + it('collects error for unknown parameter reference', () => { + const model = new PictModel(`A: `); + expect(errorMessages(model)).toContainEqual(expect.stringContaining('Unknown parameter reference: "Unknown"')); + }); + + it('handles combined features', () => { + const model = new PictModel(`OS: "Windows 10" | Win10, ~"Bad OS" (5), Linux`); + expect(model.parameters).toEqual({ "OS": ["Windows 10", "Bad OS", "Linux"] }); + }); +}); + +describe('PictModel with parameters and constraints', () => { + it('parses parameters and constraints together', () => { + const model = new PictModel(` +Type: Single, Span, Stripe +Size: 10, 100, 500 + +IF [Type] = "Single" THEN [Size] > 10; + `); + expect(model.parameters).toEqual({ + "Type": ["Single", "Span", "Stripe"], + "Size": [10, 100, 500], + }); + expect(model.constraints).toHaveLength(1); + expect(errorMessages(model)).toEqual([]); + }); + + it('filter checks constraint', () => { + const model = new PictModel(` +Type: A, B +Size: 10, 100 + +IF [Type] = "A" THEN [Size] = 100; + `); + expect(model.filter({ Type: 'A', Size: 100 })).toBe(true); + expect(model.filter({ Type: 'A', Size: 10 })).toBe(false); + expect(model.filter({ Type: 'B', Size: 10 })).toBe(true); + }); + + it('filter returns true when no constraints', () => { + const model = new PictModel(`X: 1, 2\nY: a, b`); + expect(model.filter({ X: 1, Y: 'a' })).toBe(true); + }); + + it('make generates rows satisfying constraints', () => { + const model = new PictModel(` +Type: A, B +Size: 10, 100 +Flag: On, Off + +IF [Type] = "A" THEN [Size] = 100; + `); + const rows = model.make(); + for (const row of rows) { + if ((row as any).Type === 'A') { + expect((row as any).Size).toBe(100); + } + } + }); + + it('make accepts additional options', () => { + const model = new PictModel(` +Type: A, B, C +Size: 10, 100, 500 + `); + const rows = model.make({ strength: 2, salt: 42 }); + expect(rows.length).toBeGreaterThan(0); + }); + + it('makeAsync yields rows', () => { + const model = new PictModel(` +Type: A, B +Size: 10, 100 + `); + const rows = [...model.makeAsync()]; + expect(rows.length).toBeGreaterThan(0); + }); +}); + +describe('PictModel weights', () => { + it('parses weight from (N) syntax', () => { + const model = new PictModel(` +Browser: Chrome (10), Firefox, Safari (5) + `); + expect(errorMessages(model)).toEqual([]); + expect(model.weights).toEqual({ + Browser: { 0: 10, 2: 5 }, + }); + }); + + it('no weights when none specified', () => { + const model = new PictModel(`Browser: Chrome, Firefox`); + expect(model.weights).toEqual({}); + }); + + it('weighted value is preferred during completion', () => { + // With heavy weight on a specific value, that value should appear more often + const factors = { + A: ['a1', 'a2', 'a3'], + B: ['b1', 'b2', 'b3'], + C: ['c1', 'c2', 'c3'], + }; + const rowsNoWeight = make(factors, { salt: 1 }); + const rowsWithWeight = make(factors, { + salt: 1, + weights: { C: { 0: 100 } }, // c1 prioritized + }); + const c1CountNoWeight = rowsNoWeight.filter((r: any) => r.C === 'c1').length; + const c1CountWithWeight = rowsWithWeight.filter((r: any) => r.C === 'c1').length; + // c1 should appear at least as often (typically more often) when weighted + expect(c1CountWithWeight).toBeGreaterThanOrEqual(c1CountNoWeight); + }); + + it('PictModel with weight syntax produces rows', () => { + const model = new PictModel(` +A: a1, a2, a3 +B: b1 (10), b2, b3 + `); + const rows = model.make({ salt: 1 }); + expect(rows.length).toBeGreaterThan(0); + }); +}); + +describe('weightsByValue utility', () => { + it('converts value-keyed weights to index-keyed', () => { + const factors = { + Browser: ['Chrome', 'Firefox', 'Safari'], + }; + const result = weightsByValue(factors, { + Browser: { Chrome: 10, Safari: 5 }, + }); + expect(result).toEqual({ + Browser: { 0: 10, 2: 5 }, + }); + }); + + it('skips unknown factor keys', () => { + const result = weightsByValue( + { A: ['x', 'y'] }, + { A: { x: 10 }, Unknown: { foo: 5 } }, + ); + expect(result).toEqual({ A: { 0: 10 } }); + }); + + it('skips unknown values', () => { + const result = weightsByValue( + { A: ['x', 'y'] }, + { A: { x: 10, z: 99 } }, + ); + expect(result).toEqual({ A: { 0: 10 } }); + }); + + it('matches numeric values via string conversion', () => { + const result = weightsByValue( + { Size: [10, 100, 1000] }, + { Size: { '100': 5 } }, + ); + expect(result).toEqual({ Size: { 1: 5 } }); + }); + + it('returns empty object when no matches', () => { + const result = weightsByValue( + { A: ['x', 'y'] }, + { A: { z: 10 } }, + ); + expect(result).toEqual({}); + }); +}); + +describe('PictModel invalid values (~)', () => { + it('records invalid values from ~ prefix', () => { + const model = new PictModel(` +Age: 20, 30, ~-1, ~999 +Country: Japan, USA, ~"Mars" + `); + expect(errorMessages(model)).toEqual([]); + expect(model.negatives.get('Age')).toEqual(new Set([-1, 999])); + expect(model.negatives.get('Country')).toEqual(new Set(['Mars'])); + }); + + it('filter allows rows with no invalid values', () => { + const model = new PictModel(` +Age: 20, ~-1 +Country: Japan, ~"Mars" + `); + expect(model.filter({ Age: 20, Country: 'Japan' })).toBe(true); + }); + + it('filter allows rows with exactly one invalid value', () => { + const model = new PictModel(` +Age: 20, ~-1 +Country: Japan, ~"Mars" + `); + expect(model.filter({ Age: -1, Country: 'Japan' })).toBe(true); + expect(model.filter({ Age: 20, Country: 'Mars' })).toBe(true); + }); + + it('filter rejects rows with two or more invalid values', () => { + const model = new PictModel(` +Age: 20, ~-1 +Country: Japan, ~"Mars" + `); + expect(model.filter({ Age: -1, Country: 'Mars' })).toBe(false); + }); + + it('make generates rows that never combine two invalid values', () => { + const model = new PictModel(` +Age: 20, 30, ~-1, ~999 +Country: Japan, USA, ~"Mars" + `); + const rows = model.make(); + for (const row of rows) { + const ageInvalid = (row as any).Age === '~-1' || (row as any).Age === '~999'; + const countryInvalid = (row as any).Country === '~Mars'; + expect(ageInvalid && countryInvalid).toBe(false); + } + // Verify ~ prefix appears in output + const allAges = rows.map((r: any) => r.Age); + expect(allAges).toContain('~-1'); + expect(allAges).toContain('~999'); + const allCountries = rows.map((r: any) => r.Country); + expect(allCountries).toContain('~Mars'); + }); + + it('invalid values combined with aliases', () => { + const model = new PictModel(` +OS: Linux, ~"Bad OS" | Bad +Result: pass, ~fail + `); + expect(model.negatives.get('OS')).toEqual(new Set(['Bad OS'])); + expect(model.negatives.get('Result')).toEqual(new Set(['fail'])); + }); + + it('invalid values work alongside constraints', () => { + const model = new PictModel(` +Age: 20, 30, ~-1 +Country: Japan, USA + +IF [Country] = "USA" THEN [Age] > 18; + `); + expect(errorMessages(model)).toEqual([]); + // Valid normal row + expect(model.filter({ Age: 30, Country: 'USA' })).toBe(true); + // Single invalid value is allowed (constraint still applies though) + expect(model.filter({ Age: -1, Country: 'Japan' })).toBe(true); + // Constraint violated + expect(model.filter({ Age: 10, Country: 'USA' })).toBe(false); + }); +}); -describe('PictConstraintsLexer with single constraints', () => { +describe('PictModel caseInsensitive', () => { + it('case-insensitive equality', () => { + const model = new PictModel( + `OS: iOS, Android +Browser: Chrome, Firefox + +IF [OS] = "ios" THEN [Browser] = "chrome"; + `, + { caseInsensitive: true } + ); + expect(errorMessages(model)).toEqual([]); + expect(model.filter({ OS: 'iOS', Browser: 'Chrome' })).toBe(true); + expect(model.filter({ OS: 'iOS', Browser: 'Firefox' })).toBe(false); + expect(model.filter({ OS: 'Android', Browser: 'Firefox' })).toBe(true); + }); + + it('case-insensitive IN clause', () => { + const model = new PictModel( + `Color: Red, Blue, Green, Yellow +Category: Primary, Secondary + +IF [Color] IN {"red", "blue"} THEN [Category] = "Primary"; + `, + { caseInsensitive: true } + ); + expect(model.filter({ Color: 'Red', Category: 'Primary' })).toBe(true); + expect(model.filter({ Color: 'Blue', Category: 'Primary' })).toBe(true); + expect(model.filter({ Color: 'Green', Category: 'Secondary' })).toBe(true); + expect(model.filter({ Color: 'Red', Category: 'Secondary' })).toBe(false); + }); + + it('case-insensitive LIKE clause', () => { + const model = new PictModel( + `Name: Alice, alice, Bob +Status: Active, Inactive + +IF [Name] LIKE "ALIC*" THEN [Status] = "Active"; + `, + { caseInsensitive: true } + ); + expect(model.filter({ Name: 'Alice', Status: 'Active' })).toBe(true); + expect(model.filter({ Name: 'alice', Status: 'Active' })).toBe(true); + expect(model.filter({ Name: 'Alice', Status: 'Inactive' })).toBe(false); + expect(model.filter({ Name: 'Bob', Status: 'Inactive' })).toBe(true); + }); + + it('case-insensitive alias lookup', () => { + const model = new PictModel( + `OS: Windows | Win, Linux + +IF [OS] = "WIN" THEN [OS] <> "Linux"; + `, + { caseInsensitive: true } + ); + expect(errorMessages(model)).toEqual([]); + expect(model.filter({ OS: 'Windows' })).toBe(true); + }); + + it('case-insensitive by default (PICT compatible)', () => { + const model = new PictModel(` +OS: iOS, Android +Browser: Chrome, Firefox + +IF [OS] = "ios" THEN [Browser] = "chrome"; + `); + // Default is case-insensitive, so "ios" matches "iOS" + expect(model.filter({ OS: 'iOS', Browser: 'Chrome' })).toBe(true); + expect(model.filter({ OS: 'iOS', Browser: 'Firefox' })).toBe(false); + }); + + it('case-sensitive when explicitly disabled', () => { + const model = new PictModel( + `OS: iOS, Android +Browser: Chrome, Firefox + +IF [OS] = "ios" THEN [Browser] = "chrome"; + `, + { caseInsensitive: false } + ); + // No row matches "ios" because comparison is case-sensitive + expect(model.filter({ OS: 'iOS', Browser: 'Firefox' })).toBe(true); + }); +}); + +describe('PictModel aliases in constraints', () => { + it('alias in constraint resolves to canonical value', () => { + const model = new PictModel(` +OS: Windows | Win, Linux +Browser: Chrome, Firefox + +IF [OS] = "Win" THEN [Browser] = "Chrome"; + `); + expect(errorMessages(model)).toEqual([]); + // Row with canonical "Windows" value should match the constraint + expect(model.filter({ OS: 'Windows', Browser: 'Chrome' })).toBe(true); + expect(model.filter({ OS: 'Windows', Browser: 'Firefox' })).toBe(false); + expect(model.filter({ OS: 'Linux', Browser: 'Firefox' })).toBe(true); + }); + + it('alias in IN clause resolves to canonical value', () => { + const model = new PictModel(` +OS: "Windows 10" | Win10, "Mac OS" | Mac, Linux +Result: pass, fail + +IF [OS] IN {"Win10", "Mac"} THEN [Result] = "pass"; + `); + expect(errorMessages(model)).toEqual([]); + expect(model.filter({ OS: 'Windows 10', Result: 'pass' })).toBe(true); + expect(model.filter({ OS: 'Windows 10', Result: 'fail' })).toBe(false); + expect(model.filter({ OS: 'Mac OS', Result: 'pass' })).toBe(true); + expect(model.filter({ OS: 'Linux', Result: 'fail' })).toBe(true); + }); + + it('multiple aliases per value', () => { + const model = new PictModel(` +OS: Windows | Win | Microsoft, Linux | GNU/Linux + +IF [OS] = "Microsoft" THEN [OS] <> "GNU/Linux"; + `); + expect(errorMessages(model)).toEqual([]); + expect(model.filter({ OS: 'Windows' })).toBe(true); + expect(model.filter({ OS: 'Linux' })).toBe(true); + }); + + it('parameters use canonical value only', () => { + const model = new PictModel(`OS: Windows | Win, Linux`); + expect(model.parameters).toEqual({ OS: ['Windows', 'Linux'] }); + }); +}); + +describe('PictModel sub-models', () => { + it('parses sub-model definition', () => { + const model = new PictModel(` +A: 1, 2, 3 +B: 4, 5, 6 +C: 7, 8, 9 + +{ A, B, C } @ 3 + `); + expect(model.subModels).toEqual([{ keys: ['A', 'B', 'C'], strength: 3 }]); + expect(errorMessages(model)).toEqual([]); + }); + + it('sub-model increases coverage for group', () => { + const model = new PictModel(` +A: a1, a2, a3 +B: b1, b2, b3 +C: c1, c2, c3 +D: d1, d2 + +{ A, B, C } @ 3 + `); + const rows = model.make(); + // All 3-wise combinations of A, B, C must be covered + const abc = ['A', 'B', 'C'] as const; + const abcValues = { + A: ['a1', 'a2', 'a3'], + B: ['b1', 'b2', 'b3'], + C: ['c1', 'c2', 'c3'], + }; + for (const a of abcValues.A) { + for (const b of abcValues.B) { + for (const c of abcValues.C) { + const found = rows.some((row: any) => row.A === a && row.B === b && row.C === c); + expect(found).toBe(true); + } + } + } + }); + + it('default strength still applies cross-group', () => { + const model = new PictModel(` +A: a1, a2 +B: b1, b2 +C: c1, c2 +D: d1, d2 + +{ A, B } @ 2 + `); + // Default strength 2 applies to cross-group pairs (e.g. A-C, A-D, B-C, B-D, C-D) + const rows = model.make(); + // Check that all 2-wise pairs of C and D are covered + for (const c of ['c1', 'c2']) { + for (const d of ['d1', 'd2']) { + const found = rows.some((row: any) => row.C === c && row.D === d); + expect(found).toBe(true); + } + } + }); + + it('multiple sub-models', () => { + const model = new PictModel(` +A: a1, a2 +B: b1, b2 +C: c1, c2 +D: d1, d2 + +{ A, B } @ 2 +{ C, D } @ 2 + `); + expect(model.subModels).toHaveLength(2); + const rows = model.make(); + expect(rows.length).toBeGreaterThan(0); + }); + + it('sub-model via options API', () => { + const rows = new PictModel(` +A: a1, a2, a3 +B: b1, b2, b3 +C: c1, c2, c3 + `).make({ subModels: [{ keys: ['A', 'B', 'C'], strength: 3 }] }); + // All 3-wise must be covered + for (const a of ['a1', 'a2', 'a3']) { + for (const b of ['b1', 'b2', 'b3']) { + for (const c of ['c1', 'c2', 'c3']) { + const found = rows.some((row: any) => row.A === a && row.B === b && row.C === c); + expect(found).toBe(true); + } + } + } + }); + + it('invalid sub-model line produces error', () => { + const model = new PictModel(` +A: 1, 2 +B: 3, 4 + +{ A, B } + `); + // "{ A, B }" without @ is not a valid sub-model, treated as constraint + expect(errorMessages(model).length).toBeGreaterThan(0); + }); +}); + +describe('PictModel unconditional constraints', () => { + it('simple unconditional constraint', () => { + const model = new PictModel(` +A: x, y +B: x, y +[A] <> [B]; + `); + expect(errorMessages(model)).toEqual([]); + expect(model.constraints).toHaveLength(1); + expect(model.filter({ A: 'x', B: 'y' })).toBe(true); + expect(model.filter({ A: 'x', B: 'x' })).toBe(false); + }); + + it('unconditional constraint with AND', () => { + const model = new PictModel(` +A: x, y +B: x, y +C: yes, no +[A] <> [B] AND [C] = "yes"; + `); + expect(errorMessages(model)).toEqual([]); + expect(model.filter({ A: 'x', B: 'y', C: 'yes' })).toBe(true); + expect(model.filter({ A: 'x', B: 'x', C: 'yes' })).toBe(false); + expect(model.filter({ A: 'x', B: 'y', C: 'no' })).toBe(false); + }); + + it('mixed conditional and unconditional constraints', () => { + const model = new PictModel(` +A: 1, 2 +B: 2, 3 +C: x, y +D: x, y +IF [A] = 1 THEN [B] = 2; +[C] <> [D]; + `); + expect(errorMessages(model)).toEqual([]); + expect(model.constraints).toHaveLength(2); + expect(model.filter({ A: 1, B: 2, C: 'x', D: 'y' })).toBe(true); + expect(model.filter({ A: 1, B: 3, C: 'x', D: 'y' })).toBe(false); + expect(model.filter({ A: 0, B: 3, C: 'x', D: 'x' })).toBe(false); + }); +}); + +describe('PictModel single constraints', () => { it('Blank', () => { - const lexer = new PictConstraintsLexer(``, true); - expect(lexer.filters.length).toBe(0); - expect(lexer.errors.length).toBe(0); + const model = new PictModel(``); + expect(model.constraints.length).toBe(0); + expect(errorMessages(model).length).toBe(0); const row1 = { PRICE: 150, DISCOUNT: 'YES' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); }); it('should filter correctly with LIKE and IN conditions', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] LIKE "Alic?" THEN [STATUS] IN {"Active", "Pending"} ELSE [AGE] > 20 OR [COUNTRY] = "USA"; - `, false); + const model = new PictModel(` +NAME: Alice, Bob +STATUS: Active, Pending, Inactive +AGE: 15, 25 +COUNTRY: USA, UK + +IF [NAME] LIKE "Alic?" THEN [STATUS] IN {"Active", "Pending"} ELSE [AGE] > 20 OR [COUNTRY] = "USA"; + `); const row1 = { NAME: 'Alice', STATUS: 'Active' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { NAME: 'Alice', STATUS: 'Inactive' }; - expect(lexer.filter(row2)).toBe(false); + expect(model.filter(row2)).toBe(false); }); it('should filter correctly with numeric conditions', () => { - const lexer = new PictConstraintsLexer(` - IF [PRICE] > 100 THEN [DISCOUNT] = "YES" ELSE [DISCOUNT] = "NO"; - `, false); + const model = new PictModel(` +PRICE: 90, 150 +DISCOUNT: YES, NO + +IF [PRICE] > 100 THEN [DISCOUNT] = "YES" ELSE [DISCOUNT] = "NO"; + `); const row1 = { PRICE: 150, DISCOUNT: 'YES' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { PRICE: 90, DISCOUNT: 'NO' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { PRICE: 90, DISCOUNT: 'YES' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); }); it('should handle NOT conditions correctly', () => { - const lexer = new PictConstraintsLexer(` - IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] <> "No" ELSE [AVAILABLE] = "No"; - `, false); + const model = new PictModel(` +PRODUCT: Book, Pen +AVAILABLE: Yes, No + +IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] <> "No" ELSE [AVAILABLE] = "No"; + `); const row1 = { PRODUCT: 'Pen', AVAILABLE: 'Yes' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { PRODUCT: 'Book', AVAILABLE: 'No' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { PRODUCT: 'Pen', AVAILABLE: 'No' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); }); it('should filter with AND conditions', () => { - const lexer = new PictConstraintsLexer(` - IF [CATEGORY] = "Electronics" AND [BRAND] = "Sony" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; - `, false); + const model = new PictModel(` +CATEGORY: Electronics, Furniture +BRAND: Sony, "General Electric Company" +WARRANTY: Included, "Not Included" + +IF [CATEGORY] = "Electronics" AND [BRAND] = "Sony" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; + `); const row1 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Included' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { CATEGORY: 'Electronics', BRAND: 'General Electric Company', WARRANTY: 'Not Included' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Not Included' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); }); it('should handle nested conditions with parentheses', () => { - const lexer = new PictConstraintsLexer(` - IF ([CATEGORY] = "Electronics" AND [BRAND] = "Sony") OR [BRAND] = "Apple" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; - `, false); + const model = new PictModel(` +CATEGORY: Electronics, Furniture +BRAND: Sony, Apple, Samsung, IKEA +WARRANTY: Included, "Not Included" + +IF ([CATEGORY] = "Electronics" AND [BRAND] = "Sony") OR [BRAND] = "Apple" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; + `); const row1 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Included' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { CATEGORY: 'Electronics', BRAND: 'Apple', WARRANTY: 'Included' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { CATEGORY: 'Furniture', BRAND: 'IKEA', WARRANTY: 'Not Included' }; - expect(lexer.filter(row3)).toBe(true); + expect(model.filter(row3)).toBe(true); const row4 = { CATEGORY: 'Electronics', BRAND: 'Samsung', WARRANTY: 'Included' }; - expect(lexer.filter(row4)).toBe(false); + expect(model.filter(row4)).toBe(false); }); it('should handle fields containing spaces', () => { - const lexer = new PictConstraintsLexer(` - IF [PRODUCT NAME] = "Laptop" THEN [PRICE] > 500 ELSE [PRICE] <= 500; - `, false); + const model = new PictModel(` +PRODUCT NAME: Laptop, Desktop +PRICE: 400, 500, 600 + +IF [PRODUCT NAME] = "Laptop" THEN [PRICE] > 500 ELSE [PRICE] <= 500; + `); const row1 = { 'PRODUCT NAME': 'Laptop', PRICE: 600 }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { 'PRODUCT NAME': 'Laptop', PRICE: 400 }; - expect(lexer.filter(row2)).toBe(false); + expect(model.filter(row2)).toBe(false); const row3 = { 'PRODUCT NAME': 'Desktop', PRICE: 600 }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); }); it('should handle IN conditions', () => { - const lexer = new PictConstraintsLexer(` - IF [COLOR] IN {"Red", "Blue", "Green"} THEN [CATEGORY] = "Primary" ELSE [CATEGORY] = "Secondary"; - `, false); + const model = new PictModel(` +COLOR: Red, Blue, Green, Yellow +CATEGORY: Primary, Secondary + +IF [COLOR] IN {"Red", "Blue", "Green"} THEN [CATEGORY] = "Primary" ELSE [CATEGORY] = "Secondary"; + `); const row1 = { COLOR: 'Red', CATEGORY: 'Primary' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { COLOR: 'Yellow', CATEGORY: 'Secondary' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { COLOR: 'Red', CATEGORY: 'Secondary' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); }); it('should handle complex conditions with nested parentheses', () => { - const lexer = new PictConstraintsLexer(` - IF ([AGE] > 20 AND ([COUNTRY] = "USA" OR [COUNTRY] = "Canada")) THEN [STATUS] = "Allowed" ELSE [STATUS] = "Denied"; - `, false); + const model = new PictModel(` +AGE: 18, 25 +COUNTRY: USA, Canada, UK +STATUS: Allowed, Denied + +IF ([AGE] > 20 AND ([COUNTRY] = "USA" OR [COUNTRY] = "Canada")) THEN [STATUS] = "Allowed" ELSE [STATUS] = "Denied"; + `); const row1 = { AGE: 25, COUNTRY: 'USA', STATUS: 'Allowed' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { AGE: 18, COUNTRY: 'USA', STATUS: 'Denied' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { AGE: 25, COUNTRY: 'UK', STATUS: 'Denied' }; - expect(lexer.filter(row3)).toBe(true); + expect(model.filter(row3)).toBe(true); const row4 = { AGE: 25, COUNTRY: 'Canada', STATUS: 'Allowed' }; - expect(lexer.filter(row4)).toBe(true); + expect(model.filter(row4)).toBe(true); const row5 = { AGE: 25, COUNTRY: 'Canada', STATUS: 'Denied' }; - expect(lexer.filter(row5)).toBe(false); + expect(model.filter(row5)).toBe(false); }); + it('should handle false in ELSE condition', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE FALSE; - `, false); + const model = new PictModel(` +NAME: Bob, Alice +STATUS: Active, Inactive + +IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE FALSE; + `); const row1 = { NAME: 'Bob', STATUS: 'Inactive' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { NAME: 'Alice', STATUS: 'Active' }; - expect(lexer.filter(row2)).toBe(false); + expect(model.filter(row2)).toBe(false); }); it('should handle true in ELSE condition', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE true; - `, false); + const model = new PictModel(` +NAME: Bob, Alice +STATUS: Active, Inactive + +IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE true; + `); const row1 = { NAME: 'Bob', STATUS: 'Inactive' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { NAME: 'Alice', STATUS: 'Active' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); }); + it('Compare with other fields', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] = [ALIAS] THEN [AGE] <= 26; - `, false); + const model = new PictModel(` +NAME: Bob, Alice, Shohei +ALIAS: Bob, Lissie, Shohei +AGE: 18, 25, 30 + +IF [NAME] = [ALIAS] THEN [AGE] <= 26; + `); const row1 = { NAME: 'Bob', ALIAS: 'Bob', AGE: 18 }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { NAME: 'Alice', ALIAS: 'Lissie', AGE: 25 }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { NAME: 'Shohei', ALIAS: 'Shohei', AGE: 30 }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); }); }); -describe('PictConstraintsLexer with multiple constraints', () => { +describe('PictModel multiple constraints', () => { it('should handle multiple constraints correctly (Test Case 1)', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] = "Alice" THEN [AGE] > 20 ELSE [AGE] < 20; - IF [COUNTRY] = "USA" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; - `, false); + const model = new PictModel(` +NAME: Alice, Bob +AGE: 15, 18, 25 +COUNTRY: USA, Canada +STATUS: Active, Inactive + +IF [NAME] = "Alice" THEN [AGE] > 20 ELSE [AGE] < 20; +IF [COUNTRY] = "USA" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `); const row1 = { NAME: 'Alice', AGE: 25, COUNTRY: 'USA', STATUS: 'Active' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { NAME: 'Alice', AGE: 25, COUNTRY: 'Canada', STATUS: 'Inactive' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { NAME: 'Alice', AGE: 18, COUNTRY: 'USA', STATUS: 'Active' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); const row4 = { NAME: 'Bob', AGE: 15, COUNTRY: 'USA', STATUS: 'Inactive' }; - expect(lexer.filter(row4)).toBe(false); + expect(model.filter(row4)).toBe(false); }); it('should handle multiple constraints correctly (Test Case 2)', () => { - const lexer = new PictConstraintsLexer(` - IF [SCORE] >= 90 THEN [GRADE] = "A" ELSE [GRADE] = "B"; - IF [MEMBER] = "YES" THEN [DISCOUNT] = "20%" ELSE [DISCOUNT] = "10%"; - `, false); + const model = new PictModel(` +SCORE: 85, 95 +GRADE: A, B +MEMBER: YES, NO +DISCOUNT: "10%", "20%" + +IF [SCORE] >= 90 THEN [GRADE] = "A" ELSE [GRADE] = "B"; +IF [MEMBER] = "YES" THEN [DISCOUNT] = "20%" ELSE [DISCOUNT] = "10%"; + `); const row1 = { SCORE: 95, GRADE: 'A', MEMBER: 'YES', DISCOUNT: '20%' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { SCORE: 85, GRADE: 'B', MEMBER: 'NO', DISCOUNT: '10%' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { SCORE: 85, GRADE: 'B', MEMBER: 'YES', DISCOUNT: '20%' }; - expect(lexer.filter(row3)).toBe(true); + expect(model.filter(row3)).toBe(true); const row4 = { SCORE: 85, GRADE: 'A', MEMBER: 'YES', DISCOUNT: '10%' }; - expect(lexer.filter(row4)).toBe(false); + expect(model.filter(row4)).toBe(false); }); it('should handle multiple constraints correctly (Test Case 3)', () => { - const lexer = new PictConstraintsLexer(` - IF [TEMP] > 30 THEN [STATE] = "HOT" ELSE [STATE] = "COLD"; - IF [HUMIDITY] < 50 THEN [COMFORT] = "DRY" ELSE [COMFORT] = "HUMID"; - `, false); + const model = new PictModel(` +TEMP: 25, 35 +STATE: HOT, COLD +HUMIDITY: 45, 55 +COMFORT: DRY, HUMID + +IF [TEMP] > 30 THEN [STATE] = "HOT" ELSE [STATE] = "COLD"; +IF [HUMIDITY] < 50 THEN [COMFORT] = "DRY" ELSE [COMFORT] = "HUMID"; + `); const row1 = { TEMP: 35, STATE: 'HOT', HUMIDITY: 45, COMFORT: 'DRY' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { TEMP: 25, STATE: 'COLD', HUMIDITY: 55, COMFORT: 'HUMID' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { TEMP: 25, STATE: 'HOT', HUMIDITY: 55, COMFORT: 'DRY' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); const row4 = { TEMP: 35, STATE: 'HOT', HUMIDITY: 55, COMFORT: 'HUMID' }; - expect(lexer.filter(row4)).toBe(true); + expect(model.filter(row4)).toBe(true); }); it('should handle multiple constraints correctly (Test Case 4)', () => { - const lexer = new PictConstraintsLexer(` - IF [CATEGORY] = "Electronics" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; - IF [PRICE] > 100 THEN [DISCOUNT] = "YES" ELSE [DISCOUNT] = "NO"; - `, false); + const model = new PictModel(` +CATEGORY: Electronics, Furniture +WARRANTY: Included, "Not Included" +PRICE: 90, 150 +DISCOUNT: YES, NO + +IF [CATEGORY] = "Electronics" THEN [WARRANTY] = "Included" ELSE [WARRANTY] = "Not Included"; +IF [PRICE] > 100 THEN [DISCOUNT] = "YES" ELSE [DISCOUNT] = "NO"; + `); const row1 = { CATEGORY: 'Electronics', WARRANTY: 'Included', PRICE: 150, DISCOUNT: 'YES' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { CATEGORY: 'Furniture', WARRANTY: 'Not Included', PRICE: 90, DISCOUNT: 'NO' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { CATEGORY: 'Electronics', WARRANTY: 'Not Included', PRICE: 150, DISCOUNT: 'NO' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); const row4 = { CATEGORY: 'Furniture', WARRANTY: 'Not Included', PRICE: 150, DISCOUNT: 'YES' }; - expect(lexer.filter(row4)).toBe(true); + expect(model.filter(row4)).toBe(true); }); it('should handle multiple constraints correctly (Test Case 5)', () => { - const lexer = new PictConstraintsLexer(` - IF [COLOR] = "Red" THEN [CATEGORY] = "Primary" ELSE [CATEGORY] = "Secondary"; - IF [QUANTITY] < 10 THEN [STOCK] = "Low" ELSE [STOCK] = "High"; - `, false); + const model = new PictModel(` +COLOR: Red, Blue +CATEGORY: Primary, Secondary +QUANTITY: 5, 20 +STOCK: Low, High + +IF [COLOR] = "Red" THEN [CATEGORY] = "Primary" ELSE [CATEGORY] = "Secondary"; +IF [QUANTITY] < 10 THEN [STOCK] = "Low" ELSE [STOCK] = "High"; + `); const row1 = { COLOR: 'Red', CATEGORY: 'Primary', QUANTITY: 5, STOCK: 'Low' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { COLOR: 'Blue', CATEGORY: 'Secondary', QUANTITY: 20, STOCK: 'High' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { COLOR: 'Red', CATEGORY: 'Secondary', QUANTITY: 5, STOCK: 'High' }; - expect(lexer.filter(row3)).toBe(false); + expect(model.filter(row3)).toBe(false); const row4 = { COLOR: 'Red', CATEGORY: 'Primary', QUANTITY: 20, STOCK: 'High' }; - expect(lexer.filter(row4)).toBe(true); + expect(model.filter(row4)).toBe(true); }); it('should handle multiple constraints correctly (Test Case 6)', () => { - const lexer = new PictConstraintsLexer(` - IF [SIZE] = "Large" THEN [AVAILABILITY] = "In Stock" ELSE [AVAILABILITY] = "Out of Stock"; - IF ([DISCOUNT] = "YES" AND [MEMBER] = "YES") THEN [PRICE] < 100 ELSE [PRICE] >= 100; - `, false); + const model = new PictModel(` +SIZE: Large, Medium +AVAILABILITY: "In Stock", "Out of Stock" +DISCOUNT: YES, NO +MEMBER: YES, NO +PRICE: 90, 110, 120 + +IF [SIZE] = "Large" THEN [AVAILABILITY] = "In Stock" ELSE [AVAILABILITY] = "Out of Stock"; +IF ([DISCOUNT] = "YES" AND [MEMBER] = "YES") THEN [PRICE] < 100 ELSE [PRICE] >= 100; + `); const row1 = { SIZE: 'Large', AVAILABILITY: 'In Stock', DISCOUNT: 'YES', MEMBER: 'YES', PRICE: 90 }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { SIZE: 'Medium', AVAILABILITY: 'Out of Stock', DISCOUNT: 'NO', MEMBER: 'NO', PRICE: 120 }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { SIZE: 'Large', AVAILABILITY: 'In Stock', DISCOUNT: 'YES', MEMBER: 'NO', PRICE: 110 }; - expect(lexer.filter(row3)).toBe(true); + expect(model.filter(row3)).toBe(true); }); it('should handle multiple constraints correctly (Test Case 7)', () => { - const lexer = new PictConstraintsLexer(` - IF [SEASON] = "Winter" THEN [CLOTHING] = "Coat" ELSE [CLOTHING] = "Shirt"; - IF ([TEMP] < 0 AND [WEATHER] = "Snowy") THEN [ACTIVITY] = "Skiing" ELSE [ACTIVITY] = "Running"; - `, false); + const model = new PictModel(` +SEASON: Winter, Summer +CLOTHING: Coat, Shirt +TEMP: -5, 5, 25 +WEATHER: Snowy, Sunny +ACTIVITY: Skiing, Running + +IF [SEASON] = "Winter" THEN [CLOTHING] = "Coat" ELSE [CLOTHING] = "Shirt"; +IF ([TEMP] < 0 AND [WEATHER] = "Snowy") THEN [ACTIVITY] = "Skiing" ELSE [ACTIVITY] = "Running"; + `); const row1 = { SEASON: 'Winter', CLOTHING: 'Coat', TEMP: -5, WEATHER: 'Snowy', ACTIVITY: 'Skiing' }; - expect(lexer.filter(row1)).toBe(true); + expect(model.filter(row1)).toBe(true); const row2 = { SEASON: 'Summer', CLOTHING: 'Shirt', TEMP: 25, WEATHER: 'Sunny', ACTIVITY: 'Running' }; - expect(lexer.filter(row2)).toBe(true); + expect(model.filter(row2)).toBe(true); const row3 = { SEASON: 'Winter', CLOTHING: 'Coat', TEMP: 5, WEATHER: 'Sunny', ACTIVITY: 'Running' }; - expect(lexer.filter(row3)).toBe(true); + expect(model.filter(row3)).toBe(true); }); }); -describe('PictConstraintsLexer with invalid constraints', () => { +describe('PictModel invalid constraints', () => { it('Unknown comparer', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] @ "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Unknown comparison operator: @'); + const model = new PictModel(` +NAME: Alice +STATUS: Active, Inactive + +IF [NAME] @ "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Unknown comparison operator: @'); }); it('Comparison operator missing, got a value', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Expected comparison operator but found value: "Alice"'); + const model = new PictModel(` +NAME: Alice +STATUS: Active, Inactive + +IF [NAME] "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Expected comparison operator but found value: "Alice"'); }); - + it('Comparison operator missing, got an operator', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] AND TRUE THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Expected comparison operator but found operator: AND'); + const model = new PictModel(` +NAME: Alice +STATUS: Active, Inactive + +IF [NAME] AND TRUE THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Expected comparison operator but found operator: AND'); }); it('Comparison operator and value missing, got then', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive" - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('A comparison operator and value are required after the field.'); + const model = new PictModel(` +NAME: Summer +STATUS: Active, Inactive + +IF [NAME] THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive" + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('A comparison operator and value are required after the field.'); }); + it('Nothing after IF', () => { - const lexer = new PictConstraintsLexer(` - IF THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive" - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); + const model = new PictModel(` +STATUS: Active, Inactive + +IF THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive" + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); }); it('Nothing after THEN', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] = "Summer" THEN ELSE [STATUS] = "Active" - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); + const model = new PictModel(` +NAME: Summer +STATUS: Active + +IF [NAME] = "Summer" THEN ELSE [STATUS] = "Active" + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); }); it('Nothing after ELSE', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); + const model = new PictModel(` +NAME: Summer +STATUS: Active + +IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"'); }); - it('IF is missing, typo', () => { - const lexer = new PictConstraintsLexer(` - F [NAME] = "Summer" THEN [STATUS] = "Active" - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('Unknown token: F'); + const model = new PictModel(` +NAME: Summer +STATUS: Active + +F [NAME] = "Summer" THEN [STATUS] = "Active" + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Unknown token: F'); }); it('IF is nothing', () => { - const lexer = new PictConstraintsLexer(` - [NAME] = "Summer" THEN [STATUS] = "Active" - `, false); - expect(lexer.errors.length).toBe(1); - expect(lexer.errors[0]).toBe('The leading "IF" is missing, found [NAME]'); + // Without IF, `[NAME] = "Summer"` is parsed as an unconditional constraint, + // then `THEN` is unexpected and causes an error. + const model = new PictModel(` +NAME: Summer +STATUS: Active + +[NAME] = "Summer" THEN [STATUS] = "Active" + `); + // 1 valid unconditional constraint + 1 error (THEN is unexpected) + expect(model.constraints).toHaveLength(1); + expect(errorMessages(model)).toHaveLength(1); + expect(errorMessages(model)[0]).toMatch(/Expected/); // THEN is unexpected }); it('Multiple invalid expressions', () => { - const lexer = new PictConstraintsLexer(` - IF [NAME] THEN [STATUS] = "Active"; - IF [NAME] = "Summer" THEN [STATUS] = "Active"; - IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE; - IF [NAME] = "Summer" THEN [STATUS] = "Active"; - IF [NAME] @ "Summer" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; - `, false); - - expect(lexer.errors.length).toBe(5); - - expect(lexer.errors[0]).toBe('A comparison operator and value are required after the field.' ); - expect(lexer.errors[1]).toBe(null); - expect(lexer.errors[2]).toBe('Expected field or value after "IF", "THEN", "ELSE"' ); - expect(lexer.errors[3]).toBe(null); - expect(lexer.errors[4]).toBe('Unknown comparison operator: @'); - - expect(lexer.filters[0]).toBeNull(); - expect(lexer.filters[1]).not.toBeNull(); - expect(lexer.filters[2]).toBeNull(); - expect(lexer.filters[3]).not.toBeNull(); - expect(lexer.filters[4]).toBeNull(); - }); -}); \ No newline at end of file + const model = new PictModel(` +NAME: Summer +STATUS: Active + +IF [NAME] THEN [STATUS] = "Active"; +IF [NAME] = "Summer" THEN [STATUS] = "Active"; +IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE; +IF [NAME] = "Summer" THEN [STATUS] = "Active"; +IF [NAME] @ "Summer" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"; + `); + + expect(errorMessages(model)).toEqual([ + 'A comparison operator and value are required after the field.', + 'Expected field or value after "IF", "THEN", "ELSE"', + 'Unknown comparison operator: @', + ]); + + // Only valid constraints are returned (nulls filtered out) + expect(model.constraints).toHaveLength(2); + }); + + it('Unterminated string literal', () => { + const model = new PictModel(` +NAME: Alice +STATUS: Active + +IF [NAME] = "Alice THEN [STATUS] = "Active"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toMatch(/Unterminated string literal/); + }); + + it('Unterminated field reference', () => { + const model = new PictModel(` +NAME: Alice + +IF [NAME + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toMatch(/Unterminated field reference/); + }); + + it('Unterminated set (missing closing brace)', () => { + const model = new PictModel(` +COLOR: Red, Blue +CATEGORY: Primary + +IF [COLOR] IN {"Red", "Blue" THEN [CATEGORY] = "Primary"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toMatch(/Unterminated set/); + }); + + it('Empty IN set', () => { + const model = new PictModel(` +COLOR: Red +CATEGORY: Primary + +IF [COLOR] IN {} THEN [CATEGORY] = "Primary"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toBe('Empty set in IN clause'); + }); + + it('!= operator suggests <>', () => { + const model = new PictModel(` +NAME: Alice +STATUS: Active + +IF [NAME] != "Alice" THEN [STATUS] = "Active"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toMatch(/Use "<>" for inequality/); + }); + + it('IF without THEN', () => { + const model = new PictModel(` +NAME: Alice +STATUS: Active + +IF [NAME] = "Alice" [STATUS] = "Active"; + `); + expect(errorMessages(model).length).toBe(1); + expect(errorMessages(model)[0]).toMatch(/Expected "THEN" but found/); + }); +}); diff --git a/typescript/src/__tests__/profile.test.ts b/typescript/src/__tests__/profile.test.ts new file mode 100644 index 0000000..b3d5337 --- /dev/null +++ b/typescript/src/__tests__/profile.test.ts @@ -0,0 +1,250 @@ +import { Controller } from '../controller'; +import { criteria } from '../index'; +import { combinations, unique } from '../lib'; +import type { FactorsType, PairByKeyType, PairType, ScalarType } from '../types'; + +describe('profile 20x10 greedy no constraints', () => { + const makeFactors = () => { + const factors: Record = {}; + for (let i = 0; i < 20; i++) { + factors[`f${i}`] = Array.from({ length: 10 }, (_, j) => j); + } + return factors; + }; + + it('instruments key methods (setPair, close, consumePairs, etc.)', () => { + const factors = makeFactors(); + + let setPairCalls = 0; + let closeCalls = 0; + let closeTime = 0; + let setPairTime = 0; + let consumePairsTime = 0; + let recordCompletionsTime = 0; + let closeSuccesses = 0; + let closeFailures = 0; + + const origSetPair = (Controller.prototype as any).setPair; + (Controller.prototype as any).setPair = function (...args: any[]) { + setPairCalls++; + const t0 = Date.now(); + const result = origSetPair.apply(this, args); + setPairTime += Date.now() - t0; + return result; + }; + + const origClose = (Controller.prototype as any).close; + (Controller.prototype as any).close = function (...args: any[]) { + closeCalls++; + const t0 = Date.now(); + const result = origClose.apply(this, args); + closeTime += Date.now() - t0; + if (result === true) closeSuccesses++; + else closeFailures++; + return result; + }; + + const origConsumePairs = (Controller.prototype as any).consumePairs; + (Controller.prototype as any).consumePairs = function (...args: any[]) { + const t0 = Date.now(); + const result = origConsumePairs.apply(this, args); + consumePairsTime += Date.now() - t0; + return result; + }; + + const origRecordCompletions = (Controller.prototype as any).recordCompletions; + (Controller.prototype as any).recordCompletions = function (...args: any[]) { + const t0 = Date.now(); + const result = origRecordCompletions.apply(this, args); + recordCompletionsTime += Date.now() - t0; + return result; + }; + + const totalStart = Date.now(); + const ctrl = new Controller(factors, { criterion: criteria.greedy }); + const ctorTime = Date.now() - totalStart; + + const makeStart = Date.now(); + const rows = ctrl.make(); + const totalMakeTime = Date.now() - makeStart; + + const greedyEstimate = totalMakeTime - closeTime - setPairTime - consumePairsTime - recordCompletionsTime; + + // Restore + (Controller.prototype as any).setPair = origSetPair; + (Controller.prototype as any).close = origClose; + (Controller.prototype as any).consumePairs = origConsumePairs; + (Controller.prototype as any).recordCompletions = origRecordCompletions; + + console.log('=== PROFILE RESULTS ==='); + console.log(`Constructor time: ${ctorTime}ms`); + console.log(`Total make() time: ${totalMakeTime}ms`); + console.log(`Rows produced: ${rows.length}`); + console.log(`Incomplete pairs left: ${ctrl.incomplete.size}`); + console.log(''); + console.log(`setPair calls: ${setPairCalls}`); + console.log(`setPair total time: ${setPairTime}ms`); + console.log(`close() calls: ${closeCalls}`); + console.log(`close() total time: ${closeTime}ms`); + console.log(`close() successes: ${closeSuccesses}`); + console.log(`close() failures: ${closeFailures}`); + console.log(`consumePairs time: ${consumePairsTime}ms`); + console.log(`recordCompletions time: ${recordCompletionsTime}ms`); + console.log(`Greedy+other (residual): ${greedyEstimate}ms`); + }); + + it('per-row iteration timing', () => { + const factors = makeFactors(); + const ctrl = new Controller(factors, { criterion: criteria.greedy }); + + const iterTimes: number[] = []; + const gen = ctrl.makeAsync(); + let iterStart = Date.now(); + for (const row of gen) { + iterTimes.push(Date.now() - iterStart); + iterStart = Date.now(); + } + const totalTime = iterTimes.reduce((a, b) => a + b, 0); + + const sorted = [...iterTimes].sort((a, b) => b - a); + console.log(`\n=== ITERATION PROFILE ===`); + console.log(`Total rows: ${iterTimes.length}, Total time: ${totalTime}ms`); + console.log(`Avg per row: ${(totalTime / iterTimes.length).toFixed(1)}ms`); + console.log(`Slowest 10: ${sorted.slice(0, 10).join(', ')}ms`); + console.log(`Fastest 10: ${sorted.slice(-10).join(', ')}ms`); + + const buckets = [0, 10, 50, 100, 200, 500, Infinity]; + for (let i = 0; i < buckets.length - 1; i++) { + const count = iterTimes.filter(t => t >= buckets[i] && t < buckets[i + 1]).length; + if (count > 0) console.log(` ${buckets[i]}-${buckets[i + 1]}ms: ${count} rows`); + } + console.log(`First 10: ${iterTimes.slice(0, 10).join(', ')}ms`); + console.log(`Last 10: ${iterTimes.slice(-10).join(', ')}ms`); + }); + + it('profiles greedy internals with inlined instrumented criterion', () => { + const factors = makeFactors(); + + // Counters for greedy internals + let rowCoveredTime = 0; + let rowCoveredCalls = 0; + let innerLoopIterations = 0; + let isCompatibleCalls = 0; + let getNumRemovablePairsCalls = 0; + let getNumRemovablePairsTime = 0; + let outerWhileIterations = 0; + let pairsYielded = 0; + let earlyBreakCount = 0; + let rowCoveredSkips = 0; + let invalidPairSkips = 0; + let incompatibleSkips = 0; + let compatZeroSkips = 0; + + // Inline the greedy criterion with instrumentation + const getNumRemovablePairs = (indexes: Set, incomplete: PairByKeyType, strengths: number[], exclude?: Set) => { + getNumRemovablePairsCalls++; + const t0 = Date.now(); + let num = 0; + for (const s of strengths) { + for (let pair of combinations([...indexes], s)) { + const key = unique(pair); + if (incomplete.has(key) && (!exclude || !exclude.has(key))) { + num++; + } + } + } + getNumRemovablePairsTime += Date.now() - t0; + return num; + }; + + const instrumentedGreedy = function* (ctrl: Controller): Generator { + while (true) { + outerWhileIterations++; + let maxNumPairs: number | null = null; + let efficientPair: PairType | null = null; + + const rcStart = Date.now(); + rowCoveredCalls++; + const rowCovered = new Set(); + if (ctrl.row.size > 0) { + for (const s of ctrl.allStrengths) { + for (const p of combinations([...ctrl.row.values()], s)) { + rowCovered.add(unique(p)); + } + } + } + rowCoveredTime += Date.now() - rcStart; + + for (const [pairKey, pair] of ctrl.incomplete.entries()) { + innerLoopIterations++; + const rowSize = ctrl.row.size; + if (ctrl.isFilled(ctrl.row)) break; + + if (rowCovered.has(pairKey)) { rowCoveredSkips++; continue; } + if (ctrl.row.invalidPairs.has(pairKey)) { invalidPairSkips++; continue; } + + const compat = rowSize === 0 ? pair.length : ctrl.isCompatible(pair); + isCompatibleCalls++; + if (compat === null) { incompatibleSkips++; continue; } + if (compat === 0) { compatZeroSkips++; continue; } + + let storable = compat; + const storableAbs = Math.abs(storable); + const { tolerance = 0 } = ctrl.options!; + + const numPairs = getNumRemovablePairs( + new Set([...ctrl.row.values(), ...pair]), + ctrl.incomplete, + ctrl.allStrengths, + rowCovered, + ); + + if (numPairs + tolerance > rowSize * storableAbs) { + efficientPair = pair; + earlyBreakCount++; + break; + } + if (maxNumPairs === null || maxNumPairs < numPairs) { + maxNumPairs = numPairs; + efficientPair = pair; + } + } + if (efficientPair === null) break; + pairsYielded++; + yield efficientPair; + } + }; + + const ctrl = new Controller(factors, { criterion: instrumentedGreedy as any }); + const t0 = Date.now(); + const rows = ctrl.make(); + const elapsed = Date.now() - t0; + + console.log(`\n=== GREEDY INTERNALS (instrumented) ===`); + console.log(`Total time: ${elapsed}ms`); + console.log(`Rows: ${rows.length}`); + console.log(`Outer while iterations: ${outerWhileIterations}`); + console.log(`Pairs yielded: ${pairsYielded}`); + console.log(`Inner loop iterations: ${innerLoopIterations}`); + console.log(''); + console.log(`rowCovered computation: ${rowCoveredTime}ms (${rowCoveredCalls} calls)`); + console.log(`getNumRemovablePairs: ${getNumRemovablePairsTime}ms (${getNumRemovablePairsCalls} calls)`); + console.log(''); + console.log(`isCompatible calls: ${isCompatibleCalls}`); + console.log(`rowCovered skips: ${rowCoveredSkips}`); + console.log(`invalidPair skips: ${invalidPairSkips}`); + console.log(`incompatible skips: ${incompatibleSkips}`); + console.log(`compat=0 skips: ${compatZeroSkips}`); + console.log(`early breaks (efficient): ${earlyBreakCount}`); + console.log(''); + console.log(`Avg inner iterations/outer: ${(innerLoopIterations / outerWhileIterations).toFixed(0)}`); + console.log(`Avg getNumRemovable/outer: ${(getNumRemovablePairsCalls / outerWhileIterations).toFixed(0)}`); + + // Estimate time NOT in getNumRemovablePairs or rowCovered + const otherTime = elapsed - getNumRemovablePairsTime - rowCoveredTime; + console.log(`\nTime breakdown:`); + console.log(` getNumRemovablePairs: ${getNumRemovablePairsTime}ms (${(getNumRemovablePairsTime / elapsed * 100).toFixed(1)}%)`); + console.log(` rowCovered computation: ${rowCoveredTime}ms (${(rowCoveredTime / elapsed * 100).toFixed(1)}%)`); + console.log(` other (iteration, compat): ${otherTime}ms (${(otherTime / elapsed * 100).toFixed(1)}%)`); + }); +}); diff --git a/typescript/src/__tests__/salt-sweep.test.ts b/typescript/src/__tests__/salt-sweep.test.ts new file mode 100644 index 0000000..e0450ca --- /dev/null +++ b/typescript/src/__tests__/salt-sweep.test.ts @@ -0,0 +1,29 @@ +import { Controller } from '../controller'; +import { criteria } from '../index'; + +describe('salt sweep', () => { + it('20x10 greedy salt 0-50', () => { + const factors: Record = {}; + for (let i = 0; i < 20; i++) { + factors[`f${i}`] = Array.from({ length: 10 }, (_, j) => j); + } + + let bestRows = Infinity; + let bestSalt = 0; + let bestTime = 0; + + for (let salt = 0; salt <= 50; salt++) { + const t0 = Date.now(); + const ctrl = new Controller(factors, { criterion: criteria.greedy, salt }); + const rows = ctrl.make(); + const t1 = Date.now(); + if (rows.length < bestRows) { + bestRows = rows.length; + bestSalt = salt; + bestTime = t1 - t0; + } + } + + console.log(`Best: salt=${bestSalt} rows=${bestRows} time=${bestTime}ms`); + }, 300000); +}); diff --git a/typescript/src/__tests__/simple-criterion.test.ts b/typescript/src/__tests__/simple-criterion.test.ts new file mode 100644 index 0000000..b4e8cc0 --- /dev/null +++ b/typescript/src/__tests__/simple-criterion.test.ts @@ -0,0 +1,176 @@ +import { Controller } from '../controller'; +import { criteria } from '../index'; +import type { Condition } from '../types'; + +const runWithSimple = (factors: any, constraints: Condition[]) => { + const ctrl = new Controller(factors, { constraints, criterion: criteria.simple }); + const rows = ctrl.make(); + return { rows, stats: ctrl.stats }; +}; + +describe('simple criterion with constraints', () => { + + it('3-level chain', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: [1000, 2000, 3000], + }; + const constraints: Condition[] = [ + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'eq', field: 'B', value: 10 }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'B', value: 10 }, + { operator: 'eq', field: 'C', value: 100 }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'C', value: 100 }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + ]; + const { rows, stats } = runWithSimple(factors, constraints); + console.log('3-level simple:', { rowCount: stats.rowCount, progress: stats.progress, pruned: stats.prunedPairs }); + for (const r of rows as any[]) { + if (r.A === 1) expect(r.B).toBe(10); + if (r.B === 10) expect(r.C).toBe(100); + if (r.C === 100) expect(r.D).toBe(1000); + } + expect(stats.progress).toBe(1); + }); + + it('6-level deep chain', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + C: [100, 200, 300], + D: [1000, 2000, 3000], + E: ['α', 'β', 'γ'], + F: ['X', 'Y', 'Z'], + }; + const constraints: Condition[] = [ + { operator: 'or', conditions: [ + { operator: 'ne', field: 'A', value: 1 }, + { operator: 'in', field: 'B', values: [10, 20] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'in', field: 'B', values: [30] }, + { operator: 'in', field: 'C', values: [100, 200] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'in', field: 'C', values: [300] }, + { operator: 'eq', field: 'D', value: 1000 }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'D', value: 1000 }, + { operator: 'in', field: 'E', values: ['α', 'β'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'in', field: 'E', values: ['γ'] }, + { operator: 'eq', field: 'F', value: 'X' }, + ]}, + ]; + const { rows, stats } = runWithSimple(factors, constraints); + console.log('6-level simple:', { rowCount: stats.rowCount, progress: stats.progress, pruned: stats.prunedPairs }); + for (const r of rows as any[]) { + if (r.A === 1) expect([10, 20]).toContain(r.B); + if ([10, 20].includes(r.B)) expect([100, 200]).toContain(r.C); + if ([100, 200].includes(r.C)) expect(r.D).toBe(1000); + if (r.D === 1000) expect(['α', 'β']).toContain(r.E); + if (['α', 'β'].includes(r.E)) expect(r.F).toBe('X'); + } + expect(stats.progress).toBe(1); + }); + + it('all-different', () => { + const vals = [1, 2, 3, 4]; + const factors = { A: vals, B: vals, C: vals, D: vals }; + const constraints: Condition[] = [ + { operator: 'ne', field: 'A', target: 'B' }, + { operator: 'ne', field: 'A', target: 'C' }, + { operator: 'ne', field: 'A', target: 'D' }, + { operator: 'ne', field: 'B', target: 'C' }, + { operator: 'ne', field: 'B', target: 'D' }, + { operator: 'ne', field: 'C', target: 'D' }, + ]; + const { rows, stats } = runWithSimple(factors, constraints); + console.log('all-different simple:', { rowCount: stats.rowCount, progress: stats.progress, pruned: stats.prunedPairs }); + for (const r of rows as any[]) { + expect(new Set([r.A, r.B, r.C, r.D]).size).toBe(4); + } + expect(stats.progress).toBe(1); + }); + + it('mixed chains and field comparisons', () => { + const factors = { + Priority: ['low', 'medium', 'high', 'critical'], + Assignee: ['alice', 'bob', 'carol'], + Reviewer: ['alice', 'bob', 'carol'], + Environment: ['dev', 'staging', 'prod'], + Approval: ['none', 'lead', 'director'], + }; + const constraints: Condition[] = [ + { operator: 'ne', field: 'Assignee', target: 'Reviewer' }, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'critical' }, + { operator: 'eq', field: 'Environment', value: 'prod' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Environment', value: 'prod' }, + { operator: 'eq', field: 'Approval', value: 'director' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'high' }, + { operator: 'in', field: 'Environment', values: ['staging', 'prod'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Environment', value: 'staging' }, + { operator: 'in', field: 'Approval', values: ['lead', 'director'] }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'low' }, + { operator: 'eq', field: 'Approval', value: 'none' }, + ]}, + { operator: 'or', conditions: [ + { operator: 'ne', field: 'Priority', value: 'low' }, + { operator: 'eq', field: 'Environment', value: 'dev' }, + ]}, + ]; + const { rows, stats } = runWithSimple(factors, constraints); + console.log('mixed simple:', { rowCount: stats.rowCount, progress: stats.progress, pruned: stats.prunedPairs }); + for (const r of rows as any[]) { + expect(r.Assignee).not.toBe(r.Reviewer); + if (r.Priority === 'critical') expect(r.Environment).toBe('prod'); + if (r.Environment === 'prod') expect(r.Approval).toBe('director'); + if (r.Priority === 'low') { expect(r.Approval).toBe('none'); expect(r.Environment).toBe('dev'); } + } + expect(stats.progress).toBe(1); + }); + + it('heavy.pict', () => { + const fs = require('fs'); + const path = require('path'); + const { PictModel } = require('../pict'); + const modelText = fs.readFileSync( + path.resolve(__dirname, '../../../heavy.pict'), 'utf-8', + ); + const model = new PictModel(modelText); + const ctrl = new Controller(model.parameters, { + ...model._buildOptions(), + criterion: criteria.simple, + } as any); + const rows = ctrl.make(); + console.log('heavy.pict simple:', { + rowCount: ctrl.stats.rowCount, + progress: ctrl.stats.progress, + pruned: ctrl.stats.prunedPairs, + uncovered: ctrl.stats.uncoveredPairs.length, + }); + for (const r of rows) { + expect(model.filter(r)).toBe(true); + } + expect(ctrl.stats.progress).toBe(1); + }, 120000); +}); diff --git a/typescript/src/__tests__/typo-constraint.test.ts b/typescript/src/__tests__/typo-constraint.test.ts new file mode 100644 index 0000000..38bf958 --- /dev/null +++ b/typescript/src/__tests__/typo-constraint.test.ts @@ -0,0 +1,22 @@ +import { PictModel } from '../pict'; + +describe('typo in constraint field', () => { + it('should not block generation when constraint references unknown parameter', () => { + const m = new PictModel(` +Type: Single, Span, Stripe, Mirror, RAID-5 +Size: 10, 100, 500, 1000, 5000, 10000, 40000 +Format method: Quick, Slow +File system: FAT, FAT32, NTFS +Cluster size: 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 +Compression: On, Off + +IF [File syste] = "FAT" THEN [Size] <= 4096; +IF [File system] = "FAT32" THEN [Size] <= 32000; + `); + console.log('issues:', m.issues); + const rows = m.make(); + console.log('rows:', rows.length); + console.log('progress:', m.progress); + expect(rows.length).toBeGreaterThan(0); + }); +}); diff --git a/typescript/src/_bench.ts b/typescript/src/_bench.ts new file mode 100644 index 0000000..392b9ef --- /dev/null +++ b/typescript/src/_bench.ts @@ -0,0 +1,35 @@ +import { make } from './index'; +import { range } from './lib'; + +// 20 factors, each with 10 levels +const factors: string[][] = []; +for (let i = 0; i < 20; i++) { + factors.push(range(0, 10).map((j: number) => `f${i}_${j}`)); +} + +let minRows = Infinity; +let bestSeed = 0; +const results: [number, number][] = []; + +for (let salt = 1; salt <= 200; salt++) { + const rows = make(factors, { salt: salt }); + const count = rows.length; + results.push([salt, count]); + if (count < minRows) { + minRows = count; + bestSeed = salt; + } + if (salt % 20 === 0) { + console.log(`salt ${salt}: ${count} rows (best so far: salt=${bestSeed}, rows=${minRows})`); + } +} + +console.log(`\n=== RESULT ===`); +console.log(`Best salt: ${bestSeed}`); +console.log(`Min rows: ${minRows}`); + +results.sort((a, b) => a[1] - b[1]); +console.log(`\nTop 10 salts:`); +for (let i = 0; i < 10; i++) { + console.log(` salt=${results[i][0]}, rows=${results[i][1]}`); +} diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index 80544c1..fdfdd71 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -10,7 +10,6 @@ import { ascOrder, primeGenerator, unique, - proxyHandler, } from "./lib"; import { @@ -26,12 +25,15 @@ import { OptionsType, PairType, SuggestRowType, + Condition, + Comparer, } from "./types"; -import { NeverMatch, NotReady } from "./exceptions"; +import { evaluate, extractKeys, TriState } from "./evaluate"; +import { NeverMatch, UncoveredPair } from "./exceptions"; export class Row extends Map implements RowType { - // index: number - public consumed: PairByKeyType = new Map(); + /** Pair keys that failed constraint checks for this row attempt. */ + public invalidPairs: Set = new Set(); constructor(row: CandidateType) { super(); @@ -50,6 +52,28 @@ export class Row extends Map implements RowType { } } +interface ResolvedConstraint { + condition: Condition; + keys: ReadonlySet; +} + +export interface ControllerStats { + /** Total pairs before any pruning. */ + totalPairs: number; + /** Number of pairs pruned by constraints (infeasible). */ + prunedPairs: number; + /** Number of pairs consumed so far. */ + coveredPairs: number; + /** Coverage ratio: coveredPairs / (totalPairs - prunedPairs). */ + progress: number; + /** Number of generated rows. */ + rowCount: number; + /** Pairs that could not be covered. Populated after make/makeAsync completes. */ + uncoveredPairs: UncoveredPair[]; + /** Counts of values filled by close() (completion), keyed by factor then value. */ + completions: Record>; +} + export class Controller { public factorLength: number; public factorIsArray: Boolean; @@ -58,25 +82,80 @@ export class Controller { private parents: ParentsType = new Map(); private indices: IndicesType = new Map(); public incomplete: PairByKeyType = new Map(); - private numAllChunks: number = 0; - + private rejected: Set = new Set(); public row: Row; + private _totalPairs: number = 0; + private _prunedPairs: number = 0; + private _rowCount: number = 0; + private _uncoveredPairs: UncoveredPair[] = []; + private _completions: Record> = {}; + + get stats(): ControllerStats { + return { + totalPairs: this._totalPairs, + prunedPairs: this._prunedPairs, + coveredPairs: this._totalPairs - this._prunedPairs - this.incomplete.size, + progress: this._totalPairs === 0 ? 0 : 1 - this.incomplete.size / this._totalPairs, + rowCount: this._rowCount, + uncoveredPairs: this._uncoveredPairs, + completions: this._completions, + }; + } + + private constraints: ResolvedConstraint[] = []; + private constraintsByKey: Map> = new Map(); + private comparer: Comparer; + + /** + * Indices into `constraints` that have already evaluated to `true` + * against the **current** row. Cleared whenever the row is reset or + * yielded. Safe because the row only grows and each condition is + * deterministic over its declared keys. + */ + private passedIndexes: Set = new Set(); + constructor(public factors: FactorsType, public options: OptionsType = {}) { + this.comparer = options.comparer ?? {}; this.serialize(factors); - this.setIncomplete(); - this.numAllChunks = this.incomplete.size; - this.row = new Row([]); this.factorLength = len(factors); this.factorIsArray = factors instanceof Array; + this.resolveConstraints(); + this.setIncomplete(); + this._totalPairs = this.incomplete.size; + this.row = new Row([]); - // Delete initial pairs that do not satisfy preFilter + // Delete initial pairs that cannot possibly satisfy the constraints. + // Two-pass: first check direct violations, then use forward checking + // to detect pairs made impossible by constraint chains. for (const [pairKey, pair] of this.incomplete.entries()) { const cand = this.getCandidate(pair); - const storable = this.storable(cand); - if (storable == null) { + if (this.storableCheck(cand) === false) { this.incomplete.delete(pairKey); + } else if (this.constraints.length > 0) { + const snapshot = new Row(cand); + if (!this.forwardCheck(snapshot)) { + this.incomplete.delete(pairKey); + } + } + } + this._prunedPairs = this._totalPairs - this.incomplete.size; + + } + + private resolveConstraints() { + const constraints = this.options.constraints ?? []; + for (let i = 0; i < constraints.length; i++) { + const keys = extractKeys(constraints[i]); + this.constraints.push({ condition: constraints[i], keys }); + for (const k of keys) { + let set = this.constraintsByKey.get(k); + if (!set) { + set = new Set(); + this.constraintsByKey.set(k, set); + } + set.add(i); } } } @@ -99,41 +178,74 @@ export class Controller { }; private setIncomplete() { - const { sorter = hash, seed = "" } = this.options; + const { sorter = hash, salt = "" } = this.options; const pairs: PairType[] = []; const allKeys = getItems(this.serials).map(([k, _]) => k); - for (const keys of combinations(allKeys, this.pairwiseCount)) { - const comb = range(0, this.pairwiseCount).map((i) => this.serials.get(keys[i]) as PairType); + const subModels = this.options.subModels ?? []; + const subModelKeySets = subModels.map(sm => new Set(sm.keys)); + + const isWithinSubModel = (keys: ScalarType[]) => + subModelKeySets.some(ks => keys.every(k => ks.has(k))); + + for (const keys of combinations(allKeys, this.strength)) { + if (isWithinSubModel(keys)) continue; + const comb = range(0, this.strength).map((i) => this.serials.get(keys[i]) as PairType); for (let pair of product(...comb)) { - pair = pair.sort(ascOrder); - pairs.push(pair); + pairs.push(pair.sort(ascOrder)); + } + } + + for (const sub of subModels) { + for (const keys of combinations(sub.keys, sub.strength)) { + const comb = range(0, sub.strength).map((i) => this.serials.get(keys[i]) as PairType); + for (let pair of product(...comb)) { + pairs.push(pair.sort(ascOrder)); + } } } - for (let pair of sorter(pairs, { seed, indices: this.indices })) { + + for (let pair of sorter(pairs, { salt, indices: this.indices })) { this.incomplete.set(unique(pair), pair); } } - private setPair(pair: PairType) { - for (let [key, value] of this.getCandidate(pair)) { - this.row.set(key, value); - } - //this.consume(pair); - for (let p of combinations([...this.row.values()], this.pairwiseCount)) { - this.consume(p); + /** + * Try to add a candidate pair to the current row. Evaluates constraints + * against a snapshot (row + pair) without mutating `this.row`. If all + * constraints pass (or are unknown), the pair is committed to `this.row` + * and `true` is returned. If any constraint definitively fails, `this.row` + * is unchanged and `false` is returned. + */ + private setPair(pair: PairType): boolean { + const candidate = this.getCandidate(pair); + // Build a snapshot to evaluate constraints against. + const snapshot = new Row([...this.row.entries(), ...candidate]); + const snapshotObj = this.toObject(snapshot); + + // Evaluate all non-passed constraints on the snapshot. + for (let i = 0; i < this.constraints.length; i++) { + if (this.passedIndexes.has(i)) continue; + const result = evaluate(this.constraints[i].condition, snapshotObj, this.comparer); + if (result === false) return false; } - } - public consume(pair: PairType) { - const pairKey = unique(pair); - const deleted = this.incomplete.delete(pairKey); - if (deleted) { - this.row.consumed.set(pairKey, pair); + // All constraints pass or unknown — run forward check before committing. + if (!this.forwardCheck(snapshot)) return false; + + // Forward check passed — commit the pair. + for (const [key, value] of candidate) { + this.row.set(key, value); } + this.markPassedConstraints(this.row); + return true; } - public consumeRow(row: Row) { - for (let pair of combinations([...row.values()], this.pairwiseCount)) { - this.consume(pair); + + private consumePairs(row: Row) { + for (const s of this.allStrengths) { + for (let pair of combinations([...row.values()], s)) { + const pairKey = unique(pair); + this.incomplete.delete(pairKey); + } } } @@ -141,36 +253,215 @@ export class Controller { return getCandidate(pair, this.parents); } - // Returns a negative value if it is unknown if it can be stored. - public storable(candidate: CandidateType) { + public isCompatible(pair: PairType): number | null { + let num = 0; + for (const serial of pair) { + const key = this.parents.get(serial)!; + const existing = this.row.get(key); + if (typeof existing === "undefined") { + num++; + } else if (existing !== serial) { + return null; + } + } + return num; + } + + /** + * Check whether adding `candidate` to `row` would violate any constraint. + * Returns `true` (OK), `false` (definitively violated), or `null` + * (some dependency is still missing — defer). + * + * Constraints already in `passedIndexes` are skipped. + */ + private storableCheck(candidate: CandidateType, row: Row = this.row): TriState { + if (this.constraints.length === 0) return true; + let nxtObject: DictType | null = null; + for (let i = 0; i < this.constraints.length; i++) { + if (this.passedIndexes.has(i)) continue; + if (nxtObject === null) { + const nxt = new Row([...row.entries(), ...candidate]); + nxtObject = this.toObject(nxt); + } + const result = evaluate(this.constraints[i].condition, nxtObject, this.comparer); + if (result === false) return false; + // true or unknown → continue checking other constraints + } + return true; + } + + /** + * Returns the number of new keys this candidate would add to `row`, or + * `null` if the candidate is incompatible or would definitively violate a + * constraint. `null` results from three-valued evaluation are treated + * as "OK for now" — they will be rechecked once more keys are known. + */ + public storable(candidate: CandidateType, row: Row = this.row): number | null { let num = 0; for (let [key, el] of candidate) { - let existing: number | undefined = this.row.get(key); + let existing: number | undefined = row.get(key); if (typeof existing === "undefined") { num++; } else if (existing != el) { return null; } } - if (!this.options.preFilter) { - return num; + const check = this.storableCheck(candidate, row); + if (check === false) return null; + return num; + } + + /** + * Evaluate constraints against `row` and mark those that pass as done. + * Returns `false` if any constraint definitively fails (= the row is + * unsalvageable and should be abandoned), `true` otherwise. + */ + private markPassedConstraints(row: Row): boolean { + if (this.constraints.length === 0) return true; + let obj: DictType | null = null; + for (let i = 0; i < this.constraints.length; i++) { + if (this.passedIndexes.has(i)) continue; + if (obj === null) obj = this.toObject(row); + const result = evaluate(this.constraints[i].condition, obj, this.comparer); + if (result === true) { + this.passedIndexes.add(i); + } else if (result === false) { + return false; + } } - const candidates: CandidateType = [...this.row.entries()].concat(candidate); - const nxt = new Row(candidates); - const proxy = this.toProxy(nxt); - try { - const ok = this.options.preFilter(proxy); - if (!ok) { - this.consumeRow(nxt); - return null; + return true; + } + + /** + * Forward checking: given a snapshot row, propagate constraints to prune + * domains of unfilled factors. If any factor's domain becomes empty, the + * current assignment is unsolvable — return false. + * + * This is read-only: it does NOT modify this.row. It builds a temporary + * domain map and iteratively narrows it by evaluating constraints with + * each candidate value. + */ + private forwardCheck(snapshot: Row): boolean { + if (this.constraints.length === 0) return true; + + // Build initial domains for unfilled factors. + const domains = new Map(); + for (const [key, serials] of this.serials.entries()) { + if (!snapshot.has(key)) { + domains.set(key, [...serials]); } - } catch (e) { - if (e instanceof NotReady) { - return -num; + } + if (domains.size === 0) return true; + + // Start with all constraints as potentially relevant. + // Restricting to only snapshot-key constraints would miss constraints + // that solely reference unfilled factors (e.g. a constant constraint + // like `machine=WindowsPhone` when machine is unfilled). + const relevantSet = new Set(this.constraints.map((_, i) => i)); + + // Iterative arc-consistency: prune domains, and when a domain shrinks + // to 1 value (forced), "assign" it in the temp row and re-propagate. + // For multi-value domains, after pruning, check what peer factor values + // survive under ALL remaining candidates (intersection). If a peer + // value doesn't survive under some candidate, it can be pruned. + const tempRow = new Row([...snapshot.entries()]); + let changed = true; + while (changed) { + changed = false; + for (const [key, domain] of domains.entries()) { + if (domain.length === 0) return false; + const keyConstraints = this.constraintsByKey.get(key as string); + if (!keyConstraints) continue; + let hasRelevant = false; + for (const ci of keyConstraints) { + if (relevantSet.has(ci)) { hasRelevant = true; break; } + } + if (!hasRelevant) continue; + + const surviving: number[] = []; + for (const serial of domain) { + tempRow.set(key, serial); + const obj = this.toObject(tempRow); + let viable = true; + for (const ci of keyConstraints) { + if (this.passedIndexes.has(ci)) continue; + if (evaluate(this.constraints[ci].condition, obj, this.comparer) === false) { + viable = false; + break; + } + } + if (viable) surviving.push(serial); + } + tempRow.delete(key); + + if (surviving.length === 0) return false; + if (surviving.length < domain.length) { + domains.set(key, surviving); + changed = true; + if (surviving.length === 1) { + tempRow.set(key, surviving[0]); + domains.delete(key); + const nc = this.constraintsByKey.get(key as string); + if (nc) { for (const ci of nc) relevantSet.add(ci); } + } + } + + // For multi-value surviving domains, check peer factors. + // For each peer, compute which values survive under EVERY candidate + // of this factor (intersection). Values that fail under any candidate + // can be pruned from the peer's domain. + if (surviving.length > 1) { + for (const [peerKey, peerDomain] of domains.entries()) { + if (peerKey === key) continue; + const peerConstraints = this.constraintsByKey.get(peerKey as string); + if (!peerConstraints) continue; + // Check if any peer constraint shares keys with this factor. + let shares = false; + for (const ci of peerConstraints) { + if (keyConstraints.has(ci)) { shares = true; break; } + } + if (!shares) continue; + + // Union across all candidates of `key`: a peer value is viable + // if it works with at least one candidate. + const peerViable = new Set(); + for (const serial of surviving) { + tempRow.set(key, serial); + for (const ps of peerDomain) { + if (peerViable.has(ps)) continue; + tempRow.set(peerKey, ps); + const obj = this.toObject(tempRow); + let ok = true; + for (const ci of peerConstraints) { + if (this.passedIndexes.has(ci)) continue; + if (evaluate(this.constraints[ci].condition, obj, this.comparer) === false) { + ok = false; + break; + } + } + if (ok) peerViable.add(ps); + } + tempRow.delete(peerKey); + } + tempRow.delete(key); + + const narrowed = peerDomain.filter(v => peerViable.has(v)); + if (narrowed.length === 0) return false; + if (narrowed.length < peerDomain.length) { + domains.set(peerKey, narrowed); + changed = true; + if (narrowed.length === 1) { + tempRow.set(peerKey, narrowed[0]); + domains.delete(peerKey); + const nc = this.constraintsByKey.get(peerKey as string); + if (nc) { for (const ci of nc) relevantSet.add(ci); } + } + } + } + } } - throw e } - return num; + return true; } public isFilled(row: Row): boolean { @@ -188,14 +479,6 @@ export class Controller { return result; } - private toProxy(row: Row) { - const obj: DictType = {}; - for (let [key, value] of this.toMap(row).entries()) { - obj[key] = value; - } - return new Proxy(obj, proxyHandler) as SuggestRowType; - } - private toObject(row: Row) { const obj: DictType = {}; for (let [key, value] of this.toMap(row).entries()) { @@ -205,21 +488,14 @@ export class Controller { } private reset() { - this.row.consumed.forEach((pair, pairKey) => { - this.incomplete.set(pairKey, pair); - }); - this.row = new Row([]); - } - - private discard() { - const pairKey = this.row.getPairKey(); - this.rejected.add(pairKey); this.row = new Row([]); + this.passedIndexes.clear(); } private restore() { const row = this.row; this.row = new Row([]); + this.passedIndexes.clear(); if (this.factorIsArray) { const map = this.toMap(row); return getItems(map) @@ -229,93 +505,345 @@ export class Controller { return this.toObject(row); } - private close() { - const trier = new Row([...this.row.entries()]); + /** + * Fill the remaining unfilled factors of `this.row` and check constraints. + * Uses depth-first backtracking: each unfilled factor tries its values in + * order (weight-sorted on the first pass). When a value causes a + * constraint to evaluate to `false` (via three-valued `storable`), the + * next candidate is tried; if all candidates are exhausted, the previous + * factor is backtracked. + * + * Returns `true` when a valid completion is found (the row is updated in + * place), or `false` when no valid completion exists. + */ + /** + * Result of close(): `true` = valid completion found; `false` = failed; + * or an object with the conflict keys from the first failing constraint. + */ + private close(): true | { conflictKeys: ReadonlySet | null } { const kvs = getItems(this.serials); - for (let [k, vs] of kvs) { - for (let v of vs) { - const pairKey = trier.getPairKey(v); - if (this.rejected.has(pairKey)) { + + const unfilled: { key: ScalarType; values: PairType }[] = []; + for (const [k, vs] of kvs) { + if (!this.row.has(k)) { + unfilled.push({ key: k, values: this.orderByWeight(k, vs) }); + } + } + + if (unfilled.length === 0) { + this.passedIndexes.clear(); + this.markPassedConstraints(this.row); + if (this.isComplete) return true; + return { conflictKeys: this.findConflictKeys() }; + } + + const trier = new Row([...this.row.entries()]); + const depth = unfilled.length; + const indices = new Array(depth).fill(0); + let d = 0; + let lastConflictKeys: ReadonlySet | null = null; + + trier.set(unfilled[0].key, unfilled[0].values[0]); + + while (true) { + const entry = unfilled[d]; + const v = entry.values[indices[d]]; + const cand: CandidateType = [[entry.key, v]]; + const s = this.storable(cand, trier); + + if (s !== null) { + if (d === depth - 1) { + this.row.copy(trier); + this.passedIndexes.clear(); + this.markPassedConstraints(this.row); + if (this.isComplete) return true; + // Record which constraint failed for reporting to the caller. + lastConflictKeys = this.findConflictKeys(); + } else { + d++; + indices[d] = 0; + trier.set(unfilled[d].key, unfilled[d].values[0]); continue; } - const cand: CandidateType = [[k, v]]; - const storable = this.storable(cand); - if (storable == null) { - this.rejected.add(pairKey); - continue; + } + + while (true) { + indices[d]++; + if (indices[d] < unfilled[d].values.length) { + trier.set(unfilled[d].key, unfilled[d].values[indices[d]]); + break; + } + trier.delete(unfilled[d].key); + d--; + if (d < 0) { + this.reset(); + return { conflictKeys: lastConflictKeys }; } - trier.set(k, v); - break; } } - this.row.copy(trier); - if (this.isComplete) { - return true; + } + + get strength() { + return this.options.strength || 2; + } + + get allStrengths(): number[] { + const strengths = new Set([this.strength]); + for (const sub of this.options.subModels ?? []) { + strengths.add(sub.strength); } - if (trier.size === 0) { - return false; + return [...strengths]; + } + + private valueToSerial(key: ScalarType, value: any): number | null { + const factorValues = (this.factors as any)[key]; + if (!factorValues) return null; + const idx = factorValues.indexOf(value); + if (idx === -1) return null; + const serialList = this.serials.get(key); + if (!serialList) return null; + return serialList[idx]; + } + + private applyPreset(preset: any): boolean { + const entries: [ScalarType, number][] = []; + for (const [key, value] of getItems(preset)) { + const serial = this.valueToSerial(key, value); + if (serial === null) return false; + entries.push([key, serial]); } - const pairKey = trier.getPairKey(); - if (this.rejected.has(pairKey)) { - throw new NeverMatch(); + if (entries.length === 0) return false; + for (const [key, serial] of entries) { + this.row.set(key, serial); } - this.rejected.add(pairKey); - this.reset(); - return false; + return true; } - get pairwiseCount() { - return this.options.length || 2; + private orderByWeight(key: ScalarType, serials: PairType): PairType { + const weights = this.options.weights; + if (!weights) return serials; + const factorWeights = weights[key as string]; + if (!factorWeights) return serials; + const first = this.indices.get(serials[0]) as number; + return [...serials].sort((a, b) => { + const wa = factorWeights[(this.indices.get(a) as number) - first] ?? 1; + const wb = factorWeights[(this.indices.get(b) as number) - first] ?? 1; + return wb - wa; + }); } get isComplete() { - const filled = this.isFilled(this.row); - if (!filled) { - return false; - } - const proxy = this.toProxy(this.row); - try { - return this.options.preFilter?.(proxy) ?? true; - } catch (e) { - if (e instanceof NotReady) { - return false; + if (!this.isFilled(this.row)) return false; + if (this.constraints.length === 0) return true; + const obj = this.toObject(this.row); + for (let i = 0; i < this.constraints.length; i++) { + if (this.passedIndexes.has(i)) continue; + const result = evaluate(this.constraints[i].condition, obj, this.comparer); + // false = definitively violated. null (unknown) means a referenced key + // doesn't exist in the factors — treat as satisfied (constraint is + // vacuously true when it can never be evaluated). + if (result === false) return false; + } + return true; + } + + /** + * Find the keys of the first failing constraint on the current row. + * Returns the set of factor keys that participate in the conflict, + * or null if the row passes all constraints. + */ + private findConflictKeys(): ReadonlySet | null { + if (!this.isFilled(this.row)) return null; + const obj = this.toObject(this.row); + for (let i = 0; i < this.constraints.length; i++) { + if (this.passedIndexes.has(i)) continue; + if (evaluate(this.constraints[i].condition, obj, this.comparer) === false) { + return this.constraints[i].keys; } - throw e; } + return null; } - get progress() { - if (this.numAllChunks === 0) { - return 0; + /** + * Analyse remaining incomplete pairs and identify which constraint(s) + * make each pair infeasible. Used to build a diagnostic when throwing + * NeverMatch. + */ + private diagnoseUncoveredPairs(): UncoveredPair[] { + const result: UncoveredPair[] = []; + for (const [, pair] of this.incomplete.entries()) { + const cand = this.getCandidate(pair); + // Convert serial-based candidate to human-readable key→value. + const pairObj: Record = {}; + for (const [key, serial] of cand) { + const idx = this.indices.get(serial) as number; + const serials = this.serials.get(key) as PairType; + const first = this.indices.get(serials[0]) as number; + // @ts-ignore TS7015 + pairObj[key as string] = this.factors[key][idx - first]; + } + + // Find which constraints fail or are unsatisfiable via forward check. + const snapshot = new Row(cand); + const snapshotObj = this.toObject(snapshot); + const failingConstraints: number[] = []; + for (let i = 0; i < this.constraints.length; i++) { + const r = evaluate(this.constraints[i].condition, snapshotObj, this.comparer); + if (r === false) { + failingConstraints.push(i); + } + } + // If no direct failure, the pair fails due to forward-check chain. + // Report all constraints that share keys with the pair. + if (failingConstraints.length === 0) { + const pairKeys = new Set(Object.keys(pairObj)); + for (let i = 0; i < this.constraints.length; i++) { + for (const k of this.constraints[i].keys) { + if (pairKeys.has(k)) { + failingConstraints.push(i); + break; + } + } + } + } + result.push({ pair: pairObj, constraints: failingConstraints }); + } + return result; + } + + /** + * Record which factor values were filled by close() (completion) rather + * than by greedy. `greedyKeys` are the keys that were already in the row + * before close() ran. + */ + private recordCompletions(row: Row, greedyKeys: Set) { + for (const [key, serial] of row.entries()) { + if (greedyKeys.has(key)) continue; + const idx = this.indices.get(serial) as number; + const serials = this.serials.get(key) as PairType; + const first = this.indices.get(serials[0]) as number; + // @ts-ignore TS7015 + const value = String(this.factors[key][idx - first]); + const keyStr = String(key); + if (!this._completions[keyStr]) { + this._completions[keyStr] = {}; + } + this._completions[keyStr][value] = (this._completions[keyStr][value] ?? 0) + 1; } - return 1 - this.incomplete.size / this.numAllChunks; + } + + + get progress() { + return this.stats.progress; + } + + public make(): SuggestRowType[] { + return [...this.makeAsync()]; } public *makeAsync() { - const {criterion = greedy, postFilter} = this.options; - do { + const {criterion = greedy, presets = []} = this.options; + + for (const preset of presets) { + if (!this.applyPreset(preset)) continue; + const presetKeys = new Set(this.row.keys()); + try { + const result = this.close(); + if (result === true) { + this.recordCompletions(this.row, presetKeys); + this.consumePairs(this.row); + this._rowCount++; + yield this.restore() as SuggestRowType; + } + } catch (e) { + if (e instanceof NeverMatch) { + this.row = new Row([]); + this.passedIndexes.clear(); + } else { + throw e; + } + } + } + + let consecutiveFailures = 0; + while (this.incomplete.size) { + // Phase 1: greedy selects pairs and setPair validates via snapshot. + // Pairs that fail are added to row.invalidPairs and skipped. for (let pair of criterion(this)) { - if (this.isFilled(this.row)) { - break; + if (this.isFilled(this.row)) break; + const pk = unique(pair); + if (this.row.invalidPairs.has(pk)) continue; + if (!this.setPair(pair)) { + this.row.invalidPairs.add(pk); } - this.setPair(pair); } + + // Remember which keys greedy filled, so we can identify completions. + const greedyKeys = new Set(this.row.keys()); + + // Phase 2: If no valid pairs remain (incomplete - invalidPairs is + // empty), or the row is filled, proceed to close (completion). try { - const complete = this.close(); - if (complete) { - if (!postFilter || postFilter(this.toObject(this.row))) { - yield this.restore() as SuggestRowType; - } else { - this.discard(); + const result = this.close(); + if (result === true) { + this.recordCompletions(this.row, greedyKeys); + this.consumePairs(this.row); + this._rowCount++; + yield this.restore() as SuggestRowType; + consecutiveFailures = 0; + } else { + consecutiveFailures++; + if (consecutiveFailures > this.incomplete.size) { + break; + } + // Carry the invalidPairs from this failed row into the next + // attempt so greedy avoids the same pairs. + const failedPairs = this.row.invalidPairs; + // Also mark pairs that were in the row (greedy selected them + // but close couldn't complete them). + for (const s of this.allStrengths) { + for (let p of combinations([...this.row.values()], s)) { + failedPairs.add(unique(p)); + } + } + this.reset(); + this.rejected.clear(); + // Transfer to the new row. + for (const pk of failedPairs) { + this.row.invalidPairs.add(pk); } } } catch (e) { if (e instanceof NeverMatch) { - break; + this.reset(); + this.rejected.clear(); + continue; } throw e; } - } while (this.incomplete.size); - this.incomplete.clear(); + } + + // Phase 3 (rescue): greedy couldn't cover remaining pairs. Try each + // one individually — set just that pair, then close(). This trades + // row-efficiency for coverage completeness. + for (const [, pair] of [...this.incomplete.entries()]) { + this.reset(); + if (!this.setPair(pair)) continue; + const rescueKeys = new Set(this.row.keys()); + const result = this.close(); + if (result === true) { + this.recordCompletions(this.row, rescueKeys); + this.consumePairs(this.row); + this._rowCount++; + yield this.restore() as SuggestRowType; + } else { + this.reset(); + } + } + + if (this.incomplete.size > 0) { + this._uncoveredPairs = this.diagnoseUncoveredPairs(); + } + } } diff --git a/typescript/src/criteria/greedy.ts b/typescript/src/criteria/greedy.ts index 512b6de..c4cb9ca 100644 --- a/typescript/src/criteria/greedy.ts +++ b/typescript/src/criteria/greedy.ts @@ -1,50 +1,97 @@ -import type {FactorsType, PairByKeyType, PairType} from '../types'; +import type {FactorsType, PairByKeyType, PairType, ScalarType} from '../types'; import { combinations, unique } from '../lib'; import { Controller } from '../controller'; -const getNumRemovablePairs = (indexes: Set, incomplete: PairByKeyType, length: number) => { +const getNumRemovablePairs = (indexes: Set, incomplete: PairByKeyType, strengths: number[], exclude?: Set) => { let num = 0; - const removingKeys = combinations([... indexes], length); - for (let pair of removingKeys) { - const key = unique(pair); - if (incomplete.has(key)) { - num++; + for (const s of strengths) { + if (s === 2) { + // Fast path for pairwise: avoid combinations/unique overhead. + const arr = [...indexes]; + const len = arr.length; + for (let i = 0; i < len - 1; i++) { + const ai = arr[i]; + for (let j = i + 1; j < len; j++) { + const key = ai * arr[j]; + if (incomplete.has(key) && (!exclude || !exclude.has(key))) { + num++; + } + } + } + } else { + for (let pair of combinations([...indexes], s)) { + const key = unique(pair); + if (incomplete.has(key) && (!exclude || !exclude.has(key))) { + num++; + } + } } } return num; }; export default function* (ctrl: Controller): Generator { + const hasConstraints = (ctrl.options?.constraints?.length ?? 0) > 0; while (true) { let maxNumPairs: number | null = null; let efficientPair: PairType | null = null; + // Compute the set of pairs already covered by the current row so + // getNumRemovablePairs can exclude them. These pairs are still in + // `incomplete` (consumption happens at yield time) but should not be + // counted as "removable" — they are already guaranteed to be covered + // by this row if it succeeds. + const rowCovered = new Set(); + if (ctrl.row.size > 0) { + for (const s of ctrl.allStrengths) { + for (const p of combinations([...ctrl.row.values()], s)) { + rowCovered.add(unique(p)); + } + } + } + for (const [pairKey, pair] of ctrl.incomplete.entries()) { const rowSize = ctrl.row.size; - if (rowSize === 0) { - yield pair; - continue; - } if (ctrl.isFilled(ctrl.row)) { break; } - const storable = ctrl.storable(ctrl.getCandidate(pair)); - if (storable === null) { + // Skip pairs already covered by the current row. + if (rowCovered.has(pairKey)) continue; + + // Skip pairs that have been tried and failed for this row. + if (ctrl.row.invalidPairs.has(pairKey)) continue; + + // Fast path: check compatibility without allocations + const compat = rowSize === 0 ? pair.length : ctrl.isCompatible(pair); + if (compat === null) { continue; } - - if (storable === 0) { - ctrl.consume(pair); + if (compat === 0) { continue; } + + // If constraints exist, do full storable check + let storable = compat; + if (hasConstraints) { + const fullStorable = ctrl.storable(ctrl.getCandidate(pair)); + if (fullStorable === null) { + continue; + } + if (fullStorable === 0) { + continue; + } + storable = fullStorable; + } + const storableAbs = Math.abs(storable); const { tolerance = 0 } = ctrl.options!; - + const numPairs = getNumRemovablePairs( - new Set([...ctrl.row.values(), ...pair]), - ctrl.incomplete, - ctrl.pairwiseCount, + new Set([...ctrl.row.values(), ...pair]), + ctrl.incomplete, + ctrl.allStrengths, + rowCovered, ); if (numPairs + tolerance > rowSize * storableAbs) { @@ -55,6 +102,7 @@ export default function* (ctrl: Controller): Generator maxNumPairs = numPairs; efficientPair = pair; } + } if (efficientPair === null) { break; diff --git a/typescript/src/evaluate.ts b/typescript/src/evaluate.ts new file mode 100644 index 0000000..b9996d0 --- /dev/null +++ b/typescript/src/evaluate.ts @@ -0,0 +1,133 @@ +import type { Condition, Comparer, DictType } from './types'; + +export type TriState = true | false | null; + +/** + * Resolve a dot-separated field path against a row object. + * Returns `undefined` if any segment is missing. + */ +export function resolve(row: DictType, field: string): any { + const parts = field.split('.'); + let current: any = row; + for (const part of parts) { + if (current === undefined || current === null) return undefined; + current = current[part]; + } + return current; +} + +/** + * Extract the set of top-level factor keys that a condition depends on. + * For dot-separated paths, only the first segment is returned (that is the + * factor key; deeper segments are properties within the factor value). + */ +export function extractKeys(c: Condition): Set { + switch (c.operator) { + case 'not': + return extractKeys(c.condition); + case 'and': + case 'or': { + const keys = new Set(); + for (const sub of c.conditions) { + for (const k of extractKeys(sub)) keys.add(k); + } + return keys; + } + case 'custom': + return new Set(c.keys); + default: { + const keys = new Set(); + keys.add(c.field.split('.')[0]); + if ('target' in c && typeof c.target === 'string') { + keys.add(c.target.split('.')[0]); + } + return keys; + } + } +} + +const DEFAULT_COMPARER: Required = { + eq: (a, b) => a === b, + ne: (a, b) => a !== b, + gt: (a, b) => a > b, + lt: (a, b) => a < b, + gte: (a, b) => a >= b, + lte: (a, b) => a <= b, + in: (value, values) => values.includes(value), +}; + +/** + * Evaluate a `Condition` against a (possibly incomplete) row under Kleene + * three-valued logic. + * + * - `true` — the condition is satisfied + * - `false` — the condition is definitively violated + * - `null` — a referenced field is missing; the result is inconclusive + * + * The `comparer` is only called when both operands are resolved (not + * `undefined`). + */ +export function evaluate( + c: Condition, + row: DictType, + comparer: Comparer = {}, +): TriState { + switch (c.operator) { + // -- logical -- + case 'not': { + const r = evaluate(c.condition, row, comparer); + if (r === null) return null; + return !r; + } + case 'and': { + let hasUnknown = false; + for (const sub of c.conditions) { + const r = evaluate(sub, row, comparer); + if (r === false) return false; + if (r === null) hasUnknown = true; + } + return hasUnknown ? null : true; + } + case 'or': { + let hasUnknown = false; + for (const sub of c.conditions) { + const r = evaluate(sub, row, comparer); + if (r === true) return true; + if (r === null) hasUnknown = true; + } + return hasUnknown ? null : false; + } + + // -- custom -- + case 'custom': { + for (const k of c.keys) { + if (resolve(row, k) === undefined) return null; + } + return c.evaluate(row); + } + + // -- in -- + case 'in': { + const v = resolve(row, c.field); + if (v === undefined) return null; + return (comparer.in ?? DEFAULT_COMPARER.in)(v, c.values); + } + + // -- comparison -- + default: { + const v = resolve(row, c.field); + if (v === undefined) return null; + + let target: any; + if ('target' in c) { + target = resolve(row, c.target); + if (target === undefined) return null; + } else { + target = (c as any).value; + } + + const fn = comparer[c.operator] ?? DEFAULT_COMPARER[c.operator]; + return fn(v, target); + } + } +} diff --git a/typescript/src/exceptions.ts b/typescript/src/exceptions.ts index 677f9fe..9e8bf85 100644 --- a/typescript/src/exceptions.ts +++ b/typescript/src/exceptions.ts @@ -6,5 +6,18 @@ export class NotReady extends Error { } } +export interface UncoveredPair { + /** The pair expressed as factor-key → value entries. */ + pair: Record; + /** The constraint(s) that made this pair infeasible, if identifiable. */ + constraints: number[]; +} + export class NeverMatch extends Error { + public uncoveredPairs: UncoveredPair[]; + + constructor(message?: string, uncoveredPairs: UncoveredPair[] = []) { + super(message); + this.uncoveredPairs = uncoveredPairs; + } }; diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 2b86560..e0e126d 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -5,9 +5,9 @@ import random from "./sorters/random"; import greedy from "./criteria/greedy"; import simple from "./criteria/simple"; -import {PictConstraintsLexer} from "./utils/pict"; -import { FactorsType, OptionsType, SuggestRowType, DictType, ListType } from "./types"; -import { Controller } from "./controller"; +import { FactorsType, OptionsType, SuggestRowType, DictType, ListType, Condition, ComparisonCondition, LogicalCondition, CustomCondition, Comparer } from "./types"; +import { Controller, ControllerStats } from "./controller"; +import { NeverMatch, UncoveredPair } from "./exceptions"; const makeAsync = function* ( factors: T, @@ -18,19 +18,27 @@ const makeAsync = function* ( }; const make = (factors: T, options: OptionsType = {}) => { - return [...makeAsync(factors, options)]; + const ctrl = new Controller(factors, options); + const rows = ctrl.make(); + if (ctrl.stats.uncoveredPairs.length > 0) { + throw new NeverMatch( + `Unable to cover ${ctrl.stats.uncoveredPairs.length} remaining pair(s) without violating constraints`, + ctrl.stats.uncoveredPairs, + ); + } + return rows; }; const sorters = { hash, random }; const criteria = { greedy, simple }; -export { +export { make, makeAsync, sorters, criteria, - PictConstraintsLexer, Controller, + NeverMatch, }; export type { @@ -38,6 +46,12 @@ export type { SuggestRowType, DictType, ListType, + Condition, + ComparisonCondition, + LogicalCondition, + CustomCondition, + Comparer, + UncoveredPair, + ControllerStats, } -export default make; diff --git a/typescript/src/utils/pict.ts b/typescript/src/pict/constraints.ts similarity index 50% rename from typescript/src/utils/pict.ts rename to typescript/src/pict/constraints.ts index 5ebef26..cf87a59 100644 --- a/typescript/src/utils/pict.ts +++ b/typescript/src/pict/constraints.ts @@ -1,12 +1,11 @@ -import type { FilterRowType, FilterType } from '../types'; +import type { FilterRowType } from '../types'; + +type FilterType = (row: FilterRowType) => boolean; type Token = { type: TokenType; value: string; -} - -type CacheType = { - [key: string]: any; + line: number; // 1-based line number where this token starts }; enum TokenType { @@ -31,40 +30,43 @@ enum TokenType { UNKNOWN = 'UNKNOWN', } -function classifyToken(token: string): Token { +type Evaluator = (row: FilterRowType) => any; + +function classifyToken(token: string, line: number): Token { if (token.startsWith('[') && token.endsWith(']')) { - return { type: TokenType.REF, value: token }; + return { type: TokenType.REF, value: token, line }; } if (token.startsWith('"') && token.endsWith('"')) { - return { type: TokenType.STRING, value: token }; + return { type: TokenType.STRING, value: token, line }; } if (!isNaN(parseFloat(token))) { - return { type: TokenType.NUMBER, value: token }; + return { type: TokenType.NUMBER, value: token, line }; } if (['TRUE', 'FALSE'].includes(token.toUpperCase())) { - return { type: TokenType.BOOLEAN, value: token.toUpperCase() }; + return { type: TokenType.BOOLEAN, value: token.toUpperCase(), line }; } if (token.toUpperCase() === TokenType.NULL) { - return { type: TokenType.NULL, value: token.toUpperCase() }; + return { type: TokenType.NULL, value: token.toUpperCase(), line }; } if ([TokenType.IF, TokenType.ELSE, TokenType.THEN].includes(token.toUpperCase() as TokenType)) { - return { type: token.toUpperCase() as TokenType, value: token.toUpperCase() }; + return { type: token.toUpperCase() as TokenType, value: token.toUpperCase(), line }; } if (['=', '<>', '>', '<', '>=', '<=', 'IN', 'LIKE'].includes(token.toUpperCase())) { - return { type: TokenType.COMPARER, value: token.toUpperCase() }; + return { type: TokenType.COMPARER, value: token.toUpperCase(), line }; } if (['AND', 'OR', 'NOT'].includes(token.toUpperCase())) { - return { type: TokenType.OPERATOR, value: token.toUpperCase() }; + return { type: TokenType.OPERATOR, value: token.toUpperCase(), line }; } switch (token) { - case '(': return { type: TokenType.LPAREN, value: token }; - case ')': return { type: TokenType.RPAREN, value: token }; - case '{': return { type: TokenType.LBRACE, value: token }; - case '}': return { type: TokenType.RBRACE, value: token }; - case ',': return { type: TokenType.COMMA, value: token }; - case ':': return { type: TokenType.COLON, value: token }; - case ';': return { type: TokenType.SEMICOLON, value: token }; - default: return { type: TokenType.UNKNOWN, value: token }; + case '(': return { type: TokenType.LPAREN, value: token, line }; + case ')': return { type: TokenType.RPAREN, value: token, line }; + case '{': return { type: TokenType.LBRACE, value: token, line }; + case '}': return { type: TokenType.RBRACE, value: token, line }; + case ',': return { type: TokenType.COMMA, value: token, line }; + case ':': return { type: TokenType.COLON, value: token, line }; + case ';': return { type: TokenType.SEMICOLON, value: token, line }; + default: + return { type: TokenType.UNKNOWN, value: token, line }; } } @@ -74,24 +76,57 @@ const isWhiteSpace = (char: string) => { export class PictConstraintsLexer { private tokens: Token[] = []; - private cache: CacheType = {}; public filters: (FilterType | null)[] = []; public errors: (string | null)[] = []; + // Line number where each filter/error originated (1-based, in the original input). + public filterLines: number[] = []; + // Set of factor keys each filter depends on. Same length as `filters`. + // Empty set entries correspond to errors / null filters. + public filterKeys: Set[] = []; - constructor(private input: string, private debug=false) { - this.tokenize(); + constructor( + private input: string, + private debug = false, + private aliases: Map = new Map(), + private caseInsensitive: boolean = false, + private startLine: number = 1, + ) { + try { + this.tokenize(); + } catch (e: any) { + if (this.debug) { + console.error(`Tokenize error:`, e.message); + } + this.errors.push(e.message); + this.filterLines.push(this.startLine); + return; + } this.analyze(); } private tokenize(): Token[] { const constraints = this.input; const tokens: Token[] = []; let buffer = ''; + let bufferLine = this.startLine; + let currentLine = this.startLine; let insideQuotes = false; let insideBraces = false; let insideBrackets = false; - const addToken = (type: TokenType, value: string) => { - tokens.push({ type, value }); + const addToken = (type: TokenType, value: string, line: number) => { + tokens.push({ type, value, line }); + }; + + const flushBuffer = () => { + if (buffer.length > 0) { + tokens.push(classifyToken(buffer, bufferLine)); + buffer = ''; + } + }; + + const startBuffer = (ch: string) => { + if (buffer.length === 0) bufferLine = currentLine; + buffer += ch; }; for (let i = 0; i < constraints.length; i++) { @@ -99,83 +134,78 @@ export class PictConstraintsLexer { if (char === '"') { insideQuotes = !insideQuotes; - buffer += char; + startBuffer(char); if (!insideQuotes) { - addToken(TokenType.STRING, buffer); + addToken(TokenType.STRING, buffer, bufferLine); buffer = ''; } } else if (insideQuotes) { - buffer += char; + startBuffer(char); } else if (char === '[') { - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } + flushBuffer(); insideBrackets = true; - buffer += char; + startBuffer(char); } else if (char === ']' && insideBrackets) { - buffer += char; - tokens.push(classifyToken(buffer)); + startBuffer(char); + tokens.push(classifyToken(buffer, bufferLine)); insideBrackets = false; buffer = ''; } else if (char === '{') { insideBraces = true; - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } - addToken(TokenType.LBRACE, char); + flushBuffer(); + addToken(TokenType.LBRACE, char, currentLine); } else if (char === '}') { insideBraces = false; - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } - addToken(TokenType.RBRACE, char); + flushBuffer(); + addToken(TokenType.RBRACE, char, currentLine); } else if (char === ',' && insideBraces) { - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } - addToken(TokenType.COMMA, char); + flushBuffer(); + addToken(TokenType.COMMA, char, currentLine); } else if ('[]=<>!();:'.includes(char) && !insideBraces && !insideBrackets) { - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } + flushBuffer(); if (char === '<' || char === '>' || char === '!' || char === '=') { const nextChar = constraints[i + 1]; if (nextChar === '=') { - tokens.push(classifyToken(char + '=')); + tokens.push(classifyToken(char + '=', currentLine)); i++; } else if (char === '<' && nextChar === '>') { - tokens.push(classifyToken('<>')); + tokens.push(classifyToken('<>', currentLine)); i++; } else { - tokens.push(classifyToken(char)); + tokens.push(classifyToken(char, currentLine)); } } else { - tokens.push(classifyToken(char)); + tokens.push(classifyToken(char, currentLine)); } } else if (isWhiteSpace(char) && !insideBraces && !insideBrackets) { - if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); - buffer = ''; - } + flushBuffer(); let whitespaceBuffer = char; + if (char === '\n') currentLine++; while (i + 1 < constraints.length && isWhiteSpace(constraints[i + 1])) { - whitespaceBuffer += constraints[++i]; + i++; + whitespaceBuffer += constraints[i]; + if (constraints[i] === '\n') currentLine++; } - addToken(TokenType.WHITESPACE, whitespaceBuffer); + addToken(TokenType.WHITESPACE, whitespaceBuffer, currentLine); } else if (isWhiteSpace(char) && (insideBraces || insideBrackets)) { - buffer += char; + if (char === '\n') currentLine++; + startBuffer(char); } else { - buffer += char; + startBuffer(char); } } + if (insideQuotes) { + throw new Error(`Unterminated string literal: ${buffer}`); + } + if (insideBrackets) { + throw new Error(`Unterminated field reference: ${buffer}`); + } + if (insideBraces) { + throw new Error(`Unterminated set (missing closing "}")`); + } if (buffer.length > 0) { - tokens.push(classifyToken(buffer)); + tokens.push(classifyToken(buffer, bufferLine)); } this.tokens = tokens; return tokens; @@ -183,9 +213,15 @@ export class PictConstraintsLexer { private analyze() { let tokenIndex = 0; - let setIndex = 0; - let regexIndex = 0; const tokens = this.tokens; + const ci = this.caseInsensitive; + + // Normalize a value for comparison: lowercase strings if case-insensitive + const norm = (v: any) => (ci && typeof v === 'string') ? v.toLowerCase() : v; + + // Collects every factor key referenced while parsing the *current* + // statement. `close()` snapshots and resets it. + let currentKeys = new Set(); const nextToken = () => { while (tokenIndex < tokens.length && tokens[tokenIndex].type === 'WHITESPACE') { @@ -194,43 +230,43 @@ export class PictConstraintsLexer { return tokenIndex < tokens.length ? tokens[tokenIndex++] : null; } - const parseExpression: () => string = () => { - let expr = parseTerm(); + const parseExpression: () => Evaluator = () => { + let left = parseTerm(); let token = nextToken(); if (token?.type === TokenType.UNKNOWN) { throw new Error(`Unexpected token: ${token.value}`); } while (token && token.type === 'OPERATOR' && token.value === 'OR') { - const right = parseTerm(); - expr = `(${expr} || ${right})`; + const l = left, r = parseTerm(); + left = (row) => l(row) || r(row); token = nextToken(); } - tokenIndex--; // Go back one token - return expr || 'true'; + tokenIndex--; + return left; } - const parseTerm: () => string = () => { - let term = parseFactor(); + const parseTerm: () => Evaluator = () => { + let left = parseFactor(); let token = nextToken(); if (token?.type === TokenType.UNKNOWN) { throw new Error(`Unexpected token: ${token.value}`); } while (token && token.type === 'OPERATOR' && token.value === 'AND') { - const right = parseFactor(); - term = `(${term} && ${right})`; + const l = left, r = parseFactor(); + left = (row) => l(row) && r(row); token = nextToken(); } - tokenIndex--; // Go back one token - return term; + tokenIndex--; + return left; } - const parseFactor: () => string = () => { + const parseFactor: () => Evaluator = () => { let token = nextToken(); if (token != null) { if (token.type === 'OPERATOR' && token.value === 'NOT') { - const factor = parseFactor(); - return `!(${factor})`; + const operand = parseFactor(); + return (row) => !operand(row); } if (token.type === TokenType.LPAREN) { const expr = parseExpression(); @@ -238,24 +274,24 @@ export class PictConstraintsLexer { if (!token || token.type !== TokenType.RPAREN) { throw new Error('Expected closing parenthesis'); } - return `(${expr})`; + return expr; } if (token.type === TokenType.BOOLEAN) { - return token.value.toUpperCase() === 'TRUE' ? 'true' : 'false'; + const val = token.value.toUpperCase() === 'TRUE'; + return () => val; } if (token.type === TokenType.UNKNOWN) { throw new Error(`Unexpected token: ${token.value}`); } } - tokenIndex--; // Go back one token + tokenIndex--; return parseCondition(); } - const parseCondition: () => string = () => { + const parseCondition: () => Evaluator = () => { const left = parseOperand(); if (left == null) { throw new Error('Expected field or value after "IF", "THEN", "ELSE"'); - } const comparerToken = nextToken(); if ([TokenType.NUMBER, TokenType.STRING, TokenType.BOOLEAN, TokenType.NULL].includes(comparerToken?.type!)) { @@ -268,11 +304,31 @@ export class PictConstraintsLexer { throw new Error(`Expected comparison operator but found operator: ${comparerToken.value}`); } - const comparer = comparerToken?.value; - + if (!comparerToken || comparerToken.type !== TokenType.COMPARER) { + if (comparerToken?.value === '!=') { + throw new Error(`"!=" is not supported. Use "<>" for inequality comparison`); + } + throw new Error(`Unknown comparison operator: ${comparerToken?.value}`); + } + const comparer = comparerToken.value; + if (comparer === 'IN') { - const right = parseSet(); - return `${right}.has(${left})`; + const values = parseSet(); + return (row) => values.has(norm(left(row))); + } + if (comparer === 'LIKE') { + const right = parseOperand(); + if (right == null) { + throw new Error('Expected string pattern after LIKE'); + } + // Evaluate pattern once at parse time (it must be a literal) + const patternStr = right({} as FilterRowType); + if (typeof patternStr !== 'string') { + throw new Error('Expected string pattern after LIKE'); + } + const regexPattern = patternStr.replace(/\*/g, '.*').replace(/\?/g, '.'); + const regex = new RegExp('^' + regexPattern + '$', ci ? 'i' : ''); + return (row) => regex.test(left(row)); } const right = parseOperand(); if (right == null) { @@ -280,37 +336,33 @@ export class PictConstraintsLexer { } switch (comparer) { case '=': - return `${left} === ${right}`; + return (row) => norm(left(row)) === norm(right(row)); case '<>': - return `${left} !== ${right}`; + return (row) => norm(left(row)) !== norm(right(row)); case '>': - return `${left} > ${right}`; + return (row) => left(row) > right(row); case '<': - return `${left} < ${right}`; + return (row) => left(row) < right(row); case '>=': - return `${left} >= ${right}`; + return (row) => left(row) >= right(row); case '<=': - return `${left} <= ${right}`; - case 'LIKE': - const regexPattern = right.slice(1, -1).replace(/\*/g, '.*').replace(/\?/g, '.'); // remove quotes and replace wildcards - const regexKey = `re_${regexIndex++}`; - if (!this.cache[regexKey]) { - this.cache[regexKey] = new RegExp('^' + regexPattern + '$'); - } - return `this.cache['${regexKey}'].test(${left})`; + return (row) => left(row) <= right(row); default: throw new Error(`Unknown comparison operator: ${comparer}`); } } - const parseSet: () => string = () => { + const parseSet: () => Set = () => { const elements: string[] = []; let token = nextToken(); if (token && token.type === TokenType.LBRACE) { token = nextToken(); while (token && token.type !== TokenType.RBRACE) { if (token.type === TokenType.STRING) { - elements.push(token.value.slice(1, -1)); // remove quotes + const raw = token.value.slice(1, -1); // remove quotes + const lookup = ci ? raw.toLowerCase() : raw; + const resolved = this.aliases.get(lookup) ?? raw; + elements.push(norm(resolved)); } else if (token.type !== TokenType.COMMA && token.type !== TokenType.WHITESPACE) { throw new Error(`Unexpected token in array: ${token.value}`); } @@ -319,30 +371,34 @@ export class PictConstraintsLexer { } else { throw new Error(`Expected '{' but found ${token ? token.value : TokenType.NULL}`); } - const setKey = `set_${setIndex++}`; - if (!this.cache[setKey]) { - this.cache[setKey] = new Set(elements); + if (elements.length === 0) { + throw new Error('Empty set in IN clause'); } - return `this.cache['${setKey}']`; + return new Set(elements); } - const parseOperand: () => string | null = () => { + const parseOperand: () => Evaluator | null = () => { const token = nextToken(); if (token == null) { return null; } if (token.type === TokenType.REF) { const key = token.value.slice(1, -1); // remove [ and ] - return `row["${key}"]`; + currentKeys.add(key); + return (row) => row[key]; } else if (token.type === TokenType.STRING) { - const value = token.value; // keep quotes for string literals - return `${value}`; + const raw = token.value.slice(1, -1); // remove quotes + const lookup = ci ? raw.toLowerCase() : raw; + const value = this.aliases.get(lookup) ?? raw; + return () => value; } else if (token.type === TokenType.NUMBER) { - return token.value; + const value = parseFloat(token.value); + return () => value; } else if (token.type === TokenType.BOOLEAN) { - return token.value === 'TRUE' ? 'true' : 'false'; + const value = token.value === 'TRUE'; + return () => value; } else if (token.type === TokenType.NULL) { - return TokenType.NULL; + return () => null; } else { return null; } @@ -354,9 +410,12 @@ export class PictConstraintsLexer { } } - const close = (code: string | null, error: string | null) => { - // Invariably, one of the two will be null. - if (code == null) { + // The line number where the current statement started; updated by the + // outer loop each time it begins reading a new constraint. + let currentStatementLine = this.startLine; + + const close = (evaluator: Evaluator | null, error: string | null) => { + if (evaluator == null) { if (this.debug) { console.error(`Error[${this.errors.length}]:`, error); } @@ -364,20 +423,15 @@ export class PictConstraintsLexer { this.errors.push(error); } else { if (this.debug) { - console.debug(`Code[${this.filters.length}]:`, code); - } - try { - const f = this.makeClosure(code); - this.filters.push(f); - this.errors.push(null); - } catch (e) { - console.error(e); - this.filters.push(null); - // @ts-ignore - this.errors.push(`RuntimeError[${this.errors.length}]:`, e.message); + console.debug(`Filter[${this.filters.length}]: compiled`); } - + this.filters.push(evaluator as FilterType); + this.errors.push(null); } + this.filterLines.push(currentStatementLine); + this.filterKeys.push(currentKeys); + // Start a fresh dependency set for the next statement. + currentKeys = new Set(); } const read = () => { @@ -388,8 +442,8 @@ export class PictConstraintsLexer { // @ts-ignore close(null, e.message); } - // If the conditional expression ends with “ELSE”, - // the current index reaches a semicolon, and the next expression is skipped by the abandon function. + // If the conditional expression ends with "ELSE", + // the current index reaches a semicolon, and the next expression is skipped by the abandon function. // Therefore, the index is reset to the previous one. tokenIndex--; abandon(); @@ -401,50 +455,51 @@ export class PictConstraintsLexer { if (token == null) { break; } + currentStatementLine = token.line; if (token.type === TokenType.IF) { - const action = read(); - if (action == null) { + const condition = read(); + if (condition == null) { continue; } const thenToken = nextToken(); if (!thenToken || thenToken.type !== TokenType.THEN) { + close(null, `Expected "THEN" but found ${thenToken ? thenToken.value : 'end of input'}`); abandon() continue; } - const thenAction = read(); - if (thenAction == null) { + const thenEval = read(); + if (thenEval == null) { continue; } - + const elseToken = nextToken(); - let elseAction: string | null = 'true'; + let elseEval: Evaluator = () => true; if (elseToken && elseToken.type === TokenType.ELSE) { - elseAction = read(); - if (elseAction == null) { + const parsed = read(); + if (parsed == null) { continue; } + elseEval = parsed; } else { tokenIndex--; // Go back one token if ELSE is not found } - const code = `return (${action} ? (${thenAction}) : (${elseAction}));`; - close(code, null); + close((row) => condition(row) ? thenEval(row) : elseEval(row), null); } else if (token.type === TokenType.SEMICOLON) { // do nothing + } else if (token.type === TokenType.UNKNOWN) { + close(null, `Unknown token: ${token.value}`); + abandon(); } else { - if (token.type === TokenType.UNKNOWN) { - close(null, `Unknown token: ${token.value}`); - } else { - close(null, `The leading "IF" is missing, found ${token.value}`); + // Unconditional constraint: e.g. [A] <> [B] AND [C] = "x"; + tokenIndex--; + const expr = read(); + if (expr != null) { + close(expr, null); } - abandon(); } } } - private makeClosure (code: string) { - return new Function('row', code).bind(this) as FilterType; - } - filter = (row: FilterRowType, ...additionalFilters: FilterType[]) => { for (const f of this.filters) { if (f == null) { @@ -462,4 +517,3 @@ export class PictConstraintsLexer { return true; } } - diff --git a/typescript/src/pict/index.ts b/typescript/src/pict/index.ts new file mode 100644 index 0000000..9a4bad4 --- /dev/null +++ b/typescript/src/pict/index.ts @@ -0,0 +1,12 @@ +export { PictModel } from './model'; +export type { PictModelOptions } from './model'; +export { parse } from './parse'; +export type { ParseOptions, ParseResult } from './parse'; +export { weightsByValue } from './weights'; +export { PictModelError } from './types'; +export type { + PictFactorsType, + PictModelIssue, + IssueSeverity, + IssueSource, +} from './types'; diff --git a/typescript/src/pict/model.ts b/typescript/src/pict/model.ts new file mode 100644 index 0000000..47cd525 --- /dev/null +++ b/typescript/src/pict/model.ts @@ -0,0 +1,156 @@ +import type { + Condition, + FilterRowType, + OptionsType, + SubModelType, +} from '../types'; +import { Controller } from '../controller'; +import type { PictFactorsType, PictModelIssue } from './types'; +import { PictModelError } from './types'; +import { parse } from './parse'; +import type { PictConstraintsLexer } from './constraints'; + +export interface PictModelOptions { + caseInsensitive?: boolean; + strict?: boolean; +} + +export class PictModel { + private _parameters: PictFactorsType; + private _subModels: SubModelType[]; + private _negatives: Map>; + private _weights: { [factorKey: string]: { [index: number]: number } }; + private _lexer: PictConstraintsLexer | null; + private _controller: Controller | null = null; + public issues: PictModelIssue[]; + + constructor(input: string, options: PictModelOptions = {}) { + const { caseInsensitive = true, strict = false } = options; + const result = parse(input, { caseInsensitive }); + + this._parameters = result.factors; + this._subModels = result.subModels; + this._negatives = result.negatives; + this._weights = result.weights; + this._lexer = result.lexer; + this.issues = result.issues; + + if (strict && this.issues.some(i => i.severity === "error")) { + throw new PictModelError(this.issues); + } + } + + get parameters(): PictFactorsType { return this._parameters; } + get subModels(): SubModelType[] { return this._subModels; } + get constraints(): Condition[] { return this._modelConstraints(); } + get negatives(): Map> { return this._negatives; } + get weights(): { [factorKey: string]: { [index: number]: number } } { return this._weights; } + get progress(): number { return this._controller?.progress ?? 0; } + get stats() { return this._controller?.stats ?? null; } + + /** + * Evaluate all constraints and the negative-value rule against a + * (typically complete) row. Returns true if the row passes. + */ + filter = (row: FilterRowType) => { + let seenNegative = false; + for (const [key, negativeSet] of this._negatives) { + if (key in row && negativeSet.has(row[key])) { + if (seenNegative) return false; + seenNegative = true; + } + } + if (this._lexer) { + for (const f of this._lexer.filters) { + if (f == null) continue; + if (!f(row)) return false; + } + } + return true; + }; + + /** + * Convert this model's constraints into `Condition[]` for the controller. + * Each lexer filter becomes a `custom` condition with its dependency keys. + * The negative-value rule also becomes a `custom` condition. + */ + private _modelConstraints(): Condition[] { + const list: Condition[] = []; + + if (this._lexer) { + const filters = this._lexer.filters; + const filterKeys = this._lexer.filterKeys; + for (let i = 0; i < filters.length; i++) { + const f = filters[i]; + if (f == null) continue; + list.push({ + operator: 'custom', + keys: [...filterKeys[i]], + evaluate: f, + }); + } + } + + if (this._negatives.size > 0) { + const negativeKeys = [...this._negatives.keys()] as string[]; + const negatives = this._negatives; + list.push({ + operator: 'custom', + keys: negativeKeys, + evaluate: (row) => { + let seen = false; + for (const [key, set] of negatives) { + if (set.has(row[key])) { + if (seen) return false; + seen = true; + } + } + return true; + }, + }); + } + + return list; + } + + private _buildOptions(options: OptionsType = {}): OptionsType { + const { + constraints: userConstraints, + subModels: userSubModels, + weights: userWeights, + ...rest + } = options; + const constraints = [ + ...this._modelConstraints(), + ...(userConstraints ?? []), + ]; + const subModels = userSubModels ?? (this._subModels.length > 0 ? this._subModels : undefined); + const weights = userWeights ?? (Object.keys(this._weights).length > 0 ? this._weights : undefined); + return { ...rest, constraints, subModels, weights }; + } + + private _applyNegativePrefix(row: any): any { + if (this._negatives.size === 0) return row; + const result = { ...row }; + for (const [key, negSet] of this._negatives) { + if (negSet.has(result[key])) { + result[key] = `~${result[key]}`; + } + } + return result; + } + + make(options: OptionsType = {}) { + this._controller = new Controller(this._parameters, this._buildOptions(options)); + return [...this._controller.makeAsync()].map( + (row) => this._applyNegativePrefix(row) + ); + } + + *makeAsync(options: OptionsType = {}) { + this._controller = new Controller(this._parameters, this._buildOptions(options)); + for (const row of this._controller.makeAsync()) { + yield this._applyNegativePrefix(row); + } + } +} diff --git a/typescript/src/pict/parameters.ts b/typescript/src/pict/parameters.ts new file mode 100644 index 0000000..5e1c4b6 --- /dev/null +++ b/typescript/src/pict/parameters.ts @@ -0,0 +1,176 @@ +import type { PictFactorsType, PictModelIssue, SourceLine } from './types'; + +// Split comma-separated values respecting quoted strings +export function splitValues(input: string): string[] { + const values: string[] = []; + let current = ''; + let inQuotes = false; + for (const ch of input) { + if (ch === '"') { + inQuotes = !inQuotes; + current += ch; + } else if (ch === ',' && !inQuotes) { + if (current.trim()) values.push(current.trim()); + current = ''; + } else { + current += ch; + } + } + if (current.trim()) values.push(current.trim()); + return values; +} + +export function stripQuotes(s: string): string { + if (s.startsWith('"') && s.endsWith('"')) return s.slice(1, -1); + return s; +} + +// Parse a single value token, handling ~, (weight), |aliases, , "quotes" +export function parseValue( + raw: string, + existing: Record, + aliases: Map, +): { values: (string | number)[]; isNegative: boolean; weight: number } { + const trimmed = raw.trim(); + + // Parameter reference: + if (trimmed.startsWith('<') && trimmed.endsWith('>')) { + const refName = trimmed.slice(1, -1); + if (!(refName in existing)) { + throw new Error(`Unknown parameter reference: "${refName}"`); + } + return { values: [...existing[refName]], isNegative: false, weight: 1 }; + } + + let token = trimmed; + let isNegative = false; + let weight = 1; + + // Negative prefix: ~ + if (token.startsWith('~')) { + token = token.slice(1); + isNegative = true; + } + + // Weight suffix: (N) + const weightMatch = token.match(/\s*\((\d+)\)\s*$/); + if (weightMatch) { + weight = parseInt(weightMatch[1], 10); + token = token.slice(0, token.lastIndexOf('(')).trim(); + } + + // Aliases: take canonical (first) value, record the rest + if (token.includes('|')) { + const parts = token.split('|').map(s => s.trim()); + const canonical = stripQuotes(parts[0]); + for (let i = 1; i < parts.length; i++) { + const aliasValue = stripQuotes(parts[i]); + aliases.set(aliasValue, canonical); + } + token = parts[0]; + } + + // Quoted string + if (token.startsWith('"') && token.endsWith('"')) { + return { values: [token.slice(1, -1)], isNegative, weight }; + } + + // Number or string + const n = Number(token); + return { + values: [token !== '' && !isNaN(n) ? n : token], + isNegative, + weight, + }; +} + +export function isParameterLine(trimmed: string): boolean { + const colonIdx = trimmed.indexOf(':'); + if (colonIdx <= 0) return false; + // Constraint lines start with [ or IF + if (trimmed.startsWith('[')) return false; + if (/^IF\s/i.test(trimmed)) return false; + return true; +} + +export function parseParameters(lines: SourceLine[]): { + factors: PictFactorsType; + aliases: Map; + negatives: Map>; + weights: { [factorKey: string]: { [index: number]: number } }; + issues: PictModelIssue[]; +} { + const factors: PictFactorsType = {}; + const aliases = new Map(); + const negatives = new Map>(); + const weights: { [factorKey: string]: { [index: number]: number } } = {}; + const issues: PictModelIssue[] = []; + let factorIndex = 0; + + const addIssue = (line: number, message: string) => { + issues.push({ + severity: "error", + source: "factor", + index: factorIndex, + line, + message, + }); + }; + + for (const { text, line } of lines) { + const trimmed = text.trim(); + if (trimmed === '' || trimmed.startsWith('#')) continue; + + const colonIndex = trimmed.indexOf(':'); + if (colonIndex === -1) { + addIssue(line, `Invalid line (missing ":"): ${trimmed}`); + factorIndex++; + continue; + } + + const key = trimmed.slice(0, colonIndex).trim(); + if (key === '') { + addIssue(line, `Empty parameter name in line: ${trimmed}`); + factorIndex++; + continue; + } + + try { + const rawValues = splitValues(trimmed.slice(colonIndex + 1)); + const values: (string | number)[] = []; + const negativeSet = new Set(); + const factorWeights: { [index: number]: number } = {}; + for (const raw of rawValues) { + const parsed = parseValue(raw, factors, aliases); + const startIndex = values.length; + values.push(...parsed.values); + if (parsed.isNegative) { + for (const v of parsed.values) negativeSet.add(v); + } + if (parsed.weight !== 1) { + for (let i = 0; i < parsed.values.length; i++) { + factorWeights[startIndex + i] = parsed.weight; + } + } + } + + if (values.length === 0) { + addIssue(line, `No values for parameter "${key}"`); + factorIndex++; + continue; + } + + factors[key] = values; + if (negativeSet.size > 0) { + negatives.set(key, negativeSet); + } + if (Object.keys(factorWeights).length > 0) { + weights[key] = factorWeights; + } + } catch (e: any) { + addIssue(line, e.message); + } + factorIndex++; + } + return { factors, aliases, negatives, weights, issues }; +} diff --git a/typescript/src/pict/parse.ts b/typescript/src/pict/parse.ts new file mode 100644 index 0000000..e19ce8a --- /dev/null +++ b/typescript/src/pict/parse.ts @@ -0,0 +1,124 @@ +import type { SubModelType } from '../types'; +import type { PictFactorsType, PictModelIssue, SourceLine } from './types'; +import { isParameterLine, parseParameters } from './parameters'; +import { parseSubModel, subModelPattern } from './subModels'; +import { PictConstraintsLexer } from './constraints'; + +export interface ParseOptions { + /** Match constraint comparisons and alias lookups case-insensitively. Default: true. */ + caseInsensitive?: boolean; +} + +export interface ParseResult { + factors: PictFactorsType; + aliases: Map; + negatives: Map>; + weights: { [factorKey: string]: { [index: number]: number } }; + subModels: SubModelType[]; + lexer: PictConstraintsLexer | null; + issues: PictModelIssue[]; +} + +interface SplitSections { + parameterLines: SourceLine[]; + subModelLines: SourceLine[]; + constraintText: string; + constraintStartLine: number; +} + +function splitSections(input: string): SplitSections { + const lines = input.split('\n'); + const parameterLines: SourceLine[] = []; + const subModelLines: SourceLine[] = []; + let constraintStart = lines.length; + + for (let i = 0; i < lines.length; i++) { + const text = lines[i]; + const trimmed = text.trim(); + const lineNum = i + 1; // 1-based + if (trimmed === '' || trimmed.startsWith('#')) { + parameterLines.push({ text, line: lineNum }); + continue; + } + if (isParameterLine(trimmed)) { + parameterLines.push({ text, line: lineNum }); + } else if (subModelPattern.test(trimmed)) { + subModelLines.push({ text: trimmed, line: lineNum }); + } else { + constraintStart = i; + break; + } + } + + return { + parameterLines, + subModelLines, + constraintText: lines.slice(constraintStart) + .map(l => l.trim().startsWith('#') ? '' : l) + .join('\n'), + constraintStartLine: constraintStart + 1, + }; +} + +/** + * Parse a PICT-format model string into its constituent parts: parameters, + * sub-models, and constraints. Issues are collected rather than thrown so the + * caller can decide how to handle them. + */ +export function parse(input: string, options: ParseOptions = {}): ParseResult { + const { caseInsensitive = true } = options; + const sections = splitSections(input); + const issues: PictModelIssue[] = []; + + // Parameters + const { factors, aliases, negatives, weights, issues: paramIssues } = + parseParameters(sections.parameterLines); + issues.push(...paramIssues); + + // Normalize alias keys for case-insensitive lookup + const lexerAliases = caseInsensitive + ? new Map(Array.from(aliases, ([k, v]) => [k.toLowerCase(), v])) + : aliases; + + // Sub-models + const subModels: SubModelType[] = []; + sections.subModelLines.forEach(({ text, line }, subIndex) => { + const sub = parseSubModel(text); + if (sub) { + subModels.push(sub); + } else { + issues.push({ + severity: "error", + source: "subModel", + index: subIndex, + line, + message: `Invalid sub-model definition: ${text}`, + }); + } + }); + + // Constraints + let lexer: PictConstraintsLexer | null = null; + if (sections.constraintText.trim()) { + lexer = new PictConstraintsLexer( + sections.constraintText, + false, + lexerAliases, + caseInsensitive, + sections.constraintStartLine, + ); + lexer.errors.forEach((err, constraintIndex) => { + if (err == null) return; + const line = lexer!.filterLines[constraintIndex] ?? sections.constraintStartLine; + issues.push({ + severity: "error", + source: "constraint", + index: constraintIndex, + line, + message: err, + }); + }); + } + + return { factors, aliases, negatives, weights, subModels, lexer, issues }; +} diff --git a/typescript/src/pict/subModels.ts b/typescript/src/pict/subModels.ts new file mode 100644 index 0000000..ee7507e --- /dev/null +++ b/typescript/src/pict/subModels.ts @@ -0,0 +1,12 @@ +import type { SubModelType } from '../types'; + +// Parse sub-model line: { P1, P2, P3 } @ N +export const subModelPattern = /^\{\s*(.+?)\s*\}\s*@\s*(\d+)\s*$/; + +export function parseSubModel(line: string): SubModelType | null { + const match = line.match(subModelPattern); + if (!match) return null; + const keys = match[1].split(',').map(k => k.trim()).filter(k => k !== ''); + const strength = parseInt(match[2], 10); + return { keys, strength }; +} diff --git a/typescript/src/pict/types.ts b/typescript/src/pict/types.ts new file mode 100644 index 0000000..fe3baa4 --- /dev/null +++ b/typescript/src/pict/types.ts @@ -0,0 +1,31 @@ +export type PictFactorsType = { [key: string]: (string | number)[] }; + +/** A source line tagged with its 1-based line number in the original input. */ +export interface SourceLine { + text: string; + line: number; // 1-based +} + +export type IssueSeverity = "error" | "warning"; +export type IssueSource = "factor" | "subModel" | "constraint"; + +export interface PictModelIssue { + severity: IssueSeverity; + source: IssueSource; + index: number; // 0-based index within the source + line: number; // 1-based line number in the original input + message: string; +} + +export class PictModelError extends Error { + public readonly issues: PictModelIssue[]; + constructor(issues: PictModelIssue[]) { + const errs = issues.filter(i => i.severity === "error"); + const summary = errs + .map(i => ` [${i.source}#${i.index} line ${i.line}] ${i.message}`) + .join("\n"); + super(`PictModel has ${errs.length} error(s):\n${summary}`); + this.name = "PictModelError"; + this.issues = issues; + } +} diff --git a/typescript/src/pict/weights.ts b/typescript/src/pict/weights.ts new file mode 100644 index 0000000..fce4d34 --- /dev/null +++ b/typescript/src/pict/weights.ts @@ -0,0 +1,32 @@ +import type { PictFactorsType } from './types'; + +/** + * Convert value-keyed weights to index-keyed weights for use with `OptionsType.weights`. + * Useful when you want to specify weights by value rather than by index position. + * + * @example + * weightsByValue( + * { Browser: ["Chrome", "Firefox", "Safari"] }, + * { Browser: { Chrome: 10, Safari: 5 } }, + * ) + * // → { Browser: { 0: 10, 2: 5 } } + */ +export function weightsByValue( + factors: T, + valueWeights: { [factorKey: string]: { [value: string]: number } }, +): { [factorKey: string]: { [index: number]: number } } { + const result: { [factorKey: string]: { [index: number]: number } } = {}; + for (const [key, vw] of Object.entries(valueWeights)) { + const values = factors[key]; + if (!values) continue; + const indexWeights: { [index: number]: number } = {}; + for (const [valueStr, weight] of Object.entries(vw)) { + const idx = values.findIndex(v => String(v) === valueStr); + if (idx >= 0) indexWeights[idx] = weight; + } + if (Object.keys(indexWeights).length > 0) { + result[key] = indexWeights; + } + } + return result; +} diff --git a/typescript/src/sorters/hash.ts b/typescript/src/sorters/hash.ts index d84fe7c..5ffe91e 100644 --- a/typescript/src/sorters/hash.ts +++ b/typescript/src/sorters/hash.ts @@ -8,10 +8,10 @@ export default function ( pairs: PairType[], sortArgs: SortArgsType, ): PairType[] { - const {seed, indices} = sortArgs; + const {salt, indices} = sortArgs; const comparer = (a: PairType, b: PairType) => { - const aKey = `${a.map((n) => indices.get(n) as number)} ${seed}`; - const bKey = `${b.map((n) => indices.get(n) as number)} ${seed}`; + const aKey = `${a.map((n) => indices.get(n) as number)} ${salt}`; + const bKey = `${b.map((n) => indices.get(n) as number)} ${salt}`; return fnv1a32(aKey) > fnv1a32(bKey) ? 1 : -1; } return pairs.sort(comparer); diff --git a/typescript/src/types.ts b/typescript/src/types.ts index e48be1d..be5beda 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -22,18 +22,13 @@ export type SuggestRowType = T extends ArrayTupleType : T extends ArrayObjectType ? { [K in keyof T]: T[K][number] } : unknown; -export type FilterType = (row: FilterRowType) => boolean; -export type SuggestFilterType = (row: SuggestRowType) => boolean; - export type PairType = number[]; export type PairByKeyType = Map; export type CandidateType = [ScalarType, number][]; -export interface RowType { - consumed: PairByKeyType; -}; +export interface RowType {}; export type SorterType = ( pairs: PairType[], @@ -41,23 +36,117 @@ export type SorterType = ( ) => PairType[]; export interface SortArgsType { - seed: ScalarType; + salt: ScalarType; indices: IndicesType; }; export interface CriterionArgsType { row: RowType; parents: ParentsType; - length: number; + strength: number; tolerance: number; }; +export interface SubModelType { + keys: ScalarType[]; + strength: number; +}; + +export type WeightsType = { [factorKey: string]: { [index: number]: number } }; + +export type PresetRowType = { [key: string]: any; [index: number]: any }; + +// --------------------------------------------------------------------------- +// Declarative constraints +// --------------------------------------------------------------------------- + +/** + * A comparison condition. `field` supports dot notation for nested access + * (e.g. `"payment.method"`). `target` references another field for + * field-to-field comparisons. + */ +export type ComparisonCondition = + | { operator: 'eq'; field: string; value: any } + | { operator: 'eq'; field: string; target: string } + | { operator: 'ne'; field: string; value: any } + | { operator: 'ne'; field: string; target: string } + | { operator: 'gt'; field: string; value: any } + | { operator: 'gt'; field: string; target: string } + | { operator: 'lt'; field: string; value: any } + | { operator: 'lt'; field: string; target: string } + | { operator: 'gte'; field: string; value: any } + | { operator: 'gte'; field: string; target: string } + | { operator: 'lte'; field: string; value: any } + | { operator: 'lte'; field: string; target: string } + | { operator: 'in'; field: string; values: any[] }; + +export type LogicalCondition = + | { operator: 'not'; condition: Condition } + | { operator: 'and'; conditions: Condition[] } + | { operator: 'or'; conditions: Condition[] }; + +/** + * Escape hatch for constraints that cannot be expressed declaratively. + * The engine cannot perform three-valued reasoning on these — when a + * dependency key is missing the condition is treated as `null`. + * Provide `keys` so the engine knows when it is safe to call `evaluate`. + */ +export type CustomCondition = { + operator: 'custom'; + keys: string[]; + evaluate: (row: { [key: string]: any }) => boolean; +}; + +export type Condition = ComparisonCondition | LogicalCondition | CustomCondition; + +/** + * Custom comparison functions. Each key matches a comparison operator name. + * When provided, the corresponding function is called instead of the default + * JS comparison. The function receives two resolved (non-undefined) values + * and must return a boolean. + * + * The `in` comparer receives the field value and the values array. + * + * `undefined` values (= field not yet set in the row) are **never** passed + * to a comparer — the engine returns `null` before reaching the + * comparer in that case. + */ +export interface Comparer { + eq?: (a: any, b: any) => boolean; + ne?: (a: any, b: any) => boolean; + gt?: (a: any, b: any) => boolean; + lt?: (a: any, b: any) => boolean; + gte?: (a: any, b: any) => boolean; + lte?: (a: any, b: any) => boolean; + in?: (value: any, values: any[]) => boolean; +} + +// --------------------------------------------------------------------------- +// Options +// --------------------------------------------------------------------------- + export interface OptionsType { - length?: number; + strength?: number; + subModels?: SubModelType[]; + weights?: WeightsType; + presets?: PresetRowType[]; sorter?: SorterType; criterion?: (ctrl: Controller) => IterableIterator; - seed?: ScalarType; + salt?: ScalarType; tolerance?: number; - preFilter?: FilterType | SuggestFilterType; - postFilter?: FilterType | SuggestFilterType; + /** + * Declarative constraints. Each entry is a `Condition` tree that the + * generator evaluates under Kleene three-valued logic: when a referenced + * field is not yet present in the row the result is `null` (deferred) + * rather than `false`, so the generator can prune early without + * discarding viable combinations. + * + * The top-level array is an implicit AND: every condition must be + * satisfied for a row to be accepted. + */ + constraints?: Condition[]; + /** + * Custom comparison functions. See `Comparer` for details. + */ + comparer?: Comparer; }; diff --git a/typescript/tmp/find_best_seed.ts b/typescript/tmp/find_best_seed.ts new file mode 100644 index 0000000..67e5c32 --- /dev/null +++ b/typescript/tmp/find_best_seed.ts @@ -0,0 +1,36 @@ +import make from '../src/index'; +import { range } from '../src/lib'; + +// 10 factors, each with 20 levels = 10^20 combinations +const factors: string[][] = []; +for (let i = 0; i < 10; i++) { + factors.push(range(0, 20).map((j: number) => `f${i}_${j}`)); +} + +let minRows = Infinity; +let bestSeed = 0; +const results: [number, number][] = []; + +for (let seed = 1; seed <= 200; seed++) { + const rows = make(factors, { seed }); + const count = rows.length; + results.push([seed, count]); + if (count < minRows) { + minRows = count; + bestSeed = seed; + } + if (seed % 20 === 0) { + console.log(`seed ${seed}: ${count} rows (best so far: seed=${bestSeed}, rows=${minRows})`); + } +} + +console.log(`\n=== RESULT ===`); +console.log(`Best seed: ${bestSeed}`); +console.log(`Min rows: ${minRows}`); + +// Show top 10 best seeds +results.sort((a, b) => a[1] - b[1]); +console.log(`\nTop 10 seeds:`); +for (let i = 0; i < 10; i++) { + console.log(` seed=${results[i][0]}, rows=${results[i][1]}`); +} diff --git a/typescript/tsconfig.json b/typescript/tsconfig.json index 0707532..db40473 100644 --- a/typescript/tsconfig.json +++ b/typescript/tsconfig.json @@ -1,67 +1,19 @@ { "compilerOptions": { - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es2017", "dom"], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/", /* Redirect output structure to the directory. */ - "rootDir": "./src/", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - //"rootDirs": ["src", "__tests__"], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - "baseUrl": ".", - "paths": { - "covertable/utils/pict": ["./dist/utils/pict"] - } - } + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "types": ["node", "jest"], + "lib": ["ES2020"], + "declaration": true, + "declarationDir": "./dist", + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src"], + "exclude": ["src/_bench.ts", "src/tmp", "node_modules", "dist"] } diff --git a/typescript/tslint.json b/typescript/tslint.json deleted file mode 100644 index ca0141e..0000000 --- a/typescript/tslint.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "extends": [ - "tslint:all", - "tslint-config-prettier", - "tslint-plugin-prettier" - ], - "rules": { - "prettier": true, - "semicolon": true, - - "cyclomatic-complexity": false, - "increment-decrement": false, - "newline-before-return": false, - "no-parameter-properties": false, - "no-parameter-reassignment": false, - "no-unused-variable": false, - "typedef": false, - "unnecessary-else": false, - - "comment-format": { - "options": [ - "check-space" - ] - }, - "member-access": true, - "only-arrow-functions": { - "options": [ - "allow-declarations", - "allow-named-functions" - ] - }, - - "completed-docs": false, - "no-any": false, - "no-magic-numbers": false, - "no-non-null-assertion": false, - "no-null-keyword": false, - "no-require-imports": false, - "no-unbound-method": false, - "no-unnecessary-qualifier": false, - "no-use-before-declare": false, - "no-void-expression": false, - "prefer-function-over-method": false, - "strict-comparisons": false, - "strict-type-predicates": false, - "triple-equals": { - "options": [ - "allow-undefined-check" - ] - }, - - "ban": { - "options": [ - [ - "describe", - "only" - ], - [ - "it", - "only" - ] - ] - }, - "interface-name": false, - "file-header": { - "options": [ - "Copyright \\d{4} Palantir Technologies, Inc." - ] - }, - "max-classes-per-file": false, - "member-ordering": { - "options": { - "order": "statics-first" - } - }, - "no-console": { - "options": [ - "log" - ] - }, - "no-switch-case-fall-through": true, - "strict-boolean-expressions": { - "options": [ - "allow-boolean-or-undefined" - ] - }, - "switch-default": false, - "variable-name": { - "options": [ - "ban-keywords", - "check-format", - "allow-leading-underscore", - "allow-pascal-case" - ] - }, - "linebreak-style": false - } -} \ No newline at end of file diff --git a/typescript/vite.config.ts b/typescript/vite.config.ts new file mode 100644 index 0000000..0284e98 --- /dev/null +++ b/typescript/vite.config.ts @@ -0,0 +1,20 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; +import dts from 'vite-plugin-dts'; + +export default defineConfig({ + build: { + lib: { + entry: { + index: resolve(__dirname, 'src/index.ts'), + pict: resolve(__dirname, 'src/pict/index.ts'), + }, + formats: ['es', 'cjs'], + }, + outDir: 'dist', + emptyOutDir: true, + }, + plugins: [ + dts({ rollupTypes: true }), + ], +}); diff --git a/typescript/webpack.config.js b/typescript/webpack.config.js deleted file mode 100644 index 2d4cf5f..0000000 --- a/typescript/webpack.config.js +++ /dev/null @@ -1,23 +0,0 @@ -const path = require('path'); - -module.exports = { - entry: './src/index.ts', - module: { - rules: [ - { - test: /\.ts$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - ], - }, - resolve: { - extensions: ['.ts', '.js'], - }, - output: { - filename: 'index.js', - path: path.resolve(__dirname, 'dist'), - libraryTarget: 'umd', - }, - target: 'node', -}; From 2390d3c9c245609cff170f8a6e6b631158aa9536 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 00:12:15 +0900 Subject: [PATCH 58/79] fix: workflows --- .github/workflows/python.yaml | 36 +++++++++++------- .github/workflows/typescript.yaml | 62 +++++++++++++++---------------- typescript/package.json | 7 +++- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 67b27bc..d2587b3 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -1,21 +1,28 @@ name: python on: push: + branches: + - master + - fix/* + +permissions: + id-token: write + contents: read jobs: tests: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.11"] + python-version: ["3.9", "3.13"] defaults: run: working-directory: python - + steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: setup - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: install @@ -26,7 +33,7 @@ jobs: run: | pytest --cov=covertable --cov-report=xml - name: codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./python/coverage.xml @@ -40,22 +47,23 @@ jobs: working-directory: python if: github.ref == 'refs/heads/master' name: pypi upload + environment: + name: pypi + url: https://pypi.org/p/covertable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: setup - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: install run: | python -m pip install --upgrade pip - python -m pip install -r ci_requirements.txt + python -m pip install -r ci_requirements.txt - name: build run: | python -m build --sdist --wheel --outdir dist/ . - name: upload - run: | - twine upload dist/* --non-interactive --skip-existing - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: python/dist/ diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index 536e942..eb93432 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -1,6 +1,13 @@ name: typescript on: push: + branches: + - master + - fix/* + +permissions: + id-token: write + contents: read jobs: tests: @@ -10,26 +17,17 @@ jobs: working-directory: typescript steps: - - uses: actions/checkout@v3 - - name: setup - uses: actions/setup-node@v3 - with: - node-version: "16" - - name: cache - uses: actions/cache@v3 + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 + - uses: actions/setup-node@v6 with: - path: | - node_modules - key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} + node-version: "24" - name: install - run: | - npm install + run: pnpm install - name: test - run: | - npm test -- --coverage - # npm run codecov + run: pnpm test -- --coverage - name: codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./typescript/coverage/lcov.info @@ -45,21 +43,21 @@ jobs: if: github.ref == 'refs/heads/master' name: npm upload steps: - - uses: actions/checkout@v3 - - name: setup - uses: actions/setup-node@v3 + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 + - uses: actions/setup-node@v6 with: - node-version: "16" - - name: cache - uses: actions/cache@v3 - with: - path: | - node_modules - key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} - - name: upload + node-version: "24" + registry-url: "https://registry.npmjs.org" + - run: npm install -g npm@latest + - name: remove authToken from .npmrc run: | - npm install - npm run build - echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc - npm publish || true - + NPM_RC=$(npm config get userconfig) + sed -i '/_authToken/d' "$NPM_RC" 2>/dev/null || true + - name: publish + run: | + pnpm install + pnpm build + VERSION=$(node -p "require('./package.json').version") + TAG=$( [[ "$VERSION" == *-* ]] && echo "--tag next" || echo "" ) + pnpm publish --access public --provenance $TAG --no-git-checks || true diff --git a/typescript/package.json b/typescript/package.json index 03a200b..30f6cca 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -70,6 +70,9 @@ }, "dependencies": {}, "pnpm": { - "onlyBuiltDependencies": ["esbuild"] - } + "onlyBuiltDependencies": [ + "esbuild" + ] + }, + "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319" } From 53caa09e00a4a8fd826a9abdb23cb2653d324ddf Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 00:30:07 +0900 Subject: [PATCH 59/79] 3.0.0-rc.0 --- python/setup.cfg | 2 +- typescript/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/setup.cfg b/python/setup.cfg index 65df6ed..c4bc6c3 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = covertable -version = 2.1.0 +version = 3.0.0rc0 author = righ author_email = righ.m9@gmail.com url = https://github.com/walkframe/covertable/ diff --git a/typescript/package.json b/typescript/package.json index 30f6cca..3ce31a8 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "3.0.0", + "version": "3.0.0-rc.0", "description": "A flexible pairwise tool written in TypeScript", "homepage": "https://docs.walkframe.com/covertable", "repository": { From aacece63aa1a2a4033fb9a3ecc667e22c90a17f1 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 00:37:10 +0900 Subject: [PATCH 60/79] fix: workflows --- .github/workflows/python.yaml | 11 +++++------ .github/workflows/typescript.yaml | 4 ++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index d2587b3..ec246c9 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -47,9 +47,6 @@ jobs: working-directory: python if: github.ref == 'refs/heads/master' name: pypi upload - environment: - name: pypi - url: https://pypi.org/p/covertable steps: - uses: actions/checkout@v6 - name: setup @@ -64,6 +61,8 @@ jobs: run: | python -m build --sdist --wheel --outdir dist/ . - name: upload - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: python/dist/ + run: | + twine upload dist/* --non-interactive --skip-existing + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index eb93432..2d857e5 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -19,6 +19,8 @@ jobs: steps: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v5 + with: + package_json_file: typescript/package.json - uses: actions/setup-node@v6 with: node-version: "24" @@ -45,6 +47,8 @@ jobs: steps: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v5 + with: + package_json_file: typescript/package.json - uses: actions/setup-node@v6 with: node-version: "24" From 071e25d7ffa6443c29de892df743f5b608cf28e8 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 01:36:05 +0900 Subject: [PATCH 61/79] fix: run exec jest --- .github/workflows/typescript.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index 2d857e5..956384d 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -27,7 +27,7 @@ jobs: - name: install run: pnpm install - name: test - run: pnpm test -- --coverage + run: pnpm exec jest --coverage - name: codecov uses: codecov/codecov-action@v6 with: From f984787f92ae4aa679e912a12bf27a5697e7a53f Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 01:44:15 +0900 Subject: [PATCH 62/79] fix: workflow --- .github/workflows/python.yaml | 5 ++++- python/setup.cfg | 1 + typescript/tsconfig.test.json | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 typescript/tsconfig.test.json diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index ec246c9..49270e7 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -55,11 +55,14 @@ jobs: python-version: "3.13" - name: install run: | - python -m pip install --upgrade pip + python -m pip install --upgrade pip setuptools wheel twine build python -m pip install -r ci_requirements.txt - name: build run: | python -m build --sdist --wheel --outdir dist/ . + - name: check + run: | + twine check dist/* - name: upload run: | twine upload dist/* --non-interactive --skip-existing diff --git a/python/setup.cfg b/python/setup.cfg index c4bc6c3..ab54260 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -38,3 +38,4 @@ keywords = description = A flexible pairwise tool written in Python. long_description = file: README.rst +long_description_content_type = text/x-rst diff --git a/typescript/tsconfig.test.json b/typescript/tsconfig.test.json new file mode 100644 index 0000000..a46a98e --- /dev/null +++ b/typescript/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "." + }, + "include": ["src"] +} From 227b8d8582e97937a9c2810ff15c427ce43a4f19 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 02:25:12 +0900 Subject: [PATCH 63/79] fix: add heavy.pict --- heavy.pict | 92 +++++++++++++++ .../src/__tests__/heavy-coverage.test.ts | 110 ++---------------- .../src/__tests__/heavy-covertable.test.ts | 26 ++--- 3 files changed, 111 insertions(+), 117 deletions(-) create mode 100644 heavy.pict diff --git a/heavy.pict b/heavy.pict new file mode 100644 index 0000000..191277c --- /dev/null +++ b/heavy.pict @@ -0,0 +1,92 @@ +Region: JP, US, EU, APAC +Language: ja, en, fr, de, zh +Currency: JPY, USD, EUR, GBP +Device: Desktop, MobileWeb, iOSApp, AndroidApp, Tablet +Browser: Chrome, Safari, Firefox, Edge +UserType: Guest, Member, Premium, Corporate +Payment: CreditCard, DebitCard, PayPal, ApplePay, GooglePay, BankTransfer, Invoice +Shipping: Standard, Express, SameDay, PickupPoint, StorePickup +Coupon: None, Welcome10, VIP15, FREESHIP, BULK20 +CartSize: Single, Small, Medium, Large, Bulk +ItemCategory: Electronics, Fashion, Grocery, Furniture, Digital, Subscription +InventoryStatus: InStock, LowStock, BackOrder, PreOrder +FraudCheck: Pass, Review, Reject +TaxMode: Inclusive, Exclusive +AddressType: Home, Office, Hotel, POBox +DeliveryWindow: None, Morning, Afternoon, Evening, Night +GiftOption: None, Wrap, Message, WrapAndMessage +LoyaltyUse: None, Partial, Full +SupportPlan: None, Basic, Plus +AccountAge: New, Recent, Established, Old +EmailVerified: Yes, No +PhoneVerified: Yes, No + +# ----- constraints ----- + +IF [Region] = "JP" THEN [Currency] IN {"JPY"}; +IF [Region] = "US" THEN [Currency] IN {"USD"}; +IF [Region] = "EU" THEN [Currency] IN {"EUR", "GBP"}; +IF [Region] = "APAC" THEN [Currency] IN {"JPY", "USD"}; + +IF [Language] = "ja" THEN [Region] IN {"JP", "APAC"}; +IF [Language] = "fr" THEN [Region] = "EU"; +IF [Language] = "de" THEN [Region] = "EU"; + +IF [Device] = "iOSApp" THEN [Browser] = "Safari"; +IF [Device] = "AndroidApp" THEN [Browser] = "Chrome"; +IF [Device] = "Desktop" THEN [Browser] IN {"Chrome", "Safari", "Firefox", "Edge"}; +IF [Device] = "MobileWeb" THEN [Browser] IN {"Chrome", "Safari", "Firefox"}; +IF [Device] = "Tablet" THEN [Browser] IN {"Chrome", "Safari", "Edge"}; + +IF [Payment] = "ApplePay" THEN [Device] IN {"iOSApp", "MobileWeb", "Tablet"}; +IF [Payment] = "GooglePay" THEN [Device] IN {"AndroidApp", "MobileWeb"}; +IF [Payment] = "PayPal" THEN [UserType] IN {"Guest", "Member", "Premium"}; +IF [Payment] = "Invoice" THEN [UserType] IN {"Corporate"}; +IF [Payment] = "BankTransfer" THEN [UserType] IN {"Member", "Premium", "Corporate"}; + +IF [Shipping] = "SameDay" THEN [Region] IN {"JP", "US"}; +IF [Shipping] = "StorePickup" THEN [Region] = "JP"; +IF [Shipping] = "PickupPoint" THEN [Region] IN {"EU", "US"}; +IF [AddressType] = "POBox" THEN NOT ([Shipping] IN {"SameDay", "StorePickup"}); + +IF [ItemCategory] = "Digital" THEN [Shipping] = "Standard"; +IF [ItemCategory] = "Digital" THEN [GiftOption] = "None"; +IF [ItemCategory] = "Digital" THEN [AddressType] = "Home"; +IF [ItemCategory] = "Subscription" THEN [Shipping] = "Standard"; +IF [ItemCategory] = "Furniture" THEN NOT ([Shipping] IN {"SameDay", "StorePickup", "PickupPoint"}); +IF [ItemCategory] = "Grocery" THEN NOT ([Shipping] IN {"PickupPoint", "StorePickup"}); + +IF [InventoryStatus] = "BackOrder" THEN NOT ([Shipping] IN {"SameDay"}); +IF [InventoryStatus] = "PreOrder" THEN [Shipping] IN {"Standard", "Express"}; +IF [InventoryStatus] = "PreOrder" THEN NOT ([Coupon] IN {"FREESHIP"}); + +IF [Coupon] = "VIP15" THEN [UserType] = "Premium"; +IF [Coupon] = "Welcome10" THEN [AccountAge] = "New"; +IF [Coupon] = "BULK20" THEN [CartSize] = "Bulk"; +IF [Coupon] = "FREESHIP" THEN NOT ([Shipping] IN {"StorePickup"}); + +IF [CartSize] = "Bulk" THEN NOT ([UserType] IN {"Guest"}); +IF [CartSize] = "Bulk" THEN NOT ([Payment] IN {"ApplePay", "GooglePay"}); +IF [CartSize] = "Single" THEN NOT ([Coupon] IN {"BULK20"}); + +IF [FraudCheck] = "Reject" THEN NOT ([Payment] IN {"BankTransfer", "Invoice"}); +IF [FraudCheck] = "Reject" THEN [Coupon] = "None"; +IF [FraudCheck] = "Reject" THEN [LoyaltyUse] = "None"; + +IF NOT ([LoyaltyUse] IN {"None"}) THEN NOT ([UserType] IN {"Guest"}); +IF [LoyaltyUse] = "Full" THEN [UserType] IN {"Premium"}; +IF [LoyaltyUse] = "Full" THEN [Coupon] = "None"; + +IF [SupportPlan] = "Plus" THEN [UserType] IN {"Premium", "Corporate"}; +IF [SupportPlan] = "Basic" THEN NOT ([UserType] IN {"Guest"}); + +IF [UserType] = "Guest" THEN [EmailVerified] = "No"; +IF [Payment] IN {"BankTransfer", "Invoice"} THEN [EmailVerified] = "Yes"; +IF [Shipping] IN {"Express", "SameDay"} THEN [PhoneVerified] = "Yes"; + +IF [GiftOption] = "WrapAndMessage" THEN NOT ([ItemCategory] IN {"Digital", "Subscription", "Furniture"}); +IF [GiftOption] = "Wrap" THEN NOT ([ItemCategory] IN {"Digital", "Subscription"}); +IF [GiftOption] = "Message" THEN NOT ([ItemCategory] IN {"Digital"}); + +IF [Region] IN {"JP", "EU"} THEN [TaxMode] = "Inclusive"; +IF [Region] = "US" THEN [TaxMode] = "Exclusive"; diff --git a/typescript/src/__tests__/heavy-coverage.test.ts b/typescript/src/__tests__/heavy-coverage.test.ts index 834f54f..88b8c7f 100644 --- a/typescript/src/__tests__/heavy-coverage.test.ts +++ b/typescript/src/__tests__/heavy-coverage.test.ts @@ -2,90 +2,16 @@ import { PictModel } from '../pict'; import * as fs from 'fs'; import * as path from 'path'; +const HEAVY_PICT = path.resolve(__dirname, '../../../heavy.pict'); + describe('heavy.pict coverage check', () => { - it('checks pairwise coverage of PICT output', () => { - const modelText = fs.readFileSync( - path.resolve(__dirname, '../../../heavy.pict'), - 'utf-8', - ); + it('checks pairwise coverage of generated output', () => { + const modelText = fs.readFileSync(HEAVY_PICT, 'utf-8'); const model = new PictModel(modelText); const factors = model.parameters; const keys = Object.keys(factors); - // The 65 rows from PICT output - const rawRows = `EU fr EUR Tablet Chrome Guest PayPal PickupPoint None Single Fashion InStock Reject Exclusive Home Evening Message None None New No No -US en USD Desktop Chrome Premium DebitCard Express BULK20 Bulk Grocery InStock Pass Exclusive Hotel Morning WrapAndMessage Partial Plus Established Yes Yes -US zh USD iOSApp Safari Guest CreditCard Standard FREESHIP Large Electronics BackOrder Review Exclusive POBox Night Wrap None None Recent No Yes -JP en JPY MobileWeb Chrome Member BankTransfer StorePickup Welcome10 Small Furniture BackOrder Review Inclusive Home None None Partial Basic New Yes No -US zh USD AndroidApp Chrome Member BankTransfer Standard None Medium Subscription LowStock Pass Exclusive Office Afternoon Message None Basic Old Yes No -JP ja JPY iOSApp Safari Corporate DebitCard Standard FREESHIP Single Subscription LowStock Pass Inclusive Office Evening WrapAndMessage Partial None Established No Yes -APAC en JPY AndroidApp Chrome Corporate Invoice Standard Welcome10 Single Grocery PreOrder Review Inclusive POBox Afternoon Wrap None Basic New No Yes -EU fr EUR iOSApp Safari Premium ApplePay Express VIP15 Large Grocery LowStock Review Inclusive Office None None Partial Plus Recent Yes Yes -JP ja JPY MobileWeb Chrome Premium CreditCard Standard None Medium Fashion PreOrder Review Inclusive Hotel Night Message Full Plus Old No No -APAC zh JPY AndroidApp Chrome Premium GooglePay Express VIP15 Small Furniture InStock Pass Exclusive Hotel Evening None None None Old No Yes -JP ja JPY Desktop Chrome Corporate Invoice SameDay None Large Electronics InStock Reject Inclusive Home Afternoon WrapAndMessage None Basic Recent Yes No -EU zh EUR MobileWeb Chrome Corporate Invoice Standard BULK20 Bulk Digital BackOrder Pass Exclusive Home Night None None None Established Yes No -JP ja JPY AndroidApp Chrome Premium GooglePay StorePickup VIP15 Bulk Electronics BackOrder Pass Inclusive POBox Morning Message Partial Plus New No No -EU de EUR Tablet Chrome Member CreditCard Standard BULK20 Bulk Subscription LowStock Review Inclusive POBox None Wrap Partial Basic Old Yes Yes -JP zh JPY Desktop Chrome Guest CreditCard SameDay Welcome10 Small Fashion LowStock Pass Inclusive Office Morning Wrap None None New No Yes -EU de EUR iOSApp Safari Member ApplePay PickupPoint FREESHIP Medium Fashion InStock Review Exclusive Hotel Morning WrapAndMessage Partial Basic New Yes No -EU en EUR AndroidApp Chrome Premium GooglePay PickupPoint None Medium Furniture LowStock Reject Inclusive Office Night Wrap None Plus Recent Yes Yes -EU fr EUR Desktop Chrome Guest PayPal Standard Welcome10 Medium Subscription BackOrder Pass Exclusive Hotel Night WrapAndMessage None None New No Yes -EU de EUR MobileWeb Chrome Guest PayPal Standard None Small Electronics PreOrder Reject Exclusive Office None None None None Established No Yes -EU de EUR Tablet Chrome Premium DebitCard Standard Welcome10 Large Digital PreOrder Pass Inclusive Home Evening None Partial Plus New Yes Yes -APAC en JPY iOSApp Safari Premium DebitCard Standard None Bulk Digital LowStock Review Exclusive Home Afternoon None Full None Recent Yes No -JP en JPY MobileWeb Chrome Guest PayPal SameDay FREESHIP Large Grocery LowStock Review Inclusive Home Morning Message None None Old No No -JP zh JPY iOSApp Safari Premium ApplePay StorePickup None Single Furniture BackOrder Review Inclusive POBox Evening Wrap Full Basic Established Yes Yes -EU fr EUR MobileWeb Chrome Member BankTransfer PickupPoint Welcome10 Bulk Electronics InStock Pass Inclusive POBox Evening Wrap None None New Yes No -JP en JPY Tablet Chrome Premium CreditCard StorePickup VIP15 Medium Grocery LowStock Pass Inclusive Hotel Evening WrapAndMessage None Basic Recent Yes Yes -US zh USD iOSApp Safari Corporate ApplePay Standard None Small Digital PreOrder Reject Exclusive Home None None None Basic Old No Yes -APAC zh JPY Tablet Chrome Corporate Invoice Standard None Small Subscription BackOrder Reject Inclusive Office Morning Message None None Recent Yes Yes -EU fr EUR Desktop Chrome Member BankTransfer Standard FREESHIP Single Digital InStock Review Inclusive Home Morning None None Basic Established Yes Yes -EU fr EUR AndroidApp Chrome Premium GooglePay PickupPoint None Small Fashion InStock Pass Inclusive Office None WrapAndMessage Full Plus Established Yes Yes -APAC zh JPY iOSApp Safari Premium ApplePay Express VIP15 Medium Electronics LowStock Pass Inclusive Home Night Message Partial Basic Established Yes Yes -EU fr EUR Desktop Chrome Corporate CreditCard PickupPoint BULK20 Bulk Furniture BackOrder Pass Inclusive Office Afternoon None Partial None Old No Yes -EU de EUR MobileWeb Chrome Premium DebitCard Express VIP15 Single Fashion BackOrder Pass Inclusive Hotel Afternoon Wrap None Plus Recent Yes Yes -APAC zh JPY Tablet Chrome Member BankTransfer Standard None Large Furniture PreOrder Pass Inclusive Hotel Night WrapAndMessage Partial None Recent Yes Yes -JP ja JPY iOSApp Safari Guest PayPal SameDay Welcome10 Medium Fashion InStock Pass Inclusive Hotel None None None None New No Yes -APAC en JPY AndroidApp Chrome Guest CreditCard Standard FREESHIP Single Digital InStock Pass Inclusive Home None None None None Old No Yes -EU de EUR AndroidApp Chrome Premium GooglePay Standard None Large Subscription PreOrder Review Inclusive Home Morning Wrap Full Plus New Yes Yes -EU de EUR Desktop Chrome Member DebitCard Express None Medium Furniture InStock Reject Inclusive POBox None Message None Basic New No Yes -US zh USD MobileWeb Chrome Premium DebitCard Express None Single Electronics InStock Pass Exclusive Hotel Night WrapAndMessage Full Plus Old Yes Yes -APAC en JPY iOSApp Safari Premium ApplePay Standard FREESHIP Small Subscription InStock Pass Inclusive POBox Afternoon None None Plus Established Yes Yes -JP ja JPY Tablet Chrome Member BankTransfer SameDay BULK20 Bulk Electronics InStock Pass Inclusive Home Evening Message Partial None Established Yes Yes -JP en JPY Desktop Chrome Corporate Invoice StorePickup None Large Fashion InStock Reject Inclusive Hotel Evening None None None Old Yes Yes -US zh USD Tablet Chrome Guest PayPal Express Welcome10 Single Fashion InStock Pass Exclusive POBox Afternoon Wrap None None New No Yes -JP ja JPY AndroidApp Chrome Premium DebitCard SameDay None Small Grocery InStock Pass Inclusive Home Night Wrap Full Plus New Yes Yes -EU de EUR AndroidApp Chrome Member GooglePay Standard None Bulk Grocery BackOrder Reject Inclusive POBox Afternoon WrapAndMessage None Basic New Yes Yes -JP ja JPY Tablet Chrome Corporate Invoice Express FREESHIP Medium Furniture LowStock Pass Inclusive Home None None Partial None New Yes Yes -APAC en JPY iOSApp Safari Member BankTransfer Standard BULK20 Bulk Fashion PreOrder Pass Inclusive Home None None None None Recent Yes Yes -US en USD Desktop Chrome Corporate Invoice Standard Welcome10 Single Furniture PreOrder Pass Exclusive Home Evening Message None None New Yes Yes -EU de EUR Desktop Chrome Member BankTransfer Express FREESHIP Bulk Grocery InStock Pass Inclusive Home Night None None None New Yes Yes -APAC en JPY Desktop Chrome Guest PayPal Standard None Single Furniture InStock Pass Inclusive Home Morning None None None Recent No Yes -JP en JPY Desktop Chrome Guest DebitCard StorePickup None Large Electronics InStock Pass Inclusive Office Night None None None Established No Yes -JP ja JPY iOSApp Safari Premium ApplePay Standard VIP15 Medium Digital PreOrder Pass Inclusive Home None None None None New Yes Yes -JP zh JPY AndroidApp Chrome Corporate GooglePay StorePickup BULK20 Bulk Grocery InStock Pass Inclusive Home Afternoon None None None New Yes Yes -JP ja JPY AndroidApp Chrome Guest GooglePay SameDay FREESHIP Single Electronics InStock Pass Inclusive Home None None None None New No Yes -JP ja JPY AndroidApp Chrome Guest PayPal StorePickup None Single Electronics InStock Pass Inclusive Home None None None None New No Yes -EU fr EUR iOSApp Safari Corporate Invoice Standard None Single Electronics PreOrder Pass Inclusive Home None None None None New Yes Yes -APAC en JPY MobileWeb Chrome Guest PayPal Standard None Single Digital InStock Pass Inclusive Home None None None None New No Yes -EU zh EUR Desktop Chrome Premium DebitCard PickupPoint VIP15 Large Electronics InStock Pass Inclusive Home None None None None New Yes Yes -US en USD AndroidApp Chrome Premium GooglePay Standard VIP15 Single Subscription InStock Pass Exclusive Home None None None None New Yes Yes -EU de EUR Desktop Chrome Corporate Invoice PickupPoint None Single Electronics InStock Pass Inclusive Home None None None None New Yes Yes -JP ja JPY MobileWeb Chrome Guest CreditCard Standard None Single Subscription InStock Reject Inclusive Home None None None None Established No Yes -JP ja JPY AndroidApp Chrome Guest GooglePay Standard Welcome10 Single Digital InStock Pass Inclusive Home None None None None New No Yes -JP ja JPY iOSApp Safari Premium ApplePay SameDay VIP15 Single Electronics InStock Pass Inclusive Home None None None None New Yes Yes -EU fr EUR Desktop Chrome Premium DebitCard Standard None Single Electronics InStock Pass Inclusive Home None None Full None New Yes Yes -JP ja JPY iOSApp Safari Guest ApplePay Standard Welcome10 Single Electronics InStock Pass Inclusive Home None None None None New No Yes -JP ja JPY Tablet Chrome Premium CreditCard Express None Single Electronics InStock Pass Inclusive Home None None Full None New Yes Yes`; - - const rows = rawRows.split('\n').map(line => { - const vals = line.split('\t'); - const obj: Record = {}; - keys.forEach((k, i) => { obj[k] = vals[i]; }); - return obj; - }); - + const rows = model.make(); console.log(`Rows: ${rows.length}`); // Check constraint violations @@ -98,8 +24,6 @@ JP ja JPY Tablet Chrome Premium CreditCard Express None Single Electronics InSto console.log(`Constraint violations: ${violations}`); // Compute pairwise coverage - // Total possible pairs = sum over all factor pairs of |fi| * |fj| - // Covered = pairs that appear in at least one row const covered = new Set(); let totalPossible = 0; @@ -107,29 +31,19 @@ JP ja JPY Tablet Chrome Premium CreditCard Express None Single Electronics InSto for (let j = i + 1; j < keys.length; j++) { const ki = keys[i]; const kj = keys[j]; - const vi = factors[ki]; - const vj = factors[kj]; - totalPossible += vi.length * vj.length; - + totalPossible += factors[ki].length * factors[kj].length; for (const row of rows) { - covered.add(`${ki}=${row[ki]}|${kj}=${row[kj]}`); + covered.add(`${ki}=${(row as any)[ki]}|${kj}=${(row as any)[kj]}`); } } } - // Count how many of the "possible" pairs actually appear - // But some pairs are impossible due to constraints, so we also - // count "feasible" pairs let coveredCount = 0; - let infeasibleCount = 0; for (let i = 0; i < keys.length; i++) { for (let j = i + 1; j < keys.length; j++) { - const ki = keys[i]; - const kj = keys[j]; - for (const vi of factors[ki]) { - for (const vj of factors[kj]) { - const pairKey = `${ki}=${vi}|${kj}=${vj}`; - if (covered.has(pairKey)) { + for (const vi of factors[keys[i]]) { + for (const vj of factors[keys[j]]) { + if (covered.has(`${keys[i]}=${vi}|${keys[j]}=${vj}`)) { coveredCount++; } } @@ -143,7 +57,7 @@ JP ja JPY Tablet Chrome Premium CreditCard Express None Single Electronics InSto console.log(`Raw coverage: ${(rawCoverage * 100).toFixed(1)}%`); console.log(`Uncovered: ${totalPossible - coveredCount}`); - // This is PICT's output, so coverage should be high + expect(violations).toBe(0); expect(rawCoverage).toBeGreaterThan(0.5); - }); + }, 120000); }); diff --git a/typescript/src/__tests__/heavy-covertable.test.ts b/typescript/src/__tests__/heavy-covertable.test.ts index fba3248..5c158ba 100644 --- a/typescript/src/__tests__/heavy-covertable.test.ts +++ b/typescript/src/__tests__/heavy-covertable.test.ts @@ -2,12 +2,11 @@ import { PictModel } from '../pict'; import * as fs from 'fs'; import * as path from 'path'; +const HEAVY_PICT = path.resolve(__dirname, '../../../heavy.pict'); + describe('heavy.pict covertable generation', () => { it('generates with forward checking and measures coverage', () => { - const modelText = fs.readFileSync( - path.resolve(__dirname, '../../../heavy.pict'), - 'utf-8', - ); + const modelText = fs.readFileSync(HEAVY_PICT, 'utf-8'); const model = new PictModel(modelText); const factors = model.parameters; const keys = Object.keys(factors); @@ -27,12 +26,6 @@ describe('heavy.pict covertable generation', () => { rowCount: stats.rowCount, uncoveredPairs: stats.uncoveredPairs.length, }, null, 2)); - // Show top completions (factors most filled by close) - const compEntries = Object.entries(stats.completions) - .map(([k, v]) => [k, Object.values(v).reduce((a, b) => a + b, 0)] as [string, number]) - .sort((a, b) => b[1] - a[1]); - console.log(`Top completions:`, compEntries.slice(0, 5)); - console.log(`All completions:`, JSON.stringify(stats.completions, null, 2)); // Check constraint violations let violations = 0; @@ -41,7 +34,6 @@ describe('heavy.pict covertable generation', () => { violations++; } } - console.log(`Constraint violations: ${violations}`); // Compute pairwise coverage const covered = new Set(); @@ -52,7 +44,6 @@ describe('heavy.pict covertable generation', () => { const ki = keys[i]; const kj = keys[j]; totalPossible += factors[ki].length * factors[kj].length; - for (const row of rows) { covered.add(`${ki}=${(row as any)[ki]}|${kj}=${(row as any)[kj]}`); } @@ -62,11 +53,9 @@ describe('heavy.pict covertable generation', () => { let coveredCount = 0; for (let i = 0; i < keys.length; i++) { for (let j = i + 1; j < keys.length; j++) { - const ki = keys[i]; - const kj = keys[j]; - for (const vi of factors[ki]) { - for (const vj of factors[kj]) { - if (covered.has(`${ki}=${vi}|${kj}=${vj}`)) { + for (const vi of factors[keys[i]]) { + for (const vj of factors[keys[j]]) { + if (covered.has(`${keys[i]}=${vi}|${keys[j]}=${vj}`)) { coveredCount++; } } @@ -75,11 +64,10 @@ describe('heavy.pict covertable generation', () => { } const rawCoverage = coveredCount / totalPossible; - console.log(`Total possible pairs: ${totalPossible}`); - console.log(`Covered pairs: ${coveredCount}`); console.log(`Raw coverage: ${(rawCoverage * 100).toFixed(1)}%`); expect(violations).toBe(0); + expect(stats.progress).toBe(1); expect(rawCoverage).toBeGreaterThan(0.5); }, 120000); }); From 4849de75c2ad8b212e6eeefff77858e99eb4d856 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 21:15:35 +0900 Subject: [PATCH 64/79] docs --- .github/workflows/docs.yaml | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/docs.yaml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..88993fd --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,39 @@ +name: Deploy Docs to Cloudflare Pages + +on: + push: + branches: + - master + - feature/docs + +jobs: + deploy: + runs-on: ubuntu-latest + defaults: + run: + working-directory: docs + + steps: + - uses: actions/checkout@v6 + + - uses: pnpm/action-setup@v5 + with: + package_json_file: docs/package.json + + - uses: actions/setup-node@v6 + with: + node-version: "24" + + - name: Install dependencies + run: pnpm install + + - name: Build Docusaurus + run: pnpm build + + - name: Deploy to Cloudflare Pages + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy docs/build --project-name=covertable --branch=${{ github.ref_name }} + packageManager: pnpm From 55ab64ff65ccfc1bea2dbf1cbe1f66cc8d3480a2 Mon Sep 17 00:00:00 2001 From: righ Date: Fri, 17 Apr 2026 21:41:08 +0900 Subject: [PATCH 65/79] codecov --- .github/workflows/python.yaml | 1 + .github/workflows/typescript.yaml | 1 + codecov.yml | 32 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 codecov.yml diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 49270e7..ab96e73 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -37,6 +37,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} file: ./python/coverage.xml + flags: python verbose: true release: diff --git a/.github/workflows/typescript.yaml b/.github/workflows/typescript.yaml index 956384d..924de07 100644 --- a/.github/workflows/typescript.yaml +++ b/.github/workflows/typescript.yaml @@ -33,6 +33,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} file: ./typescript/coverage/lcov.info + flags: typescript verbose: true release: diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..8c8a868 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,32 @@ +coverage: + status: + project: + typescript: + target: auto + threshold: 5% + flags: + - typescript + python: + target: auto + threshold: 5% + flags: + - python + patch: + default: + target: 70% + +flags: + typescript: + paths: + - typescript/src/ + carryforward: true + python: + paths: + - python/covertable/ + carryforward: true + +ignore: + - "typescript/src/__tests__/**" + - "typescript/src/_bench.ts" + - "typescript/tmp/**" + - "docs/**" From 676e27f178bd465bb50f33cfa47fefa67bdc37be Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 00:28:24 +0900 Subject: [PATCH 66/79] update docs --- README.md | 17 +- .../{ => advanced}/constraint-logic.mdx | 0 docs/contents/history/v3.mdx | 23 +- docs/sidebars.ts | 2 +- python/.tool-versions | 1 + python/README.rst | 202 ++++++++++-------- python/covertable/evaluate.py | 5 +- python/covertable/exceptions.py | 6 - python/covertable/main.py | 175 ++++----------- python/covertable/pict/model.py | 8 - python/test_pict.py | 6 +- python/tests.py | 65 +++--- typescript/README.md | 2 +- typescript/package.json | 2 +- 14 files changed, 226 insertions(+), 288 deletions(-) rename docs/contents/{ => advanced}/constraint-logic.mdx (100%) create mode 100644 python/.tool-versions diff --git a/README.md b/README.md index 8151999..560f465 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,17 @@ ![covertable logo](./covertable.png) -Time is limited. +CoverTable is a **pairwise (N-wise) test case generation library** based on the AETG algorithm, available for both TypeScript and Python. -Creating a test case that satisfies all possible factors is often unrealistic and, more importantly, tedious. +It is **PICT-compatible**: you can use PICT-format model files — including parameters, sub-models, constraints, invalid values, weights, and aliases — directly with CoverTable. -Save time with CoverTable, a flexible pairwise tool that generates combinations covering two (or more) factors. +Try the online demo: **[Compatible PICT](https://covertable.walkframe.com/tools/pict)** — an interactive tool that parses PICT models and generates covering arrays in your browser. ## Algorithm CoverTable uses a **one-test-at-a-time greedy algorithm** to generate covering arrays. -1. Assigns a unique prime number ID to each factor value, then enumerates all n-way combinations to be covered. +1. Assigns a unique serial ID to each factor value, then enumerates all n-way combinations to be covered. 2. For each test row, the **criterion** selects the most efficient uncovered combination to include next by evaluating how many other uncovered combinations it would simultaneously satisfy. 3. Repeats until all combinations are covered. @@ -33,12 +33,12 @@ CoverTable is available in two implementations, with TypeScript as the primary f [![NPM Version](https://badge.fury.io/js/covertable.svg)](https://badge.fury.io/js/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/typescript.yaml) -Works in both **Node.js** and **browsers** (UMD build). +Works in both **Node.js** and **browsers** (ESM/CJS dual build). - [README](https://github.com/walkframe/covertable/blob/master/typescript/README.md) - [History](https://github.com/walkframe/covertable/blob/master/typescript/history.md) -### Python (Legacy Support) +### Python [![PyPI Version](https://badge.fury.io/py/covertable.svg)](https://badge.fury.io/py/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/python.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/python.yaml) @@ -46,7 +46,10 @@ Works in both **Node.js** and **browsers** (UMD build). - [History](https://github.com/walkframe/covertable/blob/master/python/history.md) -For more details, please refer to the links above. +## Documentation + +- **Latest (v3)**: https://covertable.walkframe.com +- **v2 and earlier**: https://docs.walkframe.com/covertable/advanced ## Performance diff --git a/docs/contents/constraint-logic.mdx b/docs/contents/advanced/constraint-logic.mdx similarity index 100% rename from docs/contents/constraint-logic.mdx rename to docs/contents/advanced/constraint-logic.mdx diff --git a/docs/contents/history/v3.mdx b/docs/contents/history/v3.mdx index 47d223a..91d6bb1 100644 --- a/docs/contents/history/v3.mdx +++ b/docs/contents/history/v3.mdx @@ -14,7 +14,28 @@ Major release with breaking changes, declarative constraints, and full PICT-form - The default export has been removed. Use `import { make } from "covertable"` instead of `import make from "covertable"`. - `PictConstraintsLexer` is no longer exported. Use the new [`PictModel`](/advanced/pict) class instead. - `PictModel.errors` (`string[]`) has been replaced with `PictModel.issues` (`PictModelIssue[]`). Each issue carries `severity`, `source`, `index`, `line`, and `message`. -- `preFilter` and `postFilter` have been replaced by declarative `constraints`. See [Constraint Logic](/constraint-logic) and [Migration Guide](./migration). +- `preFilter` and `postFilter` have been replaced by declarative `constraints`. See [Constraint Logic](/advanced/constraint-logic) and [Migration Guide](./migration). + +## Why replace `preFilter` with `constraints`? + +`preFilter` was a simple, flexible callback — you could write any JavaScript/Python function to accept or reject a row. So why give up that freedom? + +The problem is that `preFilter` is a **black box**. The engine can only call it and observe `true` or `false`. It cannot reason about *why* a row was rejected, *which fields* the filter depends on, or *whether a partial row could ever satisfy it*. This leads to: + +- **Blind trial and error** — The engine must try every candidate and discard failures. With many constraints and factors, this becomes extremely slow. +- **No early pruning** — Even when a pair like `(Region=US, Currency=EUR)` is obviously impossible, the engine cannot detect this until the row is fully filled. +- **No constraint propagation** — Chain constraints (e.g. `Language=ja → Region∈{JP,APAC}` → `Currency∈{JPY,USD}`) cannot be followed ahead of time, leading to dead-end rows that waste computation. + +Declarative `constraints` solve this by giving the engine **visibility into the constraint structure**: + +- **Three-valued logic** — When a referenced field is not yet set, the result is `null` (unknown) rather than `false`. The engine can defer judgment instead of rejecting prematurely. +- **`extractKeys()`** — Each constraint declares its dependencies, so the engine only re-evaluates constraints when relevant fields change. +- **Forward checking** — Before committing a pair, the engine prunes the domains of unfilled factors. If any domain becomes empty, the pair is rejected without filling the entire row. +- **Initial pruning** — Infeasible pairs are detected and removed before generation even starts, reducing the search space. + +The result: a 22-factor, 53-constraint model (`heavy.pict`) that would churn for minutes with `preFilter` now completes in seconds with 100% pairwise coverage. + +`preFilter` / `postFilter` still work for backward compatibility, but `constraints` is the recommended approach for v3. ## New Features diff --git a/docs/sidebars.ts b/docs/sidebars.ts index d8c116c..893cce2 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -11,7 +11,7 @@ const sidebars: SidebarsConfig = { { type: 'category', label: 'Advanced', - items: ['advanced/index', 'advanced/options', 'advanced/pict', 'constraint-logic'], + items: ['advanced/index', 'advanced/options', 'advanced/pict', 'advanced/constraint-logic'], }, { type: 'category', diff --git a/python/.tool-versions b/python/.tool-versions new file mode 100644 index 0000000..ecefe3a --- /dev/null +++ b/python/.tool-versions @@ -0,0 +1 @@ +python 3.12.8 diff --git a/python/README.rst b/python/README.rst index 07e5389..54524ff 100644 --- a/python/README.rst +++ b/python/README.rst @@ -7,18 +7,12 @@ .. image:: https://codecov.io/gh/walkframe/covertable/branch/master/graph/badge.svg :target: https://codecov.io/gh/walkframe/covertable -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/python/black - .. image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg :target: https://opensource.org/licenses/Apache-2.0 Requirements ============ -- Python: 3.3 or later. - - - Tested with 3.7, 3.11 - +- Python: 3.9 or later. Installation ============ @@ -29,126 +23,166 @@ Installation Usage ===== -Just import ``covertable`` and call ``make`` function. +Import ``covertable`` and call the ``make`` function. .. code-block:: python3 >>> from covertable import make, sorters, criteria - + >>> machine_list = ['iphone', 'pixel'] >>> os_list = ['ios', 'android'] >>> browser_list = ['FireFox', 'Chrome', 'Safari'] + >>> # list input and output >>> make( - ... [machine_list, os_list, browser_list], # list factors - ... length=2, # default: 2 + ... [machine_list, os_list, browser_list], + ... strength=2, # default: 2 ... sorter=sorters.random, # default: sorters.hash ... criterion=criteria.simple, # default: criteria.greedy - ... seed=100, # default: '' - ... pre_filter=lambda row: not(row[1] == 'android' and row[0] != 'pixel') and not(row[1] == 'ios' and row[0] != 'iphone'), # default: None + ... salt='my_seed', # default: '' + ... constraints=[ + ... {'operator': 'custom', 'keys': [0, 1], 'evaluate': + ... lambda row: not(row[1] == 'android' and row[0] != 'pixel') and not(row[1] == 'ios' and row[0] != 'iphone')}, + ... ], ... ) - [ - ['pixel', 'android', 'Safari'], - ['iphone', 'ios', 'Chrome'], - ['iphone', 'ios', 'Safari'], - ['pixel', 'android', 'Chrome'], - ['pixel', 'android', 'FireFox'], - ['iphone', 'ios', 'FireFox'] - ] - + [['iphone', 'ios', 'FireFox'], ['pixel', 'android', 'Chrome'], ...] >>> # dict input and output >>> make( - ... {'machine': machine_list, 'os': os_list, 'browser': browser_list}, # dict factors - ... length=2, # default: 2 - ... tolerance=3, # default: 0 - ... post_filter=lambda row: not(row['os'] == 'android' and row['machine'] != 'pixel') and not(row['os'] == 'ios' and row['machine'] != 'iphone'), # default: None + ... {'machine': machine_list, 'os': os_list, 'browser': browser_list}, + ... strength=2, + ... tolerance=3, + ... constraints=[ + ... {'operator': 'or', 'conditions': [ + ... {'operator': 'eq', 'field': 'os', 'value': 'android'}, + ... {'operator': 'ne', 'field': 'machine', 'value': 'pixel'}, + ... ]}, + ... ], ... ) - [ - {'machine': 'pixel', 'browser': 'Chrome', 'os': 'android'}, - {'machine': 'pixel', 'browser': 'FireFox', 'os': 'android'}, - {'machine': 'iphone', 'os': 'ios', 'browser': 'Chrome'}, - {'os': 'ios', 'browser': 'FireFox', 'machine': 'iphone'} - ] + [{'machine': 'pixel', 'browser': 'Chrome', 'os': 'android'}, ...] -Options ---------------- +Declarative Constraints +======================= -``covertable.make`` function has options as keyword argument. +The ``constraints`` parameter accepts a list of condition dicts evaluated under +three-valued logic with forward checking and constraint propagation. -All options are omittable. +.. code-block:: python3 -length -~~~~~~~~~~~~~~~~ -Number of factors to be covered. (default: 2) + >>> from covertable import make + + >>> rows = make( + ... { + ... 'OS': ['Win', 'Mac', 'Linux'], + ... 'Browser': ['Chrome', 'Firefox', 'Safari'], + ... }, + ... constraints=[ + ... # Safari only on Mac + ... {'operator': 'or', 'conditions': [ + ... {'operator': 'ne', 'field': 'Browser', 'value': 'Safari'}, + ... {'operator': 'eq', 'field': 'OS', 'value': 'Mac'}, + ... ]}, + ... ], + ... ) -Obviously the more it increases, the more number of combinations increases. +Supported condition operators: -sorter -~~~~~~~~~~~~~~~~ -Combinations depend on the order of spreading all over the rows. +- **Comparison**: ``eq``, ``ne``, ``gt``, ``lt``, ``gte``, ``lte``, ``in`` +- **Logical**: ``and``, ``or``, ``not`` +- **Custom**: ``custom`` (escape hatch with ``keys`` and ``evaluate`` callable) -You can choice a sorter from the following: +Field-to-field comparison is supported via the ``target`` key: -:sorters.random: +.. code-block:: python3 - This makes different combinations everytime. (fastest) + {'operator': 'ne', 'field': 'A', 'target': 'B'} -:sorters.hash: +Stats +----- - This makes combinations depending on hash of the pair and seed. (default) +When using ``constraints``, the ``Controller`` exposes a ``stats`` property: - - It receives `seed` and `useCache` options. +.. code-block:: python3 - - `seed` option decides the order of storing from unstored pairs, therefore it outputs the same result every time when number of factors and seed are the same. - - `useCache` option decide if using cache of hash or not. (default: `true`) - - - It is around 10% faster than setting `useCache` **off**. + >>> from covertable.main import Controller + >>> ctrl = Controller( + ... {'A': [1, 2, 3], 'B': ['x', 'y', 'z']}, + ... constraints=[{'operator': 'ne', 'field': 'A', 'value': 1}], + ... ) + >>> rows = list(ctrl.make_async()) + >>> ctrl.stats + {'total_pairs': 9, 'pruned_pairs': 3, 'covered_pairs': 6, ...} -criterion -~~~~~~~~~~~~~~~~~ -:criteria.simple: +PICT Model +========== + +Parse PICT-format model files directly: + +.. code-block:: python3 + + >>> from covertable.pict import PictModel + + >>> model = PictModel(""" + ... OS: Win, Mac, Linux + ... Browser: Chrome, Firefox, ~Safari + ... IF [Browser] = "Safari" THEN [OS] = "Mac"; + ... """) + >>> rows = model.make() + >>> model.stats + + +Options +======= + +All options are keyword arguments to ``covertable.make``. + +strength +-------- +Number of factors to be covered. (default: 2) - This extracts any pairs that can be stored into the processing row. +The higher the value, the more combinations are generated. -:criteria.greedy: +sorter +------ +Controls the order of pair processing. - This attempts to make most efficient combinations. (default) - - - These combinations are not always shorter than `simple` criterion. - - It receives `tolerance `__ option. +:sorters.hash: + Deterministic ordering using FNV-1a hash. (default) -.. note:: + Accepts a ``salt`` option for reproducible results. - Not relevant options will be ignored. +:sorters.random: + Random ordering. Different results each time. +criterion +--------- -pre_filter -~~~~~~~~~~~~~~~~ -This means a function to filter beforehand. +:criteria.greedy: + Attempts to make efficient combinations. (default) -It receives an argument `row` as `object` type. + Accepts a ``tolerance`` option. -When the function returns `False`, the row combination will not be registered. +:criteria.simple: + Extracts any pairs that can be stored into the processing row. -- If factors type is `Array`, you should specify an index at the subscript like ``row => row[1] < 6``. -- If factors type is `Object`, you should specify a key at the subscript like ``row => row['month'] < 6`` +constraints +----------- +A list of declarative condition dicts. See `Declarative Constraints`_ above. -post_filter -~~~~~~~~~~~~~~~~ +comparer +-------- +A dict of custom comparison functions to override default operators. -This means a function to filter later. +.. code-block:: python3 -The usage is the same as `preFilter`, only the difference is the timing of the call. -It will delete rows not matched this function at the last. + make(factors, comparer={'eq': lambda a, b: str(a) == str(b)}) -For this reason, the final test cases may not satisfy the factors coverage. Development -=============== +=========== .. code-block:: sh @@ -161,16 +195,8 @@ Development (venv) $ pytest -Publish ----------------- - -.. code-block:: sh - - (venv) $ python setup.py sdist bdist_wheel - (venv) $ twine upload --repository pypi dist/* - - More info -=================== +========= - `walkframe/covertable - GitHub `__ +- `Documentation `__ diff --git a/python/covertable/evaluate.py b/python/covertable/evaluate.py index 7542f21..7bfbbde 100644 --- a/python/covertable/evaluate.py +++ b/python/covertable/evaluate.py @@ -32,10 +32,13 @@ def resolve(row, field): - """Resolve a dot-separated field path against a row dict. + """Resolve a field path against a row dict. + String fields support dot notation for nested access. Returns ``_SENTINEL`` if any segment is missing. """ + if not isinstance(field, str): + return row.get(field, _SENTINEL) parts = field.split(".") current = row for part in parts: diff --git a/python/covertable/exceptions.py b/python/covertable/exceptions.py index b89218f..4750d2f 100644 --- a/python/covertable/exceptions.py +++ b/python/covertable/exceptions.py @@ -2,11 +2,5 @@ class InvalidCondition(BaseException): message = "It will never meet the condition" -class NotReady(Exception): - def __init__(self, key): - super().__init__(f"Not yet '{key}' in the object") - self.key = key - - class NeverMatch(Exception): pass diff --git a/python/covertable/main.py b/python/covertable/main.py index 2700b0f..a3a09e8 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -2,19 +2,11 @@ from . import sorters from . import criteria -from .exceptions import NotReady, NeverMatch +from .exceptions import NeverMatch from .evaluate import evaluate as eval_condition, extract_keys from .lib import get_items -class ProxyRow(dict): - """Dict-like object that raises NotReady for missing keys.""" - def __getitem__(self, key): - if key not in self: - raise NotReady(key) - return super().__getitem__(key) - - class Row(dict): def __init__(self, entries=None): super().__init__(entries or {}) @@ -30,7 +22,7 @@ def copy_from(self, other): class Controller: def __init__(self, factors, strength=2, sorter=None, criterion=None, - salt="", tolerance=0, pre_filter=None, post_filter=None, + salt="", tolerance=0, sub_models=None, presets=None, weights=None, constraints=None, comparer=None): self.factors = factors @@ -42,8 +34,6 @@ def __init__(self, factors, strength=2, sorter=None, criterion=None, self.criterion = criterion or criteria.greedy self.salt = salt self.tolerance = tolerance - self.pre_filter = pre_filter - self.post_filter = post_filter self.serials = {} self.parents = {} @@ -120,7 +110,6 @@ def _set_incomplete(self): def is_within_sub_model(keys): return any(all(k in ks for k in keys) for ks in sub_model_key_sets) - # Default strength pairs, excluding combinations fully within a sub-model for keys in combinations(all_keys, self.strength): if is_within_sub_model(keys): continue @@ -128,7 +117,6 @@ def is_within_sub_model(keys): for pair in product(*comb): pairs.append(tuple(sorted(pair))) - # Sub-model pairs at their own strength for sm in self.sub_models: for keys in combinations(sm["keys"], sm["strength"]): comb = [self.serials[keys[i]] for i in range(sm["strength"])] @@ -144,41 +132,25 @@ def is_within_sub_model(keys): def _storable_check(self, candidate, row=None): """Check constraints on (row + candidate). - Returns True (OK), False (violated), or None (deferred). - Falls back to pre_filter when no declarative constraints exist. + Returns True (OK) or False (violated). """ if row is None: row = self.row - if self._constraints: - nxt_obj = None - for i, rc in enumerate(self._constraints): - if i in self._passed_indexes: - continue - if nxt_obj is None: - nxt = dict(row) - nxt.update(candidate) - nxt_obj = self._to_map_from_dict(nxt) - result = eval_condition(rc["condition"], nxt_obj, self.comparer) - if result is False: - return False + if not self._constraints: return True - # Legacy pre_filter path - if self.pre_filter is None: - return True - nxt = dict(row) - nxt.update(candidate) - nxt_row = Row(nxt) - proxy = self._to_proxy(nxt_row) - try: - ok = self.pre_filter(proxy) - if not ok: + nxt_obj = None + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + if nxt_obj is None: + nxt = dict(row) + nxt.update(candidate) + nxt_obj = self._to_map_from_dict(nxt) + result = eval_condition(rc["condition"], nxt_obj, self.comparer) + if result is False: return False - except NotReady: - return None - except Exception: - raise return True def _mark_passed_constraints(self, row): @@ -198,14 +170,6 @@ def _mark_passed_constraints(self, row): return False return True - def _set_pair(self, pair): - """Legacy: directly set pair into row (used when no constraints).""" - for key, value in self.get_candidate(pair): - self.row[key] = value - for s in self.all_strengths: - for p in combinations(sorted(self.row.values()), s): - self.consume(p) - def set_pair(self, pair): """Snapshot-based pair addition with constraint checking. @@ -311,7 +275,6 @@ def _forward_check(self, snapshot): peer_constraints = self._constraints_by_key.get(peer_key) if not peer_constraints: continue - # Check if peer shares constraints with this factor if not (peer_constraints & key_constraints): continue @@ -362,11 +325,6 @@ def consume_pairs(self, row): p = tuple(pair) self.incomplete.pop(p, None) - def consume_row(self, row): - for s in self.all_strengths: - for pair in combinations(sorted(row.values()), s): - self.consume(pair) - @property def all_strengths(self): strengths = {self.strength} @@ -402,12 +360,6 @@ def storable(self, candidate, row=None): check = self._storable_check(candidate, row) if check is False: - # Consume violated pairs when using legacy pre_filter - if not self._constraints and self.pre_filter is not None: - nxt = dict(row) - nxt.update(candidate) - nxt_row = Row(nxt) - self.consume_row(nxt_row) return None return num @@ -433,9 +385,6 @@ def _to_map_from_dict(self, d): result[key] = self.factors[key][index - first] return result - def _to_proxy(self, row): - return ProxyRow(self._to_map(row)) - def _to_object(self, row): return self._to_map(row) @@ -445,12 +394,6 @@ def _reset(self): self.row = Row() self._passed_indexes.clear() - def _discard(self): - pair_key = self.row.get_pair_key() - self.rejected.add(pair_key) - self.row = Row() - self._passed_indexes.clear() - def _restore(self): row = self.row self.row = Row() @@ -586,23 +529,17 @@ def _record_completions(self, row, greedy_keys): def is_complete(self): if not self.is_filled(): return False - if self._constraints: - obj = self._to_object(self.row) - for i, rc in enumerate(self._constraints): - if i in self._passed_indexes: - continue - result = eval_condition(rc["condition"], obj, self.comparer) - # null (None) = referenced key doesn't exist — treat as satisfied - if result is False: - return False - return True - if self.pre_filter is None: + if not self._constraints: return True - proxy = self._to_proxy(self.row) - try: - return bool(self.pre_filter(proxy)) - except NotReady: - return True # null tolerance: treat unknown as satisfied + obj = self._to_object(self.row) + for i, rc in enumerate(self._constraints): + if i in self._passed_indexes: + continue + result = eval_condition(rc["condition"], obj, self.comparer) + # null (None) = referenced key doesn't exist — treat as satisfied + if result is False: + return False + return True @property def stats(self): @@ -651,8 +588,6 @@ def _apply_preset(self, preset): return True def make_async(self): - has_constraints = bool(self._constraints) - # Process presets for preset in self.presets: if not self._apply_preset(preset): @@ -664,10 +599,7 @@ def make_async(self): self._record_completions(self.row, preset_keys) self.consume_pairs(self.row) self._row_count += 1 - if self.post_filter is None or self.post_filter(self._to_object(self.row)): - yield self._restore() - else: - self._discard() + yield self._restore() else: self._reset() except NeverMatch: @@ -677,20 +609,14 @@ def make_async(self): consecutive_failures = 0 while self.incomplete: # Phase 1: greedy selects pairs, setPair validates via snapshot - if has_constraints: - for pair in self.criterion.extract(self): - if self.is_filled(): - break - pk = pair - if pk in self.row.invalid_pairs: - continue - if not self.set_pair(pair): - self.row.invalid_pairs.add(pk) - else: - for pair in self.criterion.extract(self): - if self.is_filled(): - break - self._set_pair(pair) + for pair in self.criterion.extract(self): + if self.is_filled(): + break + pk = pair + if pk in self.row.invalid_pairs: + continue + if not self.set_pair(pair): + self.row.invalid_pairs.add(pk) greedy_keys = set(self.row.keys()) @@ -701,16 +627,12 @@ def make_async(self): self._record_completions(self.row, greedy_keys) self.consume_pairs(self.row) self._row_count += 1 - if self.post_filter is None or self.post_filter(self._to_object(self.row)): - yield self._restore() - else: - self._discard() + yield self._restore() consecutive_failures = 0 else: consecutive_failures += 1 if consecutive_failures > len(self.incomplete): break - # Carry invalidPairs into next attempt failed_pairs = set(self.row.invalid_pairs) for s in self.all_strengths: for p in combinations(sorted(self.row.values()), s): @@ -719,32 +641,24 @@ def make_async(self): self.rejected.clear() self.row.invalid_pairs.update(failed_pairs) except NeverMatch: - if has_constraints: - self._reset() - self.rejected.clear() - continue - break + self._reset() + self.rejected.clear() + continue if not self.incomplete: break # Phase 3 (rescue): try remaining pairs individually for pair in list(self.incomplete.values()): self._reset() - if has_constraints: - if not self.set_pair(pair): - continue - else: - self._set_pair(pair) + if not self.set_pair(pair): + continue rescue_keys = set(self.row.keys()) result = self._close() if result is True: self._record_completions(self.row, rescue_keys) self.consume_pairs(self.row) self._row_count += 1 - if self.post_filter is None or self.post_filter(self._to_object(self.row)): - yield self._restore() - else: - self._discard() + yield self._restore() else: self._reset() @@ -760,8 +674,6 @@ def make_async( progress=False, sorter=sorters.hash, criterion=criteria.greedy, - pre_filter=None, - post_filter=None, salt="", tolerance=0, sub_models=None, @@ -771,7 +683,6 @@ def make_async( comparer=None, **params, ): - # backwards compat: extract salt/tolerance from options dict options = params.pop("options", {}) if isinstance(options, dict): salt = options.get("salt", salt) @@ -784,8 +695,6 @@ def make_async( criterion=criterion, salt=salt, tolerance=tolerance, - pre_filter=pre_filter, - post_filter=post_filter, sub_models=sub_models, presets=presets, weights=weights, @@ -804,8 +713,6 @@ def make( progress=False, sorter=sorters.hash, criterion=criteria.greedy, - pre_filter=None, - post_filter=None, salt="", tolerance=0, sub_models=None, @@ -821,8 +728,6 @@ def make( progress=progress, sorter=sorter, criterion=criterion, - pre_filter=pre_filter, - post_filter=post_filter, salt=salt, tolerance=tolerance, sub_models=sub_models, diff --git a/python/covertable/pict/model.py b/python/covertable/pict/model.py index 74862e4..f4a8d79 100644 --- a/python/covertable/pict/model.py +++ b/python/covertable/pict/model.py @@ -189,7 +189,6 @@ def eval_negatives(row): def _build_kwargs(self, kwargs): kwargs = dict(kwargs) user_constraints = kwargs.pop("constraints", None) - user_filter = kwargs.pop("pre_filter", None) user_sub_models = kwargs.pop("sub_models", None) user_weights = kwargs.pop("weights", None) @@ -197,13 +196,6 @@ def _build_kwargs(self, kwargs): constraints = list(self._model_constraints()) if user_constraints: constraints.extend(user_constraints) - if user_filter: - # Wrap legacy pre_filter as a custom constraint - constraints.append({ - "operator": "custom", - "keys": list(self._parameters.keys()), - "evaluate": user_filter, - }) kwargs["constraints"] = constraints if user_sub_models is not None: diff --git a/python/test_pict.py b/python/test_pict.py index 1b9004e..ddcf997 100644 --- a/python/test_pict.py +++ b/python/test_pict.py @@ -383,11 +383,13 @@ def test_make_async_yields_rows(self): rows = list(model.make_async()) assert len(rows) > 0 - def test_user_pre_filter_combines_with_model_filter(self): + def test_user_constraints_combine_with_model_constraints(self): model = PictModel(""" OS: iOS, Android Browser: Chrome, Safari """) - rows = model.make(pre_filter=lambda row: row["OS"] != "iOS") + rows = model.make(constraints=[ + {"operator": "ne", "field": "OS", "value": "iOS"}, + ]) for row in rows: assert row["OS"] != "iOS" diff --git a/python/tests.py b/python/tests.py index f32ea98..af02b36 100644 --- a/python/tests.py +++ b/python/tests.py @@ -10,8 +10,7 @@ def call( sorter="hash", criterion="greedy", options={}, - pre_filter=None, - post_filter=None, + constraints=None, ): from covertable import make, sorters, criteria @@ -22,14 +21,13 @@ def call( criterion=getattr(criteria, criterion), options=options, progress=True, - pre_filter=pre_filter, - post_filter=post_filter, + constraints=constraints, ) class Test_covertable: def _get_pairs(self, factors, strength=2): - from covertable.main import get_items + from covertable.lib import get_items all_keys = [k for k, _ in get_items(factors)] for keys in combinations(all_keys, strength): @@ -55,42 +53,35 @@ def test_all_pairs_must_be_in_rows(self, strength): else: assert False, f"{pair} is not in any rows." - def test_pre_filter_excludes_specified_pairs_before(self): + def test_constraints_exclude_specified_pairs(self): factors = [["a", "b", "c"], ["d", "e"], ["f"]] - def pre_filter(row): - if row[0] == "a" and row[1] == "d": - return False - if row[0] == "b" and row[1] == "e": - return False - return True - - rows = call(factors, strength=2, pre_filter=pre_filter) + rows = call( + factors, + strength=2, + constraints=[ + {"operator": "custom", "keys": [0, 1], "evaluate": + lambda row: not (row[0] == "a" and row[1] == "d")}, + {"operator": "custom", "keys": [0, 1], "evaluate": + lambda row: not (row[0] == "b" and row[1] == "e")}, + ], + ) unexpected_pairs = [("a", "d"), ("b", "e")] for pair in unexpected_pairs: for row in rows: assert not all(p in row for p in pair), f"{pair} is in a row: {row}" - def test_pre_filter_never_matching_makes_no_rows(self): + def test_constraints_never_matching_makes_no_rows(self): factors = [["a", "b", "c"], ["d", "e"], ["f"]] - def pre_filter(row): - if row[2] == "f": - return False - return True - - rows = call(factors, strength=2, pre_filter=pre_filter) - assert not rows - - def test_post_filter_never_matching_makes_no_rows(self): - factors = [["a", "b", "c"], ["d", "e"], ["f"]] - - def post_filter(row): - if row[2] == "f": - return False - return True - - rows = call(factors, strength=2, post_filter=post_filter) + rows = call( + factors, + strength=2, + constraints=[ + {"operator": "custom", "keys": [2], "evaluate": + lambda row: row[2] != "f"}, + ], + ) assert not rows def test_greedy_sorter_should_make_rows_less_than_hashs_one_with2(self): @@ -168,16 +159,16 @@ def test_presets_partial_row_is_completed(self): assert rows[0]["A"] == "a1" assert "B" in rows[0] - def test_presets_violating_pre_filter_are_dropped(self): + def test_presets_violating_constraint_are_dropped(self): from covertable import make factors = {"OS": ["iOS", "Android"], "Browser": ["Safari", "Chrome"]} - def pre_filter(row): - return not (row["OS"] == "iOS" and row["Browser"] == "Chrome") - rows = make( factors, - pre_filter=pre_filter, + constraints=[ + {"operator": "custom", "keys": ["OS", "Browser"], "evaluate": + lambda row: not (row["OS"] == "iOS" and row["Browser"] == "Chrome")}, + ], presets=[ {"OS": "iOS", "Browser": "Chrome"}, # rejected {"OS": "Android", "Browser": "Safari"}, # accepted diff --git a/typescript/README.md b/typescript/README.md index 134dd77..3457f00 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -37,4 +37,4 @@ make([machine, os, browser]); ``` # Advanced usage -Advanced usage is [here](https://docs.walkframe.com/covertable/advanced) \ No newline at end of file +Advanced usage is [here](https://covertable.walkframe.com) \ No newline at end of file diff --git a/typescript/package.json b/typescript/package.json index 3ce31a8..9747885 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -2,7 +2,7 @@ "name": "covertable", "version": "3.0.0-rc.0", "description": "A flexible pairwise tool written in TypeScript", - "homepage": "https://docs.walkframe.com/covertable", + "homepage": "https://covertable.walkframe.com", "repository": { "type": "git", "url": "git+https://github.com/walkframe/covertable.git" From c6d1b536cb2c7c2413b8b97cc18bf86f958f9212 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 00:33:58 +0900 Subject: [PATCH 67/79] 3.0.0-rc.1 --- python/setup.cfg | 6 +++--- typescript/package.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/setup.cfg b/python/setup.cfg index ab54260..d7c5ba0 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,9 +1,9 @@ [metadata] name = covertable -version = 3.0.0rc0 +version = 3.0.0rc1 author = righ author_email = righ.m9@gmail.com -url = https://github.com/walkframe/covertable/ +url = https://covertable.walkframe.com license = Apache Software License classifier = Intended Audience :: Developers @@ -36,6 +36,6 @@ keywords = covering-arrays pict -description = A flexible pairwise tool written in Python. +description = Powerful pairwise testing library in Python, producing covering arrays that minimize test cases while respecting constraints. long_description = file: README.rst long_description_content_type = text/x-rst diff --git a/typescript/package.json b/typescript/package.json index 9747885..e5e44b0 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,7 +1,7 @@ { "name": "covertable", - "version": "3.0.0-rc.0", - "description": "A flexible pairwise tool written in TypeScript", + "version": "3.0.0-rc.1", + "description": "Efficient TypeScript library for pairwise testing, generating minimal covering arrays with constraint support.", "homepage": "https://covertable.walkframe.com", "repository": { "type": "git", From ec40f2ce362fc4d183ed16785fbd964a4529d467 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 00:41:41 +0900 Subject: [PATCH 68/79] fix: docs --- docs/contents/advanced/index.mdx | 2 +- docs/contents/advanced/options.mdx | 2 +- docs/contents/history/migration.mdx | 2 +- docs/contents/index.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/contents/advanced/index.mdx b/docs/contents/advanced/index.mdx index d99d853..ec0f9fa 100644 --- a/docs/contents/advanced/index.mdx +++ b/docs/contents/advanced/index.mdx @@ -47,7 +47,7 @@ The `make` function accepts an options object as its second argument: | `subModels` | `SubModelType[]` | `undefined` | Apply a different combination strength to a specific group of factors. | | `weights` | `WeightsType` | `undefined` | Index-keyed weights that bias value selection during row completion. | | `presets` | `PresetRowType[]` | `undefined` | Rows that must be included in the output. Equivalent to PICT's seeding feature. | -| `constraints` | `Condition[]` | `undefined` | Declarative constraints evaluated under three-valued logic. See [Constraint Logic](/constraint-logic). | +| `constraints` | `Condition[]` | `undefined` | Declarative constraints evaluated under three-valued logic. See [Constraint Logic](/advanced/constraint-logic). | | `comparer` | `Comparer` | `undefined` | Custom comparison functions for constraint evaluation. | | `sorter` | `Function` | `sorters.hash` | Determines the order of combinations. | | `criterion` | `Function` | `criteria.greedy` | Determines the algorithm for generating combinations. | diff --git a/docs/contents/advanced/options.mdx b/docs/contents/advanced/options.mdx index 2059e6e..668ae18 100644 --- a/docs/contents/advanced/options.mdx +++ b/docs/contents/advanced/options.mdx @@ -105,7 +105,7 @@ PICT calls this feature **seeding** and reads the seed rows from a tab-separated ## `constraints` -Declarative constraints evaluated under Kleene three-valued logic. See [Constraint Logic](/constraint-logic) for full documentation. +Declarative constraints evaluated under Kleene three-valued logic. See [Constraint Logic](/advanced/constraint-logic) for full documentation. ```typescript make(factors, { diff --git a/docs/contents/history/migration.mdx b/docs/contents/history/migration.mdx index 90552e2..d3062eb 100644 --- a/docs/contents/history/migration.mdx +++ b/docs/contents/history/migration.mdx @@ -60,7 +60,7 @@ Declarative constraints allow the engine to: - Propagate constraint chains via forward checking - Detect unsolvable combinations early instead of silently dropping rows -See [Constraint Logic](/constraint-logic) for details. +See [Constraint Logic](/advanced/constraint-logic) for details. ::: ### Replacing `postFilter` diff --git a/docs/contents/index.mdx b/docs/contents/index.mdx index e8f5fee..98d64e3 100644 --- a/docs/contents/index.mdx +++ b/docs/contents/index.mdx @@ -111,7 +111,7 @@ console.log(ctrl.stats); // } ``` -See [Constraint Logic](/constraint-logic#statistics) for full details on each field. +See [Constraint Logic](/advanced/constraint-logic#statistics) for full details on each field. ## Async Generation From 4f442a32e279ff34acc5c355d24d8da3550de6cc Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 17:21:20 +0900 Subject: [PATCH 69/79] feat: support arithmetic expressions --- docs/contents/advanced/constraint-logic.mdx | 18 +- docs/contents/advanced/index.mdx | 12 +- docs/contents/advanced/options.mdx | 4 +- docs/contents/advanced/pict.mdx | 75 +++++++++ docs/contents/advanced/shortcuts.mdx | 157 ++++++++++++++++++ docs/contents/history/migration.mdx | 4 +- docs/contents/tools/pict-online.mdx | 6 +- docs/contents/tools/pict.tsx | 8 + docs/sidebars.ts | 2 +- heavy.pict | 27 +++ python/README.rst | 27 ++- python/covertable/evaluate.py | 86 ++++++++-- python/covertable/main.py | 4 +- python/covertable/pict/lexer.py | 131 ++++++++++++++- python/covertable/pict/model.py | 8 +- python/covertable/pict/parser.py | 2 +- python/covertable/shortcuts.py | 153 +++++++++++++++++ python/pytest.ini | 2 +- python/test_pict.py | 4 +- python/tests.py | 93 ++++++++++- typescript/package.json | 5 + typescript/src/__tests__/bench.test.ts | 20 +-- .../src/__tests__/contradictory.test.ts | 32 ++-- .../src/__tests__/coverage-bench.test.ts | 36 ++-- .../src/__tests__/custom-condition.test.ts | 145 ++++++++++++++++ typescript/src/__tests__/filter.test.ts | 14 +- .../__tests__/forward-check-complex.test.ts | 118 ++++++------- .../__tests__/forward-check-weakness.test.ts | 64 +++---- .../src/__tests__/forward-check.test.ts | 32 ++-- typescript/src/__tests__/index.test.ts | 12 +- typescript/src/__tests__/pict.test.ts | 4 +- typescript/src/__tests__/shortcuts.test.ts | 132 +++++++++++++++ .../src/__tests__/simple-criterion.test.ts | 82 ++++----- typescript/src/controller.ts | 8 +- typescript/src/evaluate.ts | 71 ++++++-- typescript/src/index.ts | 9 +- typescript/src/pict/constraints.ts | 134 ++++++++++++++- typescript/src/pict/model.ts | 18 +- typescript/src/pict/subModels.ts | 4 +- typescript/src/shortcuts/index.ts | 154 +++++++++++++++++ typescript/src/types.ts | 73 ++++---- typescript/tsconfig.test.json | 3 +- typescript/vite.config.ts | 1 + 43 files changed, 1647 insertions(+), 347 deletions(-) create mode 100644 docs/contents/advanced/shortcuts.mdx create mode 100644 python/covertable/shortcuts.py create mode 100644 typescript/src/__tests__/custom-condition.test.ts create mode 100644 typescript/src/__tests__/shortcuts.test.ts create mode 100644 typescript/src/shortcuts/index.ts diff --git a/docs/contents/advanced/constraint-logic.mdx b/docs/contents/advanced/constraint-logic.mdx index 7d8d34d..74ffe4c 100644 --- a/docs/contents/advanced/constraint-logic.mdx +++ b/docs/contents/advanced/constraint-logic.mdx @@ -68,8 +68,8 @@ while **deferring** judgment when information is incomplete. // Example: IF [Region] = "EU" THEN [Currency] IN {"EUR", "GBP"} // Expressed as: { operator: 'or', conditions: [ - { operator: 'ne', field: 'Region', value: 'EU' }, - { operator: 'in', field: 'Currency', values: ['EUR', 'GBP'] }, + { operator: 'ne', left: 'Region', value: 'EU' }, + { operator: 'in', left: 'Currency', values: ['EUR', 'GBP'] }, ]} // Row = { Region: "EU" } → null (Currency not set) @@ -304,11 +304,11 @@ Use `Controller.make()` directly if you want to handle incomplete coverage witho | Type | Example | Description | |------|---------|-------------| -| `eq` | `{ operator: 'eq', field: 'A', value: 1 }` | Equality with literal | -| `eq` (target) | `{ operator: 'eq', field: 'A', target: 'B' }` | Equality with another field | -| `ne` | `{ operator: 'ne', field: 'A', value: 1 }` | Inequality | -| `gt`, `lt`, `gte`, `lte` | `{ operator: 'gt', field: 'A', value: 5 }` | Comparison operators | -| `in` | `{ operator: 'in', field: 'A', values: [1,2,3] }` | Set membership | +| `eq` | `{ operator: 'eq', left: 'A', value: 1 }` | Equality with literal | +| `eq` (right) | `{ operator: 'eq', left: 'A', right: 'B' }` | Equality with another field | +| `ne` | `{ operator: 'ne', left: 'A', value: 1 }` | Inequality | +| `gt`, `lt`, `gte`, `lte` | `{ operator: 'gt', left: 'A', value: 5 }` | Comparison operators | +| `in` | `{ operator: 'in', left: 'A', values: [1,2,3] }` | Set membership | | `not` | `{ operator: 'not', condition: ... }` | Logical negation | | `and` | `{ operator: 'and', conditions: [...] }` | Logical AND (all must hold) | | `or` | `{ operator: 'or', conditions: [...] }` | Logical OR (at least one) | @@ -321,8 +321,8 @@ PICT-style `IF [A] = x THEN [B] = y` is expressed as: ```typescript // IF A THEN B ≡ NOT A OR B { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 'x' }, // NOT A - { operator: 'eq', field: 'B', value: 'y' }, // B + { operator: 'ne', left: 'A', value: 'x' }, // NOT A + { operator: 'eq', left: 'B', value: 'y' }, // B ]} ``` diff --git a/docs/contents/advanced/index.mdx b/docs/contents/advanced/index.mdx index ec0f9fa..b061ad5 100644 --- a/docs/contents/advanced/index.mdx +++ b/docs/contents/advanced/index.mdx @@ -26,12 +26,12 @@ const rows = make(factors, { constraints: [ // iPhone ↔ iOS { operator: 'or', conditions: [ - { operator: 'ne', field: 'machine', value: 'iPhone' }, - { operator: 'eq', field: 'os', value: 'iOS' }, + { operator: 'ne', left: 'machine', value: 'iPhone' }, + { operator: 'eq', left: 'os', value: 'iOS' }, ]}, { operator: 'or', conditions: [ - { operator: 'eq', field: 'machine', value: 'iPhone' }, - { operator: 'ne', field: 'os', value: 'iOS' }, + { operator: 'eq', left: 'machine', value: 'iPhone' }, + { operator: 'ne', left: 'os', value: 'iOS' }, ]}, ], }); @@ -47,11 +47,11 @@ The `make` function accepts an options object as its second argument: | `subModels` | `SubModelType[]` | `undefined` | Apply a different combination strength to a specific group of factors. | | `weights` | `WeightsType` | `undefined` | Index-keyed weights that bias value selection during row completion. | | `presets` | `PresetRowType[]` | `undefined` | Rows that must be included in the output. Equivalent to PICT's seeding feature. | -| `constraints` | `Condition[]` | `undefined` | Declarative constraints evaluated under three-valued logic. See [Constraint Logic](/advanced/constraint-logic). | +| `constraints` | `Expression[]` | `undefined` | Declarative constraints evaluated under three-valued logic. See [Constraint Logic](/advanced/constraint-logic). | | `comparer` | `Comparer` | `undefined` | Custom comparison functions for constraint evaluation. | | `sorter` | `Function` | `sorters.hash` | Determines the order of combinations. | | `criterion` | `Function` | `criteria.greedy` | Determines the algorithm for generating combinations. | | `salt` | `string \| number` | `""` | Value mixed into `sorters.hash` to control the ordering of pairs. | | `tolerance` | `number` | `0` | Tolerance used by `criteria.greedy` to trade optimality for speed. | -See [Options Detail](./options) for full documentation of each option, or [PictModel](./pict) for the PICT-compatible model parser. +See [Options Detail](./options) for full documentation of each option, [PictModel](./pict) for the PICT-compatible model parser, or [Shortcuts](./shortcuts) for a concise constraint builder API. diff --git a/docs/contents/advanced/options.mdx b/docs/contents/advanced/options.mdx index 668ae18..b29084d 100644 --- a/docs/contents/advanced/options.mdx +++ b/docs/contents/advanced/options.mdx @@ -112,8 +112,8 @@ make(factors, { constraints: [ // IF machine = iPhone THEN os = iOS { operator: 'or', conditions: [ - { operator: 'ne', field: 'machine', value: 'iPhone' }, - { operator: 'eq', field: 'os', value: 'iOS' }, + { operator: 'ne', left: 'machine', value: 'iPhone' }, + { operator: 'eq', left: 'os', value: 'iOS' }, ]}, ], }); diff --git a/docs/contents/advanced/pict.mdx b/docs/contents/advanced/pict.mdx index 9924d1d..54b196d 100644 --- a/docs/contents/advanced/pict.mdx +++ b/docs/contents/advanced/pict.mdx @@ -7,6 +7,14 @@ title: PictModel `PictModel` parses a complete PICT-format model — parameters, sub-models, and constraints — into a single object that can directly generate rows. It is exported from a separate entry point so it does not bloat the bundle of consumers who only need `make`. +:::caution PICT superset + +CoverTable's model format is a **superset of Microsoft PICT**. It extends the original syntax with features such as arithmetic expressions (`[A] * [B] > 100`, `([A] + 1) * [B] <= 500`), comment lines (`#`) in the constraint section, and the `~` negative-value prefix in output. + +Models written for CoverTable **may not run in the original PICT tool** if they use these extensions. If you need compatibility with Microsoft PICT, avoid using arithmetic operators and other extended syntax in your constraints. + +::: + ```typescript import { PictModel } from "covertable/pict"; @@ -154,3 +162,70 @@ make(factors, { :::tip[Try it interactively] Try the [**Compatible PICT**](/tools/pict) tool to experiment with the constraint syntax in your browser. ::: + +## Differences from the Original PICT + +covertable's `PictModel` accepts PICT-format input, but the underlying engine works differently from the original PICT tool developed by Microsoft. + +### Generation Algorithm + +| | Original PICT | covertable | +|---|---|---| +| **Greedy strategy** | Picks the combination with the most uncovered (OPEN) slots in a bitvector, then selects a value that maximizes globally covered pairs | Scores each uncovered pair by how many other uncovered pairs it would cover when added to the current row | +| **Value selection** | `PickValue()` maximizes `complete` (fully-bound combinations) then `totalZeros` (global coverage) | Greedy selects full pairs; remaining factors are filled by `close()` using depth-first backtracking | +| **Tie-breaking** | `rand()` with a configurable seed | Deterministic hash (FNV1a32) of pair indices + `salt` string | + +### Constraint Processing + +| | Original PICT | covertable | +|---|---|---| +| **Approach** | Pre-compiles constraints into explicit exclusion sets before generation | Evaluates constraints at runtime using three-valued (Kleene) logic | +| **Internal form** | `IF [A]="x" THEN [B]<>"y"` → exclusion `{A:"x", B:"y"}` | Constraints remain as expressions and are evaluated per candidate | +| **AND** | Cross-product of exclusion sets (can grow exponentially) | Short-circuit evaluation; returns `False` as soon as any branch fails | +| **Propagation** | `ExclusionDeriver` derives implicit exclusions before generation | `forwardCheck` prunes domains dynamically (AC-3-style arc consistency) | +| **Backtracking** | Exclusions are baked into a bitvector; no backtracking needed | Depth-first backtracking fills remaining factors when greedy selection stalls | +| **Flexibility** | DSL only (`IF`/`THEN`/`ELSE`, comparisons, `IN`, `LIKE`) | Supports arbitrary lambda predicates via the `custom` operator | + +### Seeding / Presets + +| | Original PICT | covertable | +|---|---|---| +| **API** | `PictAddSeed()` / CLI `-e seedfile` | `presets` option (list of partial-row dicts/objects) | +| **Format** | Array of `(parameter, value_index)` tuples | Value dictionaries — e.g. `{ OS: "Win", Browser: "Chrome" }` | +| **Conflict handling** | Seeds violating exclusions are silently removed by `fixRowSeeds()` | Presets are processed first; `close()` fills remaining factors respecting constraints | + +### Sub-models + +| | Original PICT | covertable | +|---|---|---| +| **Structure** | Fully hierarchical — sub-models are independent `Model` instances combined via pseudo-parameters | Flat key-set partitioning with per-set strength | +| **Nesting** | Sub-models can be nested arbitrarily | Single level only | +| **Overlap** | Parameters can appear in multiple sub-models; conflicts resolved by exclusion generation | Each parameter belongs to at most one sub-model | + +### Weights + +| | Original PICT | covertable | +|---|---|---| +| **Syntax** | `value (weight)` in model file / `valueWeights[]` in API | `weights` option — `{ factor: { valueIndex: weight } }` | +| **Effect** | Influences tie-breaking in `PickValue()` and random-row generation | Influences only the `close()` (backtracking completion) phase — higher-weight values are tried first | + +### Randomization and Determinism + +| | Original PICT | covertable | +|---|---|---| +| **Default** | Deterministic (seed 0) | Deterministic (`hash` sorter with empty salt) | +| **Randomize** | `-r [seed]` flag; uses `srand()`/`rand()` | Change `salt` for reproducible variation; use `random` sorter for non-deterministic output | + +### Output and Streaming + +| | Original PICT | covertable | +|---|---|---| +| **Output** | Batch only — all rows generated before any are returned (TSV or JSON from CLI; index array from C API) | Generator-based — rows yielded incrementally via `makeAsync()` / `make_async()` | +| **Format** | Tab-separated table or JSON array of objects | Python `list`/`dict` rows; TypeScript typed arrays/objects with full type inference | + +### Platform + +| | Original PICT | covertable | +|---|---|---| +| **Language** | C++ (with C-compatible API via `pictapi.h`) | Pure Python 3 + pure TypeScript — no native code, no compilation | +| **Runtime** | Compiled binary; Windows, Linux, macOS | Python: pip install; TypeScript: npm install; also runs in browsers | diff --git a/docs/contents/advanced/shortcuts.mdx b/docs/contents/advanced/shortcuts.mdx new file mode 100644 index 0000000..86d9219 --- /dev/null +++ b/docs/contents/advanced/shortcuts.mdx @@ -0,0 +1,157 @@ +--- +sidebar_position: 5 +title: Shortcuts +--- + +# Constraint Shortcuts + +Writing constraint expressions as plain objects is verbose. The `Constraint` class provides a concise builder API with `$`-prefixed field references. + +## Setup + +```typescript +import { make } from "covertable"; +import { Constraint } from "covertable/shortcuts"; + +const factors = { + OS: ["Win", "Mac", "Linux"], + Browser: ["Chrome", "Firefox", "Safari"], + Price: [100, 500, 1000], + Qty: [1, 2, 5], +}; + +const c = new Constraint(); +``` + +```python +from covertable import make +from covertable.shortcuts import Constraint + +c = Constraint() +``` + +In TypeScript, passing `typeof factors` as a type parameter enables autocompletion for `$`-prefixed field names. + +## Field References + +Prefix a field name with `$` to reference it. Anything without `$` is treated as a literal value. + +```typescript +c.eq("$OS", "Mac") // OS == "Mac" (field vs literal) +c.ne("$OS", "$Browser") // OS != Browser (field vs field) +c.gt("$Price", 500) // Price > 500 (field vs number) +``` + +## Comparison + +| Method | Raw equivalent | +|--------|---------------| +| `c.eq("$A", "x")` | `{ operator: 'eq', left: 'A', value: 'x' }` | +| `c.ne("$A", "$B")` | `{ operator: 'ne', left: 'A', right: 'B' }` | +| `c.gt("$A", 10)` | `{ operator: 'gt', left: 'A', value: 10 }` | +| `c.lt("$A", "$B")` | `{ operator: 'lt', left: 'A', right: 'B' }` | +| `c.gte("$A", 0)` | `{ operator: 'gte', left: 'A', value: 0 }` | +| `c.lte("$A", 100)` | `{ operator: 'lte', left: 'A', value: 100 }` | +| `c.in("$A", [1, 2])` | `{ operator: 'in', left: 'A', values: [1, 2] }` | + +## Logical + +```typescript +c.and(c.eq("$OS", "Mac"), c.eq("$Browser", "Safari")) +c.or(c.eq("$OS", "Mac"), c.eq("$OS", "Win")) +c.not(c.eq("$OS", "Linux")) +``` + +In Python, use `c.and_()`, `c.or_()`, `c.not_()` (trailing underscore to avoid reserved words). + +## Arithmetic + +Binary operators that return an expression (usable as an operand in comparisons): + +```typescript +c.add("$A", "$B") // A + B +c.sub("$A", 100) // A - 100 +c.mul("$Price", "$Qty") // Price * Qty +c.div("$Total", 2) // Total / 2 +c.mod("$A", 2) // A % 2 +``` + +Nest them for complex expressions: + +```typescript +c.gt(c.mul("$Price", "$Qty"), 10000) // Price * Qty > 10000 +c.lte(c.mul(c.add("$Price", 100), "$Qty"), 30000) // (Price + 100) * Qty <= 30000 +``` + +## Variadic Arithmetic + +`sum` and `product` fold multiple operands left-to-right: + +```typescript +c.sum("$A", "$B", "$C") // (A + B) + C +c.product("$X", "$Y", "$Z") // (X * Y) * Z +c.lte(c.sum("$A", "$B", "$C"), 100) // A + B + C <= 100 +``` + +## Custom Function (`fn`) + +For constraints that can't be expressed declaratively: + +```typescript +c.fn(["OS", "Browser"], (row) => { + return row.OS !== "Linux" || row.Browser !== "Safari"; +}) +``` + +```python +c.fn(["OS", "Browser"], lambda row: row["OS"] != "Linux" or row["Browser"] != "Safari") +``` + +The `fields` parameter tells the engine which factors to wait for before calling the function (three-valued logic). + +## Full Example + +```typescript +import { make } from "covertable"; +import { Constraint } from "covertable/shortcuts"; + +const factors = { + OS: ["Win", "Mac", "Linux"], + Browser: ["Chrome", "Firefox", "Safari"], + Price: [100, 500, 1000], + Qty: [1, 2, 5, 10], +}; + +const c = new Constraint(); + +const rows = make(factors, { + constraints: [ + // Safari only on Mac + c.or(c.ne("$Browser", "Safari"), c.eq("$OS", "Mac")), + // Total must not exceed 5000 + c.lte(c.mul("$Price", "$Qty"), 5000), + // Bulk orders (qty >= 5) require Price >= 500 + c.or(c.lt("$Qty", 5), c.gte("$Price", 500)), + ], +}); +``` + +```python +from covertable import make +from covertable.shortcuts import Constraint + +factors = { + "OS": ["Win", "Mac", "Linux"], + "Browser": ["Chrome", "Firefox", "Safari"], + "Price": [100, 500, 1000], + "Qty": [1, 2, 5, 10], +} + +c = Constraint() + +rows = make(factors, constraints=[ + c.or_(c.ne("$Browser", "Safari"), c.eq("$OS", "Mac")), + c.lte(c.mul("$Price", "$Qty"), 5000), + c.or_(c.lt("$Qty", 5), c.gte("$Price", 500)), +]) +``` diff --git a/docs/contents/history/migration.mdx b/docs/contents/history/migration.mdx index d3062eb..610ccf4 100644 --- a/docs/contents/history/migration.mdx +++ b/docs/contents/history/migration.mdx @@ -46,8 +46,8 @@ make(factors, { make(factors, { constraints: [ { operator: 'or', conditions: [ - { operator: 'ne', field: 'machine', value: 'iPhone' }, - { operator: 'eq', field: 'os', value: 'iOS' }, + { operator: 'ne', left: 'machine', value: 'iPhone' }, + { operator: 'eq', left: 'os', value: 'iOS' }, ]}, ], }); diff --git a/docs/contents/tools/pict-online.mdx b/docs/contents/tools/pict-online.mdx index 1d0e59a..f97dda0 100644 --- a/docs/contents/tools/pict-online.mdx +++ b/docs/contents/tools/pict-online.mdx @@ -8,9 +8,13 @@ import PictDemo from './pict'; # Compatible PICT Online -A browser-based pairwise test case generator fully compatible with [Microsoft PICT](https://github.com/microsoft/pict) model format. +A browser-based pairwise test case generator compatible with [Microsoft PICT](https://github.com/microsoft/pict) model format. Write your model, click Generate, and get optimized test combinations instantly — no installation required. +:::caution[PICT superset] +This tool uses CoverTable's model format, which is a **superset of Microsoft PICT**. It supports extensions such as arithmetic expressions (`[A] * [B] > 100`, `([A] + 1) * [B] <= 500`) and `#` comments in constraints. Models using these extensions may not run in the original PICT tool. +::: + :::info[Privacy] All processing runs entirely in your browser. No data is sent to any server. ::: diff --git a/docs/contents/tools/pict.tsx b/docs/contents/tools/pict.tsx index 35807d6..a1607be 100644 --- a/docs/contents/tools/pict.tsx +++ b/docs/contents/tools/pict.tsx @@ -64,6 +64,7 @@ const pictMark = { paramName: Decoration.mark({ class: "cm-pict-param-name" }), paramValue: Decoration.mark({ class: "cm-pict-param-value" }), operator: Decoration.mark({ class: "cm-pict-operator" }), + arithmetic: Decoration.mark({ class: "cm-pict-arithmetic" }), subModel: Decoration.mark({ class: "cm-pict-sub-model" }), }; @@ -179,6 +180,12 @@ function buildPictDecorations(view: EditorView): DecorationSet { tokens.push({ from: base + m.index, to: base + m.index + m[0].length, mark: pictMark.keyword }); } + // Arithmetic operators +, -, *, /, % + const arithRe = /[+\-*/%]/g; + while ((m = arithRe.exec(text)) !== null) { + tokens.push({ from: base + m.index, to: base + m.index + 1, mark: pictMark.arithmetic }); + } + pos = line.to + 1; } } @@ -226,6 +233,7 @@ const pictHighlightTheme = EditorView.baseTheme({ ".cm-pict-param-name": { color: "#4ec9b0", fontWeight: "bold" }, ".cm-pict-param-value": { color: "#9cdcfe" }, ".cm-pict-operator": { color: "#d4d4d4" }, + ".cm-pict-arithmetic": { color: "#d4d4d4", fontWeight: "bold" }, ".cm-pict-sub-model": { color: "#dcdcaa" }, }); diff --git a/docs/sidebars.ts b/docs/sidebars.ts index 893cce2..e836c2d 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -11,7 +11,7 @@ const sidebars: SidebarsConfig = { { type: 'category', label: 'Advanced', - items: ['advanced/index', 'advanced/options', 'advanced/pict', 'advanced/constraint-logic'], + items: ['advanced/index', 'advanced/options', 'advanced/pict', 'advanced/constraint-logic', 'advanced/shortcuts'], }, { type: 'category', diff --git a/heavy.pict b/heavy.pict index 191277c..06b426d 100644 --- a/heavy.pict +++ b/heavy.pict @@ -20,6 +20,9 @@ SupportPlan: None, Basic, Plus AccountAge: New, Recent, Established, Old EmailVerified: Yes, No PhoneVerified: Yes, No +UnitPrice: 100, 500, 1000, 5000 +Quantity: 1, 2, 5, 10 +DiscountRate: 0, 10, 20, 50 # ----- constraints ----- @@ -90,3 +93,27 @@ IF [GiftOption] = "Message" THEN NOT ([ItemCategory] IN {"Digital"}); IF [Region] IN {"JP", "EU"} THEN [TaxMode] = "Inclusive"; IF [Region] = "US" THEN [TaxMode] = "Exclusive"; + +# ----- arithmetic constraints ----- + +# Subtotal must not exceed 25000 +[UnitPrice] * [Quantity] <= 25000; + +# Discount amount must not exceed subtotal (parentheses override precedence) +[UnitPrice] * [Quantity] * [DiscountRate] / 100 <= [UnitPrice] * [Quantity]; + +# Bulk orders (qty >= 5) require unit price >= 500 +IF [Quantity] >= 5 THEN [UnitPrice] >= 500; + +# High-value orders (subtotal > 10000) cannot use Guest +IF [UnitPrice] * [Quantity] > 10000 THEN NOT ([UserType] IN {"Guest"}); + +# Net amount after discount: parenthesized addition overrides multiplication +# (UnitPrice + 100) * Quantity <= 30000 — shipping surcharge model +([UnitPrice] + 100) * [Quantity] <= 30000; + +# Discount 50% only for subtotal >= 5000 +IF [DiscountRate] = 50 THEN [UnitPrice] * [Quantity] >= 5000; + +# Free shipping threshold: net payable must be >= 3000 +[UnitPrice] * [Quantity] - [UnitPrice] * [Quantity] * [DiscountRate] / 100 >= 0; diff --git a/python/README.rst b/python/README.rst index 54524ff..bb48db4 100644 --- a/python/README.rst +++ b/python/README.rst @@ -41,7 +41,7 @@ Import ``covertable`` and call the ``make`` function. ... criterion=criteria.simple, # default: criteria.greedy ... salt='my_seed', # default: '' ... constraints=[ - ... {'operator': 'custom', 'keys': [0, 1], 'evaluate': + ... {'operator': 'custom', 'fields': [0, 1], 'evaluate': ... lambda row: not(row[1] == 'android' and row[0] != 'pixel') and not(row[1] == 'ios' and row[0] != 'iphone')}, ... ], ... ) @@ -54,8 +54,8 @@ Import ``covertable`` and call the ``make`` function. ... tolerance=3, ... constraints=[ ... {'operator': 'or', 'conditions': [ - ... {'operator': 'eq', 'field': 'os', 'value': 'android'}, - ... {'operator': 'ne', 'field': 'machine', 'value': 'pixel'}, + ... {'operator': 'eq', 'left': 'os', 'value': 'android'}, + ... {'operator': 'ne', 'left': 'machine', 'value': 'pixel'}, ... ]}, ... ], ... ) @@ -80,8 +80,8 @@ three-valued logic with forward checking and constraint propagation. ... constraints=[ ... # Safari only on Mac ... {'operator': 'or', 'conditions': [ - ... {'operator': 'ne', 'field': 'Browser', 'value': 'Safari'}, - ... {'operator': 'eq', 'field': 'OS', 'value': 'Mac'}, + ... {'operator': 'ne', 'left': 'Browser', 'value': 'Safari'}, + ... {'operator': 'eq', 'left': 'OS', 'value': 'Mac'}, ... ]}, ... ], ... ) @@ -90,13 +90,22 @@ Supported condition operators: - **Comparison**: ``eq``, ``ne``, ``gt``, ``lt``, ``gte``, ``lte``, ``in`` - **Logical**: ``and``, ``or``, ``not`` -- **Custom**: ``custom`` (escape hatch with ``keys`` and ``evaluate`` callable) +- **Custom**: ``custom`` (escape hatch with ``fields`` and ``evaluate`` callable) -Field-to-field comparison is supported via the ``target`` key: +Field-to-field comparison uses ``right``: .. code-block:: python3 - {'operator': 'ne', 'field': 'A', 'target': 'B'} + {'operator': 'ne', 'left': 'A', 'right': 'B'} + +Arithmetic expressions can be used as operands: + +.. code-block:: python3 + + # A + B > 10 + {'operator': 'gt', 'left': {'operator': 'add', 'left': 'A', 'right': 'B'}, 'value': 10} + +Supported arithmetic operators: ``add``, ``sub``, ``mul``, ``div``, ``mod`` Stats ----- @@ -109,7 +118,7 @@ When using ``constraints``, the ``Controller`` exposes a ``stats`` property: >>> ctrl = Controller( ... {'A': [1, 2, 3], 'B': ['x', 'y', 'z']}, - ... constraints=[{'operator': 'ne', 'field': 'A', 'value': 1}], + ... constraints=[{'operator': 'ne', 'left': 'A', 'value': 1}], ... ) >>> rows = list(ctrl.make_async()) >>> ctrl.stats diff --git a/python/covertable/evaluate.py b/python/covertable/evaluate.py index 7bfbbde..c381c53 100644 --- a/python/covertable/evaluate.py +++ b/python/covertable/evaluate.py @@ -3,17 +3,24 @@ Condition types (plain dicts with an ``operator`` key): Comparison: - {"operator": "eq"|"ne"|"gt"|"lt"|"gte"|"lte", "field": str, "value": any} - {"operator": "eq"|"ne"|"gt"|"lt"|"gte"|"lte", "field": str, "target": str} - {"operator": "in", "field": str, "values": list} + {"operator": "eq"|"ne"|"gt"|"lt"|"gte"|"lte", "left": Operand, "value": any} + {"operator": "eq"|"ne"|"gt"|"lt"|"gte"|"lte", "left": Operand, "right": Operand} + {"operator": "in", "left": Operand, "values": list} Logical: {"operator": "not", "condition": Condition} {"operator": "and", "conditions": [Condition, ...]} {"operator": "or", "conditions": [Condition, ...]} -Custom (escape hatch): - {"operator": "custom", "keys": [str, ...], "evaluate": callable(row)->bool} +Arithmetic (used as Operand, not as top-level Condition): + {"operator": "add"|"sub"|"mul"|"div"|"mod", "left": Operand, "right": Operand} + {"operator": "add"|"sub"|"mul"|"div"|"mod", "left": Operand, "value": any} + +Function (escape hatch): + {"operator": "fn", "requires": [str, ...], "evaluate": callable(row)->bool} + +An Operand is either a string (field reference, dot notation supported) or +an arithmetic expression dict. ``evaluate()`` returns ``True``, ``False``, or ``None`` (unknown/deferred). """ @@ -30,6 +37,15 @@ "in": lambda value, values: value in values, } +_ARITHMETIC_OPS = { + "add": lambda a, b: a + b, + "sub": lambda a, b: a - b, + "mul": lambda a, b: a * b, + "div": lambda a, b: a / b, + "mod": lambda a, b: a % b, + "pow": lambda a, b: a ** b, +} + def resolve(row, field): """Resolve a field path against a row dict. @@ -50,6 +66,40 @@ def resolve(row, field): return current +def resolve_operand(row, operand): + """Resolve an operand (field reference or arithmetic expression). + + Returns ``_SENTINEL`` if any referenced field is missing. + """ + if isinstance(operand, (str, int)): + return resolve(row, operand) + # Arithmetic expression dict + left = resolve_operand(row, operand["left"]) + if left is _SENTINEL: + return _SENTINEL + if "right" in operand: + right = resolve_operand(row, operand["right"]) + else: + right = operand["value"] + if right is _SENTINEL: + return _SENTINEL + fn = _ARITHMETIC_OPS[operand["operator"]] + return fn(left, right) + + +def _extract_operand_keys(operand): + """Extract top-level factor keys from an operand.""" + if isinstance(operand, str): + return {operand.split(".")[0]} + if isinstance(operand, int): + return {operand} + # Arithmetic expression + keys = _extract_operand_keys(operand["left"]) + if "right" in operand: + keys.update(_extract_operand_keys(operand["right"])) + return keys + + def extract_keys(condition): """Return the set of top-level factor keys a condition depends on.""" op = condition["operator"] @@ -60,13 +110,13 @@ def extract_keys(condition): for sub in condition["conditions"]: keys.update(extract_keys(sub)) return keys - if op == "custom": - return set(condition["keys"]) + if op == "fn": + return set(condition["requires"]) # comparison / in - keys = {condition["field"].split(".")[0]} - target = condition.get("target") - if isinstance(target, str): - keys.add(target.split(".")[0]) + keys = _extract_operand_keys(condition["left"]) + right = condition.get("right") + if right is not None: + keys.update(_extract_operand_keys(right)) return keys @@ -107,28 +157,28 @@ def evaluate(condition, row, comparer=None): return None if has_unknown else False # -- custom -- - if op == "custom": - for k in condition["keys"]: + if op == "fn": + for k in condition["requires"]: if resolve(row, k) is _SENTINEL: return None return condition["evaluate"](row) # -- in -- if op == "in": - v = resolve(row, condition["field"]) + v = resolve_operand(row, condition["left"]) if v is _SENTINEL: return None fn = comparer.get("in", DEFAULT_COMPARER["in"]) return fn(v, condition["values"]) # -- comparison -- - v = resolve(row, condition["field"]) + v = resolve_operand(row, condition["left"]) if v is _SENTINEL: return None - target = condition.get("target") - if target is not None: - t = resolve(row, target) + right = condition.get("right") + if right is not None: + t = resolve_operand(row, right) if t is _SENTINEL: return None else: diff --git a/python/covertable/main.py b/python/covertable/main.py index a3a09e8..9d7396d 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -105,7 +105,7 @@ def _serialize(self, factors): def _set_incomplete(self): pairs = [] all_keys = [k for k, _ in get_items(self.serials)] - sub_model_key_sets = [set(sm["keys"]) for sm in self.sub_models] + sub_model_key_sets = [set(sm["fields"]) for sm in self.sub_models] def is_within_sub_model(keys): return any(all(k in ks for k in keys) for ks in sub_model_key_sets) @@ -118,7 +118,7 @@ def is_within_sub_model(keys): pairs.append(tuple(sorted(pair))) for sm in self.sub_models: - for keys in combinations(sm["keys"], sm["strength"]): + for keys in combinations(sm["fields"], sm["strength"]): comb = [self.serials[keys[i]] for i in range(sm["strength"])] for pair in product(*comb): pairs.append(tuple(sorted(pair))) diff --git a/python/covertable/pict/lexer.py b/python/covertable/pict/lexer.py index d29a3d3..3dd9828 100644 --- a/python/covertable/pict/lexer.py +++ b/python/covertable/pict/lexer.py @@ -21,6 +21,7 @@ _COLON = "COLON" _SEMICOLON = "SEMICOLON" _WHITESPACE = "WHITESPACE" +_ARITHMETIC = "ARITHMETIC" _UNKNOWN = "UNKNOWN" @@ -59,6 +60,10 @@ def _classify_token(token): return {"type": _COLON, "value": token} if token == ";": return {"type": _SEMICOLON, "value": token} + if token in ("+", "-", "*", "/", "%", "^"): + return {"type": _ARITHMETIC, "value": token} + if token == "**": + return {"type": _ARITHMETIC, "value": "^"} return {"type": _UNKNOWN, "value": token} @@ -138,6 +143,15 @@ def _tokenize(self): tokens.append(_classify_token(buffer)) buffer = "" tokens.append({"type": _COMMA, "value": ch}) + elif ch in "+-*/%^" and not inside_braces and not inside_brackets: + if buffer: + tokens.append(_classify_token(buffer)) + buffer = "" + if ch == "*" and i + 1 < n and constraints[i + 1] == "*": + tokens.append(_classify_token("**")) + i += 1 + else: + tokens.append(_classify_token(ch)) elif ch in "[]=<>!();:" and not inside_braces and not inside_brackets: if buffer: tokens.append(_classify_token(buffer)) @@ -230,6 +244,33 @@ def parse_term(): idx[0] -= 1 return left + def _is_logical_paren(): + """Peek ahead to determine if '(' starts a logical group or an arithmetic operand. + + A logical group contains a comparison operator (=, <>, >, <, >=, <=, IN, LIKE) + at the top level (not nested in deeper parens). If we only see arithmetic + operators and operands before the matching ')', it's arithmetic. + """ + saved = idx[0] + depth = 1 + found_comparer = False + while idx[0] < len(tokens): + t = tokens[idx[0]] + idx[0] += 1 + if t["type"] == _WHITESPACE: + continue + if t["type"] == _LPAREN: + depth += 1 + elif t["type"] == _RPAREN: + depth -= 1 + if depth == 0: + break + elif depth == 1 and t["type"] == _COMPARER: + found_comparer = True + break + idx[0] = saved + return found_comparer + def parse_factor(): tok = next_token() if tok is not None: @@ -237,11 +278,17 @@ def parse_factor(): operand = parse_factor() return lambda row: not operand(row) if tok["type"] == _LPAREN: - expr = parse_expression() - tok = next_token() - if not tok or tok["type"] != _RPAREN: - raise ValueError("Expected closing parenthesis") - return expr + if _is_logical_paren(): + # Logical grouping: (condition AND/OR condition) + expr = parse_expression() + tok = next_token() + if not tok or tok["type"] != _RPAREN: + raise ValueError("Expected closing parenthesis") + return expr + else: + # Arithmetic parentheses — let parse_condition handle it + idx[0] -= 1 + return parse_condition() if tok["type"] == _BOOLEAN: val = tok["value"].upper() == "TRUE" return lambda row: val @@ -326,10 +373,28 @@ def parse_set(): raise ValueError("Empty set in IN clause") return set(elements) - def parse_operand(): + _arith_ops = { + "+": lambda a, b: a + b, + "-": lambda a, b: a - b, + "*": lambda a, b: a * b, + "/": lambda a, b: a / b, + "%": lambda a, b: a % b, + "^": lambda a, b: a ** b, + } + + def parse_primary_operand(): tok = next_token() if tok is None: return None + if tok["type"] == _LPAREN: + # Parenthesized arithmetic expression + inner = parse_operand() + if inner is None: + raise ValueError('Expected expression after "("') + close_paren = next_token() + if not close_paren or close_paren["type"] != _RPAREN: + raise ValueError('Expected closing ")" in arithmetic expression') + return inner if tok["type"] == _REF: key = tok["value"][1:-1] current_keys[0].add(key) @@ -351,6 +416,60 @@ def parse_operand(): return lambda row: None return None + # Power: ^ or ** (highest arithmetic precedence, right-associative) + def parse_pow_operand(): + left = parse_primary_operand() + if left is None: + return None + saved = idx[0] + tok = next_token() + if tok and tok["type"] == _ARITHMETIC and tok["value"] == "^": + right = parse_pow_operand() # right-associative + if right is None: + raise ValueError("Expected operand after '^'") + left = (lambda l, r: lambda row: l(row) ** r(row))(left, right) + else: + idx[0] = saved + return left + + # Multiplicative: *, /, % + def parse_mul_operand(): + left = parse_pow_operand() + if left is None: + return None + while True: + saved = idx[0] + tok = next_token() + if tok and tok["type"] == _ARITHMETIC and tok["value"] in "*/%": + fn = _arith_ops[tok["value"]] + right = parse_pow_operand() + if right is None: + raise ValueError("Expected operand after '{}'".format(tok["value"])) + left = (lambda l, r, fn: lambda row: fn(l(row), r(row)))(left, right, fn) + else: + idx[0] = saved + break + return left + + # Additive: +, - (lower precedence) + def parse_operand(): + left = parse_mul_operand() + if left is None: + return None + while True: + saved = idx[0] + tok = next_token() + if tok and tok["type"] == _ARITHMETIC and tok["value"] in "+-": + fn = _arith_ops[tok["value"]] + right = parse_mul_operand() + if right is None: + raise ValueError("Expected operand after '{}'".format(tok["value"])) + left = (lambda l, r, fn: lambda row: fn(l(row), r(row)))(left, right, fn) + else: + idx[0] = saved + break + return left + def abandon(): while idx[0] < len(tokens) and tokens[idx[0]]["type"] != _SEMICOLON: idx[0] += 1 diff --git a/python/covertable/pict/model.py b/python/covertable/pict/model.py index f4a8d79..2aa4b96 100644 --- a/python/covertable/pict/model.py +++ b/python/covertable/pict/model.py @@ -159,8 +159,8 @@ def _model_constraints(self): if f is None: continue result.append({ - "operator": "custom", - "keys": list(filter_keys[i]), + "operator": "fn", + "requires": list(filter_keys[i]), "evaluate": f, }) @@ -179,8 +179,8 @@ def eval_negatives(row): return True result.append({ - "operator": "custom", - "keys": negative_keys, + "operator": "fn", + "requires": negative_keys, "evaluate": eval_negatives, }) diff --git a/python/covertable/pict/parser.py b/python/covertable/pict/parser.py index 217f02f..6d771e8 100644 --- a/python/covertable/pict/parser.py +++ b/python/covertable/pict/parser.py @@ -172,4 +172,4 @@ def parse_sub_model(line): return None keys = [k.strip() for k in match.group(1).split(",") if k.strip()] strength = int(match.group(2)) - return {"keys": keys, "strength": strength} + return {"fields": keys, "strength": strength} diff --git a/python/covertable/shortcuts.py b/python/covertable/shortcuts.py new file mode 100644 index 0000000..531fb5c --- /dev/null +++ b/python/covertable/shortcuts.py @@ -0,0 +1,153 @@ +"""Constraint builder with ``$``-prefixed field references. + +Usage:: + + from covertable.shortcuts import Constraint + + c = Constraint() + + make(factors, constraints=[ + c.ne("$A", "$B"), + c.eq("$OS", "Mac"), + c.gt(c.mul("$Price", "$Qty"), 10000), + c.lte(c.sum("$A", "$B", "$C"), 100), + c.or_(c.eq("$OS", "Mac"), c.ne("$Browser", "Safari")), + c.fn(["OS", "Browser"], lambda row: row["OS"] != row["Browser"]), + ]) +""" + + +class _Val: + """Wrapper to force a value to be treated as a literal.""" + __slots__ = ("value",) + + def __init__(self, value): + self.value = value + + +def _resolve(x): + """Resolve a shortcut operand. + + - ``$name`` → field reference (string without ``$``) + - ``dict`` with ``operator`` → arithmetic expression (pass through) + - ``_Val`` wrapper → forced literal + - anything else → literal value + """ + if isinstance(x, _Val): + return ("value", x.value) + if isinstance(x, dict) and "operator" in x: + return ("operand", x) + if isinstance(x, str) and x.startswith("$"): + return ("operand", x[1:]) + return ("value", x) + + +def _build_comparison(operator, left, right): + tag_l, val_l = _resolve(left) + left_op = val_l # left is always an operand + tag_r, val_r = _resolve(right) + if tag_r == "operand": + return {"operator": operator, "left": left_op, "right": val_r} + return {"operator": operator, "left": left_op, "value": val_r} + + +def _build_arithmetic(operator, left, right): + tag_l, val_l = _resolve(left) + left_op = val_l + tag_r, val_r = _resolve(right) + if tag_r == "operand": + return {"operator": operator, "left": left_op, "right": val_r} + return {"operator": operator, "left": left_op, "value": val_r} + + +def _fold_arithmetic(operator, args): + acc = _build_arithmetic(operator, args[0], args[1]) + for i in range(2, len(args)): + tag, val = _resolve(args[i]) + if tag == "operand": + acc = {"operator": operator, "left": acc, "right": val} + else: + acc = {"operator": operator, "left": acc, "value": val} + return acc + + +class Constraint: + """Constraint builder with ``$``-prefixed field references.""" + + # -- comparison -- + + def eq(self, left, right): + return _build_comparison("eq", left, right) + + def ne(self, left, right): + return _build_comparison("ne", left, right) + + def gt(self, left, right): + return _build_comparison("gt", left, right) + + def lt(self, left, right): + return _build_comparison("lt", left, right) + + def gte(self, left, right): + return _build_comparison("gte", left, right) + + def lte(self, left, right): + return _build_comparison("lte", left, right) + + def in_(self, left, values): + tag, val = _resolve(left) + return {"operator": "in", "left": val, "values": values} + + # -- logical -- + + def and_(self, *conditions): + return {"operator": "and", "conditions": list(conditions)} + + def or_(self, *conditions): + return {"operator": "or", "conditions": list(conditions)} + + def not_(self, condition): + return {"operator": "not", "condition": condition} + + # -- binary arithmetic -- + + def add(self, left, right): + return _build_arithmetic("add", left, right) + + def sub(self, left, right): + return _build_arithmetic("sub", left, right) + + def mul(self, left, right): + return _build_arithmetic("mul", left, right) + + def div(self, left, right): + return _build_arithmetic("div", left, right) + + def mod(self, left, right): + return _build_arithmetic("mod", left, right) + + def pow(self, left, right): + return _build_arithmetic("pow", left, right) + + # -- variadic arithmetic -- + + def sum(self, *args): + if len(args) < 2: + raise ValueError("sum() requires at least 2 arguments") + return _fold_arithmetic("add", args) + + def product(self, *args): + if len(args) < 2: + raise ValueError("product() requires at least 2 arguments") + return _fold_arithmetic("mul", args) + + # -- custom -- + + def fn(self, requires, evaluate): + return {"operator": "fn", "requires": requires, "evaluate": evaluate} + + # -- literal -- + + def val(self, value): + """Wrap a value to force it to be treated as a literal, not a field reference.""" + return _Val(value) diff --git a/python/pytest.ini b/python/pytest.ini index b42ddf9..db9bb70 100644 --- a/python/pytest.ini +++ b/python/pytest.ini @@ -1,3 +1,3 @@ [pytest] -python_files = tests.py +python_files = tests.py test_pict.py diff --git a/python/test_pict.py b/python/test_pict.py index ddcf997..d9789aa 100644 --- a/python/test_pict.py +++ b/python/test_pict.py @@ -225,7 +225,7 @@ def test_parses_sub_model_definition(self): { A, B, C } @ 3 """) - assert model.sub_models == [{"keys": ["A", "B", "C"], "strength": 3}] + assert model.sub_models == [{"fields": ["A", "B", "C"], "strength": 3}] assert model.errors == [] def test_sub_model_increases_coverage(self): @@ -389,7 +389,7 @@ def test_user_constraints_combine_with_model_constraints(self): Browser: Chrome, Safari """) rows = model.make(constraints=[ - {"operator": "ne", "field": "OS", "value": "iOS"}, + {"operator": "ne", "left": "OS", "value": "iOS"}, ]) for row in rows: assert row["OS"] != "iOS" diff --git a/python/tests.py b/python/tests.py index af02b36..dc3d577 100644 --- a/python/tests.py +++ b/python/tests.py @@ -60,9 +60,9 @@ def test_constraints_exclude_specified_pairs(self): factors, strength=2, constraints=[ - {"operator": "custom", "keys": [0, 1], "evaluate": + {"operator": "fn", "requires": [0, 1], "evaluate": lambda row: not (row[0] == "a" and row[1] == "d")}, - {"operator": "custom", "keys": [0, 1], "evaluate": + {"operator": "fn", "requires": [0, 1], "evaluate": lambda row: not (row[0] == "b" and row[1] == "e")}, ], ) @@ -78,7 +78,7 @@ def test_constraints_never_matching_makes_no_rows(self): factors, strength=2, constraints=[ - {"operator": "custom", "keys": [2], "evaluate": + {"operator": "fn", "requires": [2], "evaluate": lambda row: row[2] != "f"}, ], ) @@ -166,7 +166,7 @@ def test_presets_violating_constraint_are_dropped(self): rows = make( factors, constraints=[ - {"operator": "custom", "keys": ["OS", "Browser"], "evaluate": + {"operator": "fn", "requires": ["OS", "Browser"], "evaluate": lambda row: not (row["OS"] == "iOS" and row["Browser"] == "Chrome")}, ], presets=[ @@ -210,3 +210,88 @@ def test_dict_type_factors_make_dict_row(self): rows = call(factors, strength=2) for row in rows: assert sorted(row.keys()) == sorted(factors.keys()) + + +class Test_custom_condition: + def test_evaluate_returns_result_when_all_fields_present(self): + from covertable.evaluate import evaluate + cond = {"operator": "fn", "requires": ["A", "B"], + "evaluate": lambda row: row["A"] + row["B"] > 5} + assert evaluate(cond, {"A": 3, "B": 4}) is True + assert evaluate(cond, {"A": 1, "B": 2}) is False + + def test_evaluate_returns_none_when_field_missing(self): + from covertable.evaluate import evaluate + cond = {"operator": "fn", "requires": ["A", "B"], + "evaluate": lambda row: row["A"] != row["B"]} + assert evaluate(cond, {"A": 1}) is None + assert evaluate(cond, {}) is None + + def test_evaluate_returns_none_when_partial_fields(self): + from covertable.evaluate import evaluate + cond = {"operator": "fn", "requires": ["X", "Y", "Z"], + "evaluate": lambda row: row["X"] + row["Y"] + row["Z"] == 6} + assert evaluate(cond, {"X": 1, "Y": 2}) is None + + def test_evaluate_with_empty_fields(self): + from covertable.evaluate import evaluate + cond = {"operator": "fn", "requires": [], "evaluate": lambda row: True} + assert evaluate(cond, {}) is True + + def test_extract_keys_from_custom(self): + from covertable.evaluate import extract_keys + cond = {"operator": "fn", "requires": ["OS", "Browser", "Device"], + "evaluate": lambda row: True} + assert extract_keys(cond) == {"OS", "Browser", "Device"} + + def test_make_with_custom_constraint(self): + from covertable import make + rows = make( + {"A": [1, 2, 3], "B": [10, 20, 30]}, + constraints=[{"operator": "fn", "requires": ["A", "B"], + "evaluate": lambda row: row["A"] * 10 == row["B"]}], + ) + for row in rows: + assert row["A"] * 10 == row["B"] + + def test_custom_prunes_infeasible_pairs(self): + from covertable import make + rows = make( + {"X": ["a", "b"], "Y": ["c", "d"], "Z": ["e", "f"]}, + constraints=[{"operator": "fn", "requires": ["X", "Y"], + "evaluate": lambda row: not (row["X"] == "a" and row["Y"] == "c")}], + ) + for row in rows: + assert not (row["X"] == "a" and row["Y"] == "c") + + def test_custom_alongside_declarative(self): + from covertable import make + rows = make( + {"OS": ["Win", "Mac", "Linux"], "Browser": ["Chrome", "Firefox", "Safari"], "Lang": ["en", "ja"]}, + constraints=[ + {"operator": "or", "conditions": [ + {"operator": "ne", "left": "Browser", "value": "Safari"}, + {"operator": "eq", "left": "OS", "value": "Mac"}, + ]}, + {"operator": "fn", "requires": ["Browser", "Lang"], + "evaluate": lambda row: row["Lang"] != "ja" or row["Browser"] == "Chrome"}, + ], + ) + for row in rows: + if row["Browser"] == "Safari": + assert row["OS"] == "Mac" + if row["Lang"] == "ja": + assert row["Browser"] == "Chrome" + + def test_custom_inside_logical_operator(self): + from covertable import make + rows = make( + {"A": [1, 2, 3], "B": [1, 2, 3]}, + constraints=[{"operator": "or", "conditions": [ + {"operator": "eq", "left": "A", "value": 1}, + {"operator": "fn", "requires": ["B"], + "evaluate": lambda row: row["B"] >= 2}, + ]}], + ) + for row in rows: + assert row["A"] == 1 or row["B"] >= 2 diff --git a/typescript/package.json b/typescript/package.json index e5e44b0..1ec8ef3 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -47,6 +47,11 @@ "types": "./dist/pict.d.ts", "import": "./dist/pict.js", "require": "./dist/pict.cjs" + }, + "./shortcuts": { + "types": "./dist/shortcuts.d.ts", + "import": "./dist/shortcuts.js", + "require": "./dist/shortcuts.cjs" } }, "files": [ diff --git a/typescript/src/__tests__/bench.test.ts b/typescript/src/__tests__/bench.test.ts index 04c4a79..f858560 100644 --- a/typescript/src/__tests__/bench.test.ts +++ b/typescript/src/__tests__/bench.test.ts @@ -79,16 +79,16 @@ describe('benchmarks', () => { const vals = [1, 2, 3, 4, 5]; const factors = { A: vals, B: vals, C: vals, D: vals, E: vals }; const constraints = [ - { operator: 'ne' as const, field: 'A', target: 'B' }, - { operator: 'ne' as const, field: 'A', target: 'C' }, - { operator: 'ne' as const, field: 'A', target: 'D' }, - { operator: 'ne' as const, field: 'A', target: 'E' }, - { operator: 'ne' as const, field: 'B', target: 'C' }, - { operator: 'ne' as const, field: 'B', target: 'D' }, - { operator: 'ne' as const, field: 'B', target: 'E' }, - { operator: 'ne' as const, field: 'C', target: 'D' }, - { operator: 'ne' as const, field: 'C', target: 'E' }, - { operator: 'ne' as const, field: 'D', target: 'E' }, + { operator: 'ne' as const, left: 'A', right: 'B' }, + { operator: 'ne' as const, left: 'A', right: 'C' }, + { operator: 'ne' as const, left: 'A', right: 'D' }, + { operator: 'ne' as const, left: 'A', right: 'E' }, + { operator: 'ne' as const, left: 'B', right: 'C' }, + { operator: 'ne' as const, left: 'B', right: 'D' }, + { operator: 'ne' as const, left: 'B', right: 'E' }, + { operator: 'ne' as const, left: 'C', right: 'D' }, + { operator: 'ne' as const, left: 'C', right: 'E' }, + { operator: 'ne' as const, left: 'D', right: 'E' }, ]; const result = bench('5x5 all-diff greedy', () => { const ctrl = new Controller(factors, { constraints, criterion: criteria.greedy }); diff --git a/typescript/src/__tests__/contradictory.test.ts b/typescript/src/__tests__/contradictory.test.ts index f115462..4a56b49 100644 --- a/typescript/src/__tests__/contradictory.test.ts +++ b/typescript/src/__tests__/contradictory.test.ts @@ -1,5 +1,5 @@ import { Controller } from '../controller'; -import type { Condition } from '../types'; +import type { Expression } from '../types'; describe('contradictory constraints', () => { @@ -15,39 +15,39 @@ describe('contradictory constraints', () => { D: [1000, 2000], E: ['x', 'y', 'z'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // A=1 → B∈{10,20} { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'in', field: 'B', values: [10, 20] }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'in', left: 'B', values: [10, 20] }, ]}, // B=10 → C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, // B=20 → C=200 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 20 }, - { operator: 'eq', field: 'C', value: 200 }, + { operator: 'ne', left: 'B', value: 20 }, + { operator: 'eq', left: 'C', value: 200 }, ]}, // B=10 AND C=100 → D=1000 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'ne', field: 'C', value: 100 }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'ne', left: 'C', value: 100 }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, // B=20 AND C=200 → D=1000 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 20 }, - { operator: 'ne', field: 'C', value: 200 }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'ne', left: 'B', value: 20 }, + { operator: 'ne', left: 'C', value: 200 }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, // So when A=1, D must be 1000. Pair (A=1, D=2000) is infeasible. // But also add: D=1000 → E='x' { operator: 'or', conditions: [ - { operator: 'ne', field: 'D', value: 1000 }, - { operator: 'eq', field: 'E', value: 'x' }, + { operator: 'ne', left: 'D', value: 1000 }, + { operator: 'eq', left: 'E', value: 'x' }, ]}, // Now (A=1, E='y') and (A=1, E='z') are also infeasible // because A=1 → B∈{10,20} → (B,C) forces D=1000 → E='x' diff --git a/typescript/src/__tests__/coverage-bench.test.ts b/typescript/src/__tests__/coverage-bench.test.ts index 9b0c427..029b36f 100644 --- a/typescript/src/__tests__/coverage-bench.test.ts +++ b/typescript/src/__tests__/coverage-bench.test.ts @@ -1,5 +1,5 @@ import { Controller } from '../controller'; -import type { Condition } from '../types'; +import type { Expression } from '../types'; describe('coverage benchmark', () => { it('constraint chain coverage', () => { @@ -14,38 +14,38 @@ describe('coverage benchmark', () => { Auth: ['OAuth', 'SAML', 'Password', 'MFA'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ { operator: 'or', conditions: [ - { operator: 'ne', field: 'Language', value: 'de' }, - { operator: 'eq', field: 'Region', value: 'EU' }, + { operator: 'ne', left: 'Language', value: 'de' }, + { operator: 'eq', left: 'Region', value: 'EU' }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Language', value: 'ja' }, - { operator: 'eq', field: 'Region', value: 'AP' }, + { operator: 'ne', left: 'Language', value: 'ja' }, + { operator: 'eq', left: 'Region', value: 'AP' }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Language', value: 'pt' }, - { operator: 'eq', field: 'Region', value: 'SA' }, + { operator: 'ne', left: 'Language', value: 'pt' }, + { operator: 'eq', left: 'Region', value: 'SA' }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Region', value: 'EU' }, - { operator: 'in', field: 'Currency', values: ['EUR', 'GBP'] }, + { operator: 'ne', left: 'Region', value: 'EU' }, + { operator: 'in', left: 'Currency', values: ['EUR', 'GBP'] }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Region', value: 'AP' }, - { operator: 'in', field: 'Currency', values: ['JPY', 'CNY', 'KRW'] }, + { operator: 'ne', left: 'Region', value: 'AP' }, + { operator: 'in', left: 'Currency', values: ['JPY', 'CNY', 'KRW'] }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Region', value: 'SA' }, - { operator: 'in', field: 'Currency', values: ['BRL'] }, + { operator: 'ne', left: 'Region', value: 'SA' }, + { operator: 'in', left: 'Currency', values: ['BRL'] }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'OS', value: 'iOS' }, - { operator: 'in', field: 'Browser', values: ['Safari', 'Chrome'] }, + { operator: 'ne', left: 'OS', value: 'iOS' }, + { operator: 'in', left: 'Browser', values: ['Safari', 'Chrome'] }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Screen', value: 'Mobile' }, - { operator: 'in', field: 'OS', values: ['iOS', 'Android'] }, + { operator: 'ne', left: 'Screen', value: 'Mobile' }, + { operator: 'in', left: 'OS', values: ['iOS', 'Android'] }, ]}, ]; diff --git a/typescript/src/__tests__/custom-condition.test.ts b/typescript/src/__tests__/custom-condition.test.ts new file mode 100644 index 0000000..837c261 --- /dev/null +++ b/typescript/src/__tests__/custom-condition.test.ts @@ -0,0 +1,145 @@ +import { make } from '../index'; +import { evaluate, extractKeys } from '../evaluate'; +import type { Expression } from '../types'; + +describe('CustomExpression', () => { + describe('evaluate()', () => { + it('returns the result of the evaluate function when all fields are present', () => { + const condition: Expression = { + operator: 'fn', + requires: ['A', 'B'], + evaluate: (row) => row.A + row.B > 5, + }; + expect(evaluate(condition, { A: 3, B: 4 })).toBe(true); + expect(evaluate(condition, { A: 1, B: 2 })).toBe(false); + }); + + it('returns null when a referenced field is missing', () => { + const condition: Expression = { + operator: 'fn', + requires: ['A', 'B'], + evaluate: (row) => row.A !== row.B, + }; + expect(evaluate(condition, { A: 1 })).toBeNull(); + expect(evaluate(condition, {})).toBeNull(); + }); + + it('returns null when only some fields are present', () => { + const condition: Expression = { + operator: 'fn', + requires: ['X', 'Y', 'Z'], + evaluate: (row) => row.X + row.Y + row.Z === 6, + }; + expect(evaluate(condition, { X: 1, Y: 2 })).toBeNull(); + }); + + it('works with empty fields array (always evaluates)', () => { + const condition: Expression = { + operator: 'fn', + requires: [], + evaluate: () => true, + }; + expect(evaluate(condition, {})).toBe(true); + }); + }); + + describe('extractKeys()', () => { + it('extracts fields from a custom condition', () => { + const condition: Expression = { + operator: 'fn', + requires: ['OS', 'Browser', 'Device'], + evaluate: () => true, + }; + expect(extractKeys(condition)).toEqual(new Set(['OS', 'Browser', 'Device'])); + }); + }); + + describe('make() with custom constraints', () => { + it('filters rows using a custom evaluate function', () => { + const factors = { + A: [1, 2, 3], + B: [10, 20, 30], + }; + const rows = make(factors, { + constraints: [{ + operator: 'fn', + requires: ['A', 'B'], + evaluate: (row) => row.A * 10 === row.B, + }], + }); + for (const row of rows) { + expect((row as any).A * 10).toBe((row as any).B); + } + }); + + it('prunes infeasible pairs during initial pruning', () => { + const factors = { + X: ['a', 'b'], + Y: ['c', 'd'], + Z: ['e', 'f'], + }; + const rows = make(factors, { + constraints: [{ + operator: 'fn', + requires: ['X', 'Y'], + evaluate: (row) => !(row.X === 'a' && row.Y === 'c'), + }], + }); + for (const row of rows) { + expect(!((row as any).X === 'a' && (row as any).Y === 'c')).toBe(true); + } + }); + + it('works alongside declarative conditions', () => { + const factors = { + OS: ['Win', 'Mac', 'Linux'], + Browser: ['Chrome', 'Firefox', 'Safari'], + Lang: ['en', 'ja'], + }; + const rows = make(factors, { + constraints: [ + // Safari only on Mac (declarative) + { operator: 'or', conditions: [ + { operator: 'ne', left: 'Browser', value: 'Safari' }, + { operator: 'eq', left: 'OS', value: 'Mac' }, + ]}, + // Custom: ja only with Chrome + { + operator: 'fn', + requires: ['Browser', 'Lang'], + evaluate: (row) => row.Lang !== 'ja' || row.Browser === 'Chrome', + }, + ], + }); + for (const row of rows) { + const r = row as any; + if (r.Browser === 'Safari') expect(r.OS).toBe('Mac'); + if (r.Lang === 'ja') expect(r.Browser).toBe('Chrome'); + } + }); + + it('custom condition inside logical operators', () => { + const factors = { + A: [1, 2, 3], + B: [1, 2, 3], + }; + const rows = make(factors, { + constraints: [{ + operator: 'or', + conditions: [ + { operator: 'eq', left: 'A', value: 1 }, + { + operator: 'fn', + requires: ['B'], + evaluate: (row) => row.B >= 2, + }, + ], + }], + }); + for (const row of rows) { + const r = row as any; + expect(r.A === 1 || r.B >= 2).toBe(true); + } + }); + }); +}); diff --git a/typescript/src/__tests__/filter.test.ts b/typescript/src/__tests__/filter.test.ts index e7d6f0a..0af61c7 100644 --- a/typescript/src/__tests__/filter.test.ts +++ b/typescript/src/__tests__/filter.test.ts @@ -10,12 +10,12 @@ test('exclude impossible combinations', () => { constraints: [ // machine=iPhone ↔ os=iOS (bidirectional) { operator: 'or', conditions: [ - { operator: 'ne', field: 'machine', value: 'iPhone' }, - { operator: 'eq', field: 'os', value: 'iOS' }, + { operator: 'ne', left: 'machine', value: 'iPhone' }, + { operator: 'eq', left: 'os', value: 'iOS' }, ]}, { operator: 'or', conditions: [ - { operator: 'eq', field: 'machine', value: 'iPhone' }, - { operator: 'ne', field: 'os', value: 'iOS' }, + { operator: 'eq', left: 'machine', value: 'iPhone' }, + { operator: 'ne', left: 'os', value: 'iOS' }, ]}, ], }); @@ -45,8 +45,8 @@ test('Limited to iphone and iOS combinations only.', () => { const factors = {machine, os, browser}; const rows = make(factors, { constraints: [ - { operator: 'eq', field: 'machine', value: 'iPhone' }, - { operator: 'eq', field: 'os', value: 'iOS' }, + { operator: 'eq', left: 'machine', value: 'iPhone' }, + { operator: 'eq', left: 'os', value: 'iOS' }, ], }); expect(rows.length).toBe(browser.length); @@ -61,7 +61,7 @@ test('Use a constant-false constraint', () => { const rows = make(factors, { constraints: [ // No machine value equals 'WindowsPhone', so this rejects everything - { operator: 'eq', field: 'machine', value: 'WindowsPhone' }, + { operator: 'eq', left: 'machine', value: 'WindowsPhone' }, ], }); expect(rows).toEqual([]); diff --git a/typescript/src/__tests__/forward-check-complex.test.ts b/typescript/src/__tests__/forward-check-complex.test.ts index bfcd78c..da9fdc4 100644 --- a/typescript/src/__tests__/forward-check-complex.test.ts +++ b/typescript/src/__tests__/forward-check-complex.test.ts @@ -1,5 +1,5 @@ import { Controller } from '../controller'; -import type { Condition } from '../types'; +import type { Expression } from '../types'; describe('forward check complex cases', () => { @@ -16,31 +16,31 @@ describe('forward check complex cases', () => { F: ['X', 'Y', 'Z'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // A=1 → B∈{10,20} { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'in', field: 'B', values: [10, 20] }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'in', left: 'B', values: [10, 20] }, ]}, // B∈{10,20} → C∈{100,200} { operator: 'or', conditions: [ - { operator: 'in', field: 'B', values: [30] }, - { operator: 'in', field: 'C', values: [100, 200] }, + { operator: 'in', left: 'B', values: [30] }, + { operator: 'in', left: 'C', values: [100, 200] }, ]}, // C∈{100,200} → D=1000 { operator: 'or', conditions: [ - { operator: 'in', field: 'C', values: [300] }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'in', left: 'C', values: [300] }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, // D=1000 → E∈{α,β} { operator: 'or', conditions: [ - { operator: 'ne', field: 'D', value: 1000 }, - { operator: 'in', field: 'E', values: ['α', 'β'] }, + { operator: 'ne', left: 'D', value: 1000 }, + { operator: 'in', left: 'E', values: ['α', 'β'] }, ]}, // E∈{α,β} → F=X { operator: 'or', conditions: [ - { operator: 'in', field: 'E', values: ['γ'] }, - { operator: 'eq', field: 'F', value: 'X' }, + { operator: 'in', left: 'E', values: ['γ'] }, + { operator: 'eq', left: 'F', value: 'X' }, ]}, ]; @@ -77,26 +77,26 @@ describe('forward check complex cases', () => { E: ['X', 'Y', 'Z'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // A=1 → B=10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, // B=10 → C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, // D=α → B=20 { operator: 'or', conditions: [ - { operator: 'ne', field: 'D', value: 'α' }, - { operator: 'eq', field: 'B', value: 20 }, + { operator: 'ne', left: 'D', value: 'α' }, + { operator: 'eq', left: 'B', value: 20 }, ]}, // B=20 → E=X { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 20 }, - { operator: 'eq', field: 'E', value: 'X' }, + { operator: 'ne', left: 'B', value: 20 }, + { operator: 'eq', left: 'E', value: 'X' }, ]}, ]; @@ -127,13 +127,13 @@ describe('forward check complex cases', () => { const vals = [1, 2, 3, 4]; const factors = { A: vals, B: vals, C: vals, D: vals }; - const constraints: Condition[] = [ - { operator: 'ne', field: 'A', target: 'B' }, - { operator: 'ne', field: 'A', target: 'C' }, - { operator: 'ne', field: 'A', target: 'D' }, - { operator: 'ne', field: 'B', target: 'C' }, - { operator: 'ne', field: 'B', target: 'D' }, - { operator: 'ne', field: 'C', target: 'D' }, + const constraints: Expression[] = [ + { operator: 'ne', left: 'A', right: 'B' }, + { operator: 'ne', left: 'A', right: 'C' }, + { operator: 'ne', left: 'A', right: 'D' }, + { operator: 'ne', left: 'B', right: 'C' }, + { operator: 'ne', left: 'B', right: 'D' }, + { operator: 'ne', left: 'C', right: 'D' }, ]; const ctrl = new Controller(factors, { constraints }); @@ -165,26 +165,26 @@ describe('forward check complex cases', () => { E: ['p', 'q'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // A=1 → B=10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, // B=10 → A=1 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'A', value: 1 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'A', value: 1 }, ]}, // B=10 → C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, // C=100 → B=10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'C', value: 100 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'C', value: 100 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, ]; @@ -219,21 +219,21 @@ describe('forward check complex cases', () => { E: [1, 2, 3, 4, 5], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // A excludes its own value from B - { operator: 'ne', field: 'A', target: 'B' }, + { operator: 'ne', left: 'A', right: 'B' }, // B excludes its own value from C - { operator: 'ne', field: 'B', target: 'C' }, + { operator: 'ne', left: 'B', right: 'C' }, // C excludes its own value from D - { operator: 'ne', field: 'C', target: 'D' }, + { operator: 'ne', left: 'C', right: 'D' }, // D excludes its own value from E - { operator: 'ne', field: 'D', target: 'E' }, + { operator: 'ne', left: 'D', right: 'E' }, // Additionally: A value also can't equal C (skip one) - { operator: 'ne', field: 'A', target: 'C' }, + { operator: 'ne', left: 'A', right: 'C' }, // B value also can't equal D - { operator: 'ne', field: 'B', target: 'D' }, + { operator: 'ne', left: 'B', right: 'D' }, // C value also can't equal E - { operator: 'ne', field: 'C', target: 'E' }, + { operator: 'ne', left: 'C', right: 'E' }, ]; const ctrl = new Controller(factors, { constraints }); @@ -269,38 +269,38 @@ describe('forward check complex cases', () => { Approval: ['none', 'lead', 'director'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // Assignee != Reviewer - { operator: 'ne', field: 'Assignee', target: 'Reviewer' }, + { operator: 'ne', left: 'Assignee', right: 'Reviewer' }, // critical → prod { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'critical' }, - { operator: 'eq', field: 'Environment', value: 'prod' }, + { operator: 'ne', left: 'Priority', value: 'critical' }, + { operator: 'eq', left: 'Environment', value: 'prod' }, ]}, // prod → director approval { operator: 'or', conditions: [ - { operator: 'ne', field: 'Environment', value: 'prod' }, - { operator: 'eq', field: 'Approval', value: 'director' }, + { operator: 'ne', left: 'Environment', value: 'prod' }, + { operator: 'eq', left: 'Approval', value: 'director' }, ]}, // high → staging or prod { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'high' }, - { operator: 'in', field: 'Environment', values: ['staging', 'prod'] }, + { operator: 'ne', left: 'Priority', value: 'high' }, + { operator: 'in', left: 'Environment', values: ['staging', 'prod'] }, ]}, // staging → lead or director approval { operator: 'or', conditions: [ - { operator: 'ne', field: 'Environment', value: 'staging' }, - { operator: 'in', field: 'Approval', values: ['lead', 'director'] }, + { operator: 'ne', left: 'Environment', value: 'staging' }, + { operator: 'in', left: 'Approval', values: ['lead', 'director'] }, ]}, // low → no approval needed { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'low' }, - { operator: 'eq', field: 'Approval', value: 'none' }, + { operator: 'ne', left: 'Priority', value: 'low' }, + { operator: 'eq', left: 'Approval', value: 'none' }, ]}, // low → dev only { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'low' }, - { operator: 'eq', field: 'Environment', value: 'dev' }, + { operator: 'ne', left: 'Priority', value: 'low' }, + { operator: 'eq', left: 'Environment', value: 'dev' }, ]}, ]; diff --git a/typescript/src/__tests__/forward-check-weakness.test.ts b/typescript/src/__tests__/forward-check-weakness.test.ts index b2c35c3..dd683fb 100644 --- a/typescript/src/__tests__/forward-check-weakness.test.ts +++ b/typescript/src/__tests__/forward-check-weakness.test.ts @@ -1,5 +1,5 @@ import { make, Controller, NeverMatch } from '../index'; -import type { Condition } from '../types'; +import type { Expression } from '../types'; describe('forward check weakness cases', () => { @@ -14,21 +14,21 @@ describe('forward check weakness cases', () => { C: [100, 200, 300], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 THEN B IN {10, 20} { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'in', field: 'B', values: [10, 20] }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'in', left: 'B', values: [10, 20] }, ]}, // IF B=10 THEN C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, // IF B=20 THEN C=200 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 20 }, - { operator: 'eq', field: 'C', value: 200 }, + { operator: 'ne', left: 'B', value: 20 }, + { operator: 'eq', left: 'C', value: 200 }, ]}, ]; @@ -70,12 +70,12 @@ describe('forward check weakness cases', () => { C: [100, 200], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 AND B=10 THEN C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, ]; @@ -110,22 +110,22 @@ describe('forward check weakness cases', () => { D: [1000, 2000], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 THEN B=10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, // IF A=1 THEN C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, // IF B=10 AND C=100 THEN D=1000 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'ne', field: 'C', value: 100 }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'ne', left: 'C', value: 100 }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, ]; @@ -160,16 +160,16 @@ describe('forward check weakness cases', () => { C: [100, 200], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 THEN B<>10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'ne', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'ne', left: 'B', value: 10 }, ]}, // IF A=1 THEN B<>20 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'ne', field: 'B', value: 20 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'ne', left: 'B', value: 20 }, ]}, ]; @@ -201,21 +201,21 @@ describe('forward check weakness cases', () => { D: [1000, 2000], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 THEN B IN {10, 20} { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'in', field: 'B', values: [10, 20] }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'in', left: 'B', values: [10, 20] }, ]}, // IF B IN {10, 20} THEN C IN {100, 200} { operator: 'or', conditions: [ - { operator: 'in', field: 'B', values: [30] }, - { operator: 'in', field: 'C', values: [100, 200] }, + { operator: 'in', left: 'B', values: [30] }, + { operator: 'in', left: 'C', values: [100, 200] }, ]}, // IF C IN {100, 200} THEN D=1000 { operator: 'or', conditions: [ - { operator: 'in', field: 'C', values: [300] }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'in', left: 'C', values: [300] }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, ]; diff --git a/typescript/src/__tests__/forward-check.test.ts b/typescript/src/__tests__/forward-check.test.ts index 970ac68..78c5abc 100644 --- a/typescript/src/__tests__/forward-check.test.ts +++ b/typescript/src/__tests__/forward-check.test.ts @@ -1,5 +1,5 @@ import { make } from '../index'; -import type { Condition } from '../types'; +import type { Expression } from '../types'; describe('forward checking (constraint chain propagation)', () => { it('respects transitive constraint chain: Language=de → Region=EU → Currency∈{EUR,GBP}', () => { @@ -11,16 +11,16 @@ describe('forward checking (constraint chain propagation)', () => { Browser: ['Chrome', 'Firefox', 'Safari', 'Edge'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF Language=de THEN Region=EU { operator: 'or', conditions: [ - { operator: 'ne', field: 'Language', value: 'de' }, - { operator: 'eq', field: 'Region', value: 'EU' }, + { operator: 'ne', left: 'Language', value: 'de' }, + { operator: 'eq', left: 'Region', value: 'EU' }, ]}, // IF Region=EU THEN Currency IN {EUR, GBP} { operator: 'or', conditions: [ - { operator: 'ne', field: 'Region', value: 'EU' }, - { operator: 'in', field: 'Currency', values: ['EUR', 'GBP'] }, + { operator: 'ne', left: 'Region', value: 'EU' }, + { operator: 'in', left: 'Currency', values: ['EUR', 'GBP'] }, ]}, ]; @@ -46,21 +46,21 @@ describe('forward checking (constraint chain propagation)', () => { D: [1000, 2000, 3000], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 THEN B=10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, // IF B=10 THEN C=100 { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, // IF C=100 THEN D=1000 { operator: 'or', conditions: [ - { operator: 'ne', field: 'C', value: 100 }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'ne', left: 'C', value: 100 }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, ]; @@ -81,11 +81,11 @@ describe('forward checking (constraint chain propagation)', () => { C: [100, 200], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ // IF A=1 THEN B=10 { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, ]; diff --git a/typescript/src/__tests__/index.test.ts b/typescript/src/__tests__/index.test.ts index 7caeae2..6ca60bb 100644 --- a/typescript/src/__tests__/index.test.ts +++ b/typescript/src/__tests__/index.test.ts @@ -73,13 +73,13 @@ test('constraints exclude specified pairs before', () => { constraints: [ // NOT (0="a" AND 1="d") { operator: 'not', condition: { operator: 'and', conditions: [ - { operator: 'eq', field: '0', value: 'a' }, - { operator: 'eq', field: '1', value: 'd' }, + { operator: 'eq', left: '0', value: 'a' }, + { operator: 'eq', left: '1', value: 'd' }, ]}}, // NOT (0="b" AND 1="e") { operator: 'not', condition: { operator: 'and', conditions: [ - { operator: 'eq', field: '0', value: 'b' }, - { operator: 'eq', field: '1', value: 'e' }, + { operator: 'eq', left: '0', value: 'b' }, + { operator: 'eq', left: '1', value: 'e' }, ]}}, ], }); @@ -189,8 +189,8 @@ test('presets violating constraints are silently dropped', () => { constraints: [ // NOT (OS=iOS AND Browser=Chrome) { operator: 'not' as const, condition: { operator: 'and' as const, conditions: [ - { operator: 'eq' as const, field: 'OS', value: 'iOS' }, - { operator: 'eq' as const, field: 'Browser', value: 'Chrome' }, + { operator: 'eq' as const, left: 'OS', value: 'iOS' }, + { operator: 'eq' as const, left: 'Browser', value: 'Chrome' }, ]}}, ], presets: [ diff --git a/typescript/src/__tests__/pict.test.ts b/typescript/src/__tests__/pict.test.ts index c15dfb1..9e2ee1d 100644 --- a/typescript/src/__tests__/pict.test.ts +++ b/typescript/src/__tests__/pict.test.ts @@ -539,7 +539,7 @@ C: 7, 8, 9 { A, B, C } @ 3 `); - expect(model.subModels).toEqual([{ keys: ['A', 'B', 'C'], strength: 3 }]); + expect(model.subModels).toEqual([{ fields: ['A', 'B', 'C'], strength: 3 }]); expect(errorMessages(model)).toEqual([]); }); @@ -610,7 +610,7 @@ D: d1, d2 A: a1, a2, a3 B: b1, b2, b3 C: c1, c2, c3 - `).make({ subModels: [{ keys: ['A', 'B', 'C'], strength: 3 }] }); + `).make({ subModels: [{ fields: ['A', 'B', 'C'], strength: 3 }] }); // All 3-wise must be covered for (const a of ['a1', 'a2', 'a3']) { for (const b of ['b1', 'b2', 'b3']) { diff --git a/typescript/src/__tests__/shortcuts.test.ts b/typescript/src/__tests__/shortcuts.test.ts new file mode 100644 index 0000000..1aa09d9 --- /dev/null +++ b/typescript/src/__tests__/shortcuts.test.ts @@ -0,0 +1,132 @@ +import { make } from '../index'; +import { Constraint } from '../shortcuts'; + +const factors = { + OS: ['Win', 'Mac', 'Linux'], + Browser: ['Chrome', 'Firefox', 'Safari'], + Price: [100, 500, 1000], + Qty: [1, 2, 5], +}; + +const c = new Constraint(); + +describe('Constraint shortcut', () => { + describe('comparison', () => { + it('eq with literal', () => { + const cond = c.eq('$OS', 'Mac'); + expect(cond).toEqual({ operator: 'eq', left: 'OS', value: 'Mac' }); + }); + + it('ne with field reference', () => { + const cond = c.ne('$OS', '$Browser'); + expect(cond).toEqual({ operator: 'ne', left: 'OS', right: 'Browser' }); + }); + + it('gt with number', () => { + const cond = c.gt('$Price', 500); + expect(cond).toEqual({ operator: 'gt', left: 'Price', value: 500 }); + }); + + it('in with values', () => { + const cond = c.in('$OS', ['Win', 'Mac']); + expect(cond).toEqual({ operator: 'in', left: 'OS', values: ['Win', 'Mac'] }); + }); + }); + + describe('logical', () => { + it('and', () => { + const cond = c.and(c.eq('$OS', '$Browser'), c.eq('$Browser', 'Safari')); + expect(cond.operator).toBe('and'); + expect((cond as any).conditions).toHaveLength(2); + }); + + it('or', () => { + const cond = c.or(c.eq('$OS', 'Mac'), c.eq('$OS', 'Win')); + expect(cond.operator).toBe('or'); + }); + + it('not', () => { + const cond = c.not(c.eq('$OS', 'Linux')); + expect(cond).toEqual({ operator: 'not', condition: { operator: 'eq', left: 'OS', value: 'Linux' } }); + }); + }); + + describe('arithmetic', () => { + it('mul builds expression', () => { + const expr = c.mul('$Price', '$Qty'); + expect(expr).toEqual({ operator: 'mul', left: 'Price', right: 'Qty' }); + }); + + it('add with literal', () => { + const expr = c.add('$Price', 100); + expect(expr).toEqual({ operator: 'add', left: 'Price', value: 100 }); + }); + + it('nested arithmetic in comparison', () => { + const cond = c.gt(c.mul('$Price', '$Qty'), 10000); + expect(cond).toEqual({ + operator: 'gt', + left: { operator: 'mul', left: 'Price', right: 'Qty' }, + value: 10000, + }); + }); + + it('sum folds left', () => { + const expr = c.sum('$Price', '$Qty', 100); + expect(expr).toEqual({ + operator: 'add', + left: { operator: 'add', left: 'Price', right: 'Qty' }, + value: 100, + }); + }); + + it('product folds left', () => { + const expr = c.product('$Price', '$Qty', 2); + expect(expr).toEqual({ + operator: 'mul', + left: { operator: 'mul', left: 'Price', right: 'Qty' }, + value: 2, + }); + }); + + it('sum requires at least 2 args', () => { + expect(() => c.sum('$Price')).toThrow(); + }); + }); + + describe('fn (custom)', () => { + it('builds custom condition', () => { + const evalFn = (row: any) => row.OS !== row.Browser; + const cond = c.fn(['OS', 'Browser'], evalFn); + expect(cond).toEqual({ operator: 'fn', requires: ['OS', 'Browser'], evaluate: evalFn }); + }); + }); + + describe('integration with make()', () => { + it('Safari only on Mac + Price*Qty <= 2500', () => { + const rows = make(factors, { + constraints: [ + c.or(c.ne('$Browser', 'Safari'), c.eq('$OS', 'Mac')), + c.lte(c.mul('$Price', '$Qty'), 2500), + ], + }); + for (const row of rows) { + const r = row as any; + if (r.Browser === 'Safari') expect(r.OS).toBe('Mac'); + expect(r.Price * r.Qty).toBeLessThanOrEqual(2500); + } + }); + + it('sum constraint', () => { + const f2 = { A: [1, 2, 3], B: [1, 2, 3], C: [1, 2, 3] }; + const c2 = new Constraint(); + const rows = make(f2, { + constraints: [c2.lte(c2.sum('$A', '$B', '$C'), 6)], + }); + for (const row of rows) { + const r = row as any; + expect(r.A + r.B + r.C).toBeLessThanOrEqual(6); + } + }); + }); +}); diff --git a/typescript/src/__tests__/simple-criterion.test.ts b/typescript/src/__tests__/simple-criterion.test.ts index b4e8cc0..2a81d46 100644 --- a/typescript/src/__tests__/simple-criterion.test.ts +++ b/typescript/src/__tests__/simple-criterion.test.ts @@ -1,8 +1,8 @@ import { Controller } from '../controller'; import { criteria } from '../index'; -import type { Condition } from '../types'; +import type { Expression } from '../types'; -const runWithSimple = (factors: any, constraints: Condition[]) => { +const runWithSimple = (factors: any, constraints: Expression[]) => { const ctrl = new Controller(factors, { constraints, criterion: criteria.simple }); const rows = ctrl.make(); return { rows, stats: ctrl.stats }; @@ -17,18 +17,18 @@ describe('simple criterion with constraints', () => { C: [100, 200, 300], D: [1000, 2000, 3000], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'eq', field: 'B', value: 10 }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'eq', left: 'B', value: 10 }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'B', value: 10 }, - { operator: 'eq', field: 'C', value: 100 }, + { operator: 'ne', left: 'B', value: 10 }, + { operator: 'eq', left: 'C', value: 100 }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'C', value: 100 }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'ne', left: 'C', value: 100 }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, ]; const { rows, stats } = runWithSimple(factors, constraints); @@ -50,26 +50,26 @@ describe('simple criterion with constraints', () => { E: ['α', 'β', 'γ'], F: ['X', 'Y', 'Z'], }; - const constraints: Condition[] = [ + const constraints: Expression[] = [ { operator: 'or', conditions: [ - { operator: 'ne', field: 'A', value: 1 }, - { operator: 'in', field: 'B', values: [10, 20] }, + { operator: 'ne', left: 'A', value: 1 }, + { operator: 'in', left: 'B', values: [10, 20] }, ]}, { operator: 'or', conditions: [ - { operator: 'in', field: 'B', values: [30] }, - { operator: 'in', field: 'C', values: [100, 200] }, + { operator: 'in', left: 'B', values: [30] }, + { operator: 'in', left: 'C', values: [100, 200] }, ]}, { operator: 'or', conditions: [ - { operator: 'in', field: 'C', values: [300] }, - { operator: 'eq', field: 'D', value: 1000 }, + { operator: 'in', left: 'C', values: [300] }, + { operator: 'eq', left: 'D', value: 1000 }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'D', value: 1000 }, - { operator: 'in', field: 'E', values: ['α', 'β'] }, + { operator: 'ne', left: 'D', value: 1000 }, + { operator: 'in', left: 'E', values: ['α', 'β'] }, ]}, { operator: 'or', conditions: [ - { operator: 'in', field: 'E', values: ['γ'] }, - { operator: 'eq', field: 'F', value: 'X' }, + { operator: 'in', left: 'E', values: ['γ'] }, + { operator: 'eq', left: 'F', value: 'X' }, ]}, ]; const { rows, stats } = runWithSimple(factors, constraints); @@ -87,13 +87,13 @@ describe('simple criterion with constraints', () => { it('all-different', () => { const vals = [1, 2, 3, 4]; const factors = { A: vals, B: vals, C: vals, D: vals }; - const constraints: Condition[] = [ - { operator: 'ne', field: 'A', target: 'B' }, - { operator: 'ne', field: 'A', target: 'C' }, - { operator: 'ne', field: 'A', target: 'D' }, - { operator: 'ne', field: 'B', target: 'C' }, - { operator: 'ne', field: 'B', target: 'D' }, - { operator: 'ne', field: 'C', target: 'D' }, + const constraints: Expression[] = [ + { operator: 'ne', left: 'A', right: 'B' }, + { operator: 'ne', left: 'A', right: 'C' }, + { operator: 'ne', left: 'A', right: 'D' }, + { operator: 'ne', left: 'B', right: 'C' }, + { operator: 'ne', left: 'B', right: 'D' }, + { operator: 'ne', left: 'C', right: 'D' }, ]; const { rows, stats } = runWithSimple(factors, constraints); console.log('all-different simple:', { rowCount: stats.rowCount, progress: stats.progress, pruned: stats.prunedPairs }); @@ -111,31 +111,31 @@ describe('simple criterion with constraints', () => { Environment: ['dev', 'staging', 'prod'], Approval: ['none', 'lead', 'director'], }; - const constraints: Condition[] = [ - { operator: 'ne', field: 'Assignee', target: 'Reviewer' }, + const constraints: Expression[] = [ + { operator: 'ne', left: 'Assignee', right: 'Reviewer' }, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'critical' }, - { operator: 'eq', field: 'Environment', value: 'prod' }, + { operator: 'ne', left: 'Priority', value: 'critical' }, + { operator: 'eq', left: 'Environment', value: 'prod' }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Environment', value: 'prod' }, - { operator: 'eq', field: 'Approval', value: 'director' }, + { operator: 'ne', left: 'Environment', value: 'prod' }, + { operator: 'eq', left: 'Approval', value: 'director' }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'high' }, - { operator: 'in', field: 'Environment', values: ['staging', 'prod'] }, + { operator: 'ne', left: 'Priority', value: 'high' }, + { operator: 'in', left: 'Environment', values: ['staging', 'prod'] }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Environment', value: 'staging' }, - { operator: 'in', field: 'Approval', values: ['lead', 'director'] }, + { operator: 'ne', left: 'Environment', value: 'staging' }, + { operator: 'in', left: 'Approval', values: ['lead', 'director'] }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'low' }, - { operator: 'eq', field: 'Approval', value: 'none' }, + { operator: 'ne', left: 'Priority', value: 'low' }, + { operator: 'eq', left: 'Approval', value: 'none' }, ]}, { operator: 'or', conditions: [ - { operator: 'ne', field: 'Priority', value: 'low' }, - { operator: 'eq', field: 'Environment', value: 'dev' }, + { operator: 'ne', left: 'Priority', value: 'low' }, + { operator: 'eq', left: 'Environment', value: 'dev' }, ]}, ]; const { rows, stats } = runWithSimple(factors, constraints); diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index fdfdd71..db21812 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -25,7 +25,7 @@ import { OptionsType, PairType, SuggestRowType, - Condition, + Expression, Comparer, } from "./types"; import { evaluate, extractKeys, TriState } from "./evaluate"; @@ -53,7 +53,7 @@ export class Row extends Map implements RowType { } interface ResolvedConstraint { - condition: Condition; + condition: Expression; keys: ReadonlySet; } @@ -182,7 +182,7 @@ export class Controller { const pairs: PairType[] = []; const allKeys = getItems(this.serials).map(([k, _]) => k); const subModels = this.options.subModels ?? []; - const subModelKeySets = subModels.map(sm => new Set(sm.keys)); + const subModelKeySets = subModels.map(sm => new Set(sm.fields)); const isWithinSubModel = (keys: ScalarType[]) => subModelKeySets.some(ks => keys.every(k => ks.has(k))); @@ -196,7 +196,7 @@ export class Controller { } for (const sub of subModels) { - for (const keys of combinations(sub.keys, sub.strength)) { + for (const keys of combinations(sub.fields, sub.strength)) { const comb = range(0, sub.strength).map((i) => this.serials.get(keys[i]) as PairType); for (let pair of product(...comb)) { pairs.push(pair.sort(ascOrder)); diff --git a/typescript/src/evaluate.ts b/typescript/src/evaluate.ts index b9996d0..8f49f06 100644 --- a/typescript/src/evaluate.ts +++ b/typescript/src/evaluate.ts @@ -1,4 +1,4 @@ -import type { Condition, Comparer, DictType } from './types'; +import type { Expression, Comparer, DictType, Operand } from './types'; export type TriState = true | false | null; @@ -16,12 +16,54 @@ export function resolve(row: DictType, field: string): any { return current; } +const ARITHMETIC_OPS: Record number> = { + add: (a, b) => a + b, + sub: (a, b) => a - b, + mul: (a, b) => a * b, + div: (a, b) => a / b, + mod: (a, b) => a % b, + pow: (a, b) => a ** b, +}; + +/** + * Resolve an operand (field reference or arithmetic expression) against a row. + * Returns `undefined` if any referenced field is missing. + */ +function resolveOperand(row: DictType, operand: Operand): any { + if (typeof operand === 'string') { + return resolve(row, operand); + } + // Arithmetic expression + const left = resolveOperand(row, operand.left); + if (left === undefined) return undefined; + const right = 'right' in operand + ? resolveOperand(row, operand.right) + : operand.value; + if (right === undefined) return undefined; + const fn = ARITHMETIC_OPS[operand.operator]; + return fn(left, right); +} + +/** + * Extract the set of top-level factor keys that an operand depends on. + */ +function extractOperandKeys(operand: Operand): Set { + if (typeof operand === 'string') { + return new Set([operand.split('.')[0]]); + } + const keys = extractOperandKeys(operand.left); + if ('right' in operand) { + for (const k of extractOperandKeys(operand.right)) keys.add(k); + } + return keys; +} + /** * Extract the set of top-level factor keys that a condition depends on. * For dot-separated paths, only the first segment is returned (that is the * factor key; deeper segments are properties within the factor value). */ -export function extractKeys(c: Condition): Set { +export function extractKeys(c: Expression): Set { switch (c.operator) { case 'not': return extractKeys(c.condition); @@ -33,13 +75,12 @@ export function extractKeys(c: Condition): Set { } return keys; } - case 'custom': - return new Set(c.keys); + case 'fn': + return new Set(c.requires); default: { - const keys = new Set(); - keys.add(c.field.split('.')[0]); - if ('target' in c && typeof c.target === 'string') { - keys.add(c.target.split('.')[0]); + const keys = extractOperandKeys(c.left); + if ('right' in c) { + for (const k of extractOperandKeys(c.right)) keys.add(k); } return keys; } @@ -68,7 +109,7 @@ const DEFAULT_COMPARER: Required = { * `undefined`). */ export function evaluate( - c: Condition, + c: Expression, row: DictType, comparer: Comparer = {}, ): TriState { @@ -99,8 +140,8 @@ export function evaluate( } // -- custom -- - case 'custom': { - for (const k of c.keys) { + case 'fn': { + for (const k of c.requires) { if (resolve(row, k) === undefined) return null; } return c.evaluate(row); @@ -108,19 +149,19 @@ export function evaluate( // -- in -- case 'in': { - const v = resolve(row, c.field); + const v = resolveOperand(row, c.left); if (v === undefined) return null; return (comparer.in ?? DEFAULT_COMPARER.in)(v, c.values); } // -- comparison -- default: { - const v = resolve(row, c.field); + const v = resolveOperand(row, c.left); if (v === undefined) return null; let target: any; - if ('target' in c) { - target = resolve(row, c.target); + if ('right' in c) { + target = resolveOperand(row, c.right); if (target === undefined) return null; } else { target = (c as any).value; diff --git a/typescript/src/index.ts b/typescript/src/index.ts index e0e126d..c6df6e8 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -5,7 +5,7 @@ import random from "./sorters/random"; import greedy from "./criteria/greedy"; import simple from "./criteria/simple"; -import { FactorsType, OptionsType, SuggestRowType, DictType, ListType, Condition, ComparisonCondition, LogicalCondition, CustomCondition, Comparer } from "./types"; +import { FactorsType, OptionsType, SuggestRowType, DictType, ListType, Expression, ComparisonExpression, LogicalExpression, Comparer } from "./types"; import { Controller, ControllerStats } from "./controller"; import { NeverMatch, UncoveredPair } from "./exceptions"; @@ -46,10 +46,9 @@ export type { SuggestRowType, DictType, ListType, - Condition, - ComparisonCondition, - LogicalCondition, - CustomCondition, + Expression, + ComparisonExpression, + LogicalExpression, Comparer, UncoveredPair, ControllerStats, diff --git a/typescript/src/pict/constraints.ts b/typescript/src/pict/constraints.ts index cf87a59..19a164f 100644 --- a/typescript/src/pict/constraints.ts +++ b/typescript/src/pict/constraints.ts @@ -26,6 +26,7 @@ enum TokenType { COMMA = 'COMMA', COLON = 'COLON', SEMICOLON = 'SEMICOLON', + ARITHMETIC = 'ARITHMETIC', WHITESPACE = 'WHITESPACE', UNKNOWN = 'UNKNOWN', } @@ -57,6 +58,12 @@ function classifyToken(token: string, line: number): Token { if (['AND', 'OR', 'NOT'].includes(token.toUpperCase())) { return { type: TokenType.OPERATOR, value: token.toUpperCase(), line }; } + if (['+', '-', '*', '/', '%', '^'].includes(token)) { + return { type: TokenType.ARITHMETIC, value: token, line }; + } + if (token === '**') { + return { type: TokenType.ARITHMETIC, value: '^', line }; + } switch (token) { case '(': return { type: TokenType.LPAREN, value: token, line }; case ')': return { type: TokenType.RPAREN, value: token, line }; @@ -161,6 +168,14 @@ export class PictConstraintsLexer { } else if (char === ',' && insideBraces) { flushBuffer(); addToken(TokenType.COMMA, char, currentLine); + } else if ('+-*/%^'.includes(char) && !insideBraces && !insideBrackets) { + flushBuffer(); + if (char === '*' && constraints[i + 1] === '*') { + tokens.push(classifyToken('**', currentLine)); + i++; + } else { + tokens.push(classifyToken(char, currentLine)); + } } else if ('[]=<>!();:'.includes(char) && !insideBraces && !insideBrackets) { flushBuffer(); if (char === '<' || char === '>' || char === '!' || char === '=') { @@ -261,6 +276,21 @@ export class PictConstraintsLexer { return left; } + const isLogicalParen = (): boolean => { + const saved = tokenIndex; + let depth = 1; + let found = false; + while (tokenIndex < tokens.length) { + const t = tokens[tokenIndex++]; + if (t.type === TokenType.WHITESPACE) continue; + if (t.type === TokenType.LPAREN) depth++; + else if (t.type === TokenType.RPAREN) { depth--; if (depth === 0) break; } + else if (depth === 1 && t.type === TokenType.COMPARER) { found = true; break; } + } + tokenIndex = saved; + return found; + }; + const parseFactor: () => Evaluator = () => { let token = nextToken(); if (token != null) { @@ -269,12 +299,17 @@ export class PictConstraintsLexer { return (row) => !operand(row); } if (token.type === TokenType.LPAREN) { - const expr = parseExpression(); - token = nextToken(); - if (!token || token.type !== TokenType.RPAREN) { - throw new Error('Expected closing parenthesis'); + if (isLogicalParen()) { + const expr = parseExpression(); + token = nextToken(); + if (!token || token.type !== TokenType.RPAREN) { + throw new Error('Expected closing parenthesis'); + } + return expr; + } else { + tokenIndex--; + return parseCondition(); } - return expr; } if (token.type === TokenType.BOOLEAN) { const val = token.value.toUpperCase() === 'TRUE'; @@ -377,12 +412,32 @@ export class PictConstraintsLexer { return new Set(elements); } - const parseOperand: () => Evaluator | null = () => { + const ARITHMETIC_MAP: Record number> = { + '+': (a, b) => a + b, + '-': (a, b) => a - b, + '*': (a, b) => a * b, + '/': (a, b) => a / b, + '%': (a, b) => a % b, + '^': (a, b) => a ** b, + }; + + const parsePrimaryOperand: () => Evaluator | null = () => { const token = nextToken(); if (token == null) { return null; } - if (token.type === TokenType.REF) { + if (token.type === TokenType.LPAREN) { + // Parenthesized arithmetic expression + const inner = parseOperand(); + if (inner == null) { + throw new Error('Expected expression after "("'); + } + const closeParen = nextToken(); + if (!closeParen || closeParen.type !== TokenType.RPAREN) { + throw new Error('Expected closing ")" in arithmetic expression'); + } + return inner; + } else if (token.type === TokenType.REF) { const key = token.value.slice(1, -1); // remove [ and ] currentKeys.add(key); return (row) => row[key]; @@ -404,6 +459,71 @@ export class PictConstraintsLexer { } } + // Power: ^ or ** (highest arithmetic precedence, right-associative) + const parsePowOperand: () => Evaluator | null = () => { + let left = parsePrimaryOperand(); + if (left == null) return null; + const saved = tokenIndex; + const tok = nextToken(); + if (tok && tok.type === TokenType.ARITHMETIC && tok.value === '^') { + const right = parsePowOperand(); // right-associative + if (right == null) { + throw new Error("Expected operand after '^'"); + } + const l = left, r = right; + left = ((l, r) => (row: FilterRowType) => l(row) ** r(row))(l, r); + } else { + tokenIndex = saved; + } + return left; + } + + // Multiplicative: *, /, % (higher precedence) + const parseMulOperand: () => Evaluator | null = () => { + let left = parsePowOperand(); + if (left == null) return null; + while (true) { + const saved = tokenIndex; + const tok = nextToken(); + if (tok && tok.type === TokenType.ARITHMETIC && '*/%'.includes(tok.value)) { + const fn = ARITHMETIC_MAP[tok.value]; + const right = parsePowOperand(); + if (right == null) { + throw new Error(`Expected operand after '${tok.value}'`); + } + const l = left, r = right; + left = ((l, r, fn) => (row: FilterRowType) => fn(l(row), r(row)))(l, r, fn); + } else { + tokenIndex = saved; + break; + } + } + return left; + } + + // Additive: +, - (lower precedence) + const parseOperand: () => Evaluator | null = () => { + let left = parseMulOperand(); + if (left == null) return null; + while (true) { + const saved = tokenIndex; + const tok = nextToken(); + if (tok && tok.type === TokenType.ARITHMETIC && '+-'.includes(tok.value)) { + const fn = ARITHMETIC_MAP[tok.value]; + const right = parseMulOperand(); + if (right == null) { + throw new Error(`Expected operand after '${tok.value}'`); + } + const l = left, r = right; + left = ((l, r, fn) => (row: FilterRowType) => fn(l(row), r(row)))(l, r, fn); + } else { + tokenIndex = saved; + break; + } + } + return left; + } + const abandon = () => { while (tokenIndex < tokens.length && tokens[tokenIndex].type !== TokenType.SEMICOLON) { tokenIndex++; diff --git a/typescript/src/pict/model.ts b/typescript/src/pict/model.ts index 47cd525..984ce0d 100644 --- a/typescript/src/pict/model.ts +++ b/typescript/src/pict/model.ts @@ -1,5 +1,5 @@ import type { - Condition, + Expression, FilterRowType, OptionsType, SubModelType, @@ -42,7 +42,7 @@ export class PictModel { get parameters(): PictFactorsType { return this._parameters; } get subModels(): SubModelType[] { return this._subModels; } - get constraints(): Condition[] { return this._modelConstraints(); } + get constraints(): Expression[] { return this._modelConstraints(); } get negatives(): Map> { return this._negatives; } get weights(): { [factorKey: string]: { [index: number]: number } } { return this._weights; } get progress(): number { return this._controller?.progress ?? 0; } @@ -70,12 +70,12 @@ export class PictModel { }; /** - * Convert this model's constraints into `Condition[]` for the controller. + * Convert this model's constraints into `Expression[]` for the controller. * Each lexer filter becomes a `custom` condition with its dependency keys. * The negative-value rule also becomes a `custom` condition. */ - private _modelConstraints(): Condition[] { - const list: Condition[] = []; + private _modelConstraints(): Expression[] { + const list: Expression[] = []; if (this._lexer) { const filters = this._lexer.filters; @@ -84,8 +84,8 @@ export class PictModel { const f = filters[i]; if (f == null) continue; list.push({ - operator: 'custom', - keys: [...filterKeys[i]], + operator: 'fn', + requires: [...filterKeys[i]], evaluate: f, }); } @@ -95,8 +95,8 @@ export class PictModel { const negativeKeys = [...this._negatives.keys()] as string[]; const negatives = this._negatives; list.push({ - operator: 'custom', - keys: negativeKeys, + operator: 'fn', + requires: negativeKeys, evaluate: (row) => { let seen = false; for (const [key, set] of negatives) { diff --git a/typescript/src/pict/subModels.ts b/typescript/src/pict/subModels.ts index ee7507e..437e810 100644 --- a/typescript/src/pict/subModels.ts +++ b/typescript/src/pict/subModels.ts @@ -6,7 +6,7 @@ export const subModelPattern = /^\{\s*(.+?)\s*\}\s*@\s*(\d+)\s*$/; export function parseSubModel(line: string): SubModelType | null { const match = line.match(subModelPattern); if (!match) return null; - const keys = match[1].split(',').map(k => k.trim()).filter(k => k !== ''); + const fields = match[1].split(',').map(k => k.trim()).filter(k => k !== ''); const strength = parseInt(match[2], 10); - return { keys, strength }; + return { fields, strength }; } diff --git a/typescript/src/shortcuts/index.ts b/typescript/src/shortcuts/index.ts new file mode 100644 index 0000000..fe29cca --- /dev/null +++ b/typescript/src/shortcuts/index.ts @@ -0,0 +1,154 @@ +import type { + Expression, + Operand, + ArithmeticExpression, + ArrayObjectType, +} from '../types'; + +type ArithOp = 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow'; +type CompOp = 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte'; + +/** A field reference or arithmetic expression (resolves to an Operand). */ +type FieldOrExpr = `$${string & keyof T}` | ArithmeticExpression; + +/** A literal value (preserves template literal autocomplete via `string & {}`). */ +type Literal = (string & {}) | number | boolean | null; + +/** Wrapper to force a value to be treated as a literal, not a field reference. */ +type ValWrapper = { __val: true; value: any }; + +/** Right-hand operand: field reference, expression, literal, or val-wrapped. */ +type RightOperand = FieldOrExpr | Literal | ValWrapper; + +function resolveOperand(x: RightOperand): { operand: Operand } | { value: any } { + if (typeof x === 'object' && x !== null) { + if ('__val' in x) return { value: (x as ValWrapper).value }; + if ('operator' in x) return { operand: x as ArithmeticExpression }; + } + if (typeof x === 'string' && x.startsWith('$')) { + return { operand: x.slice(1) }; + } + return { value: x }; +} + +function buildComparison(operator: CompOp, left: FieldOrExpr, right: any): Expression { + const l = resolveOperand(left); + const r = resolveOperand(right); + const leftOp = 'operand' in l ? l.operand : l.value; + if ('operand' in r) { + return { operator, left: leftOp, right: r.operand } as Expression; + } + return { operator, left: leftOp, value: r.value } as Expression; +} + +function buildArithmetic(operator: ArithOp, left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + const l = resolveOperand(left); + const r = resolveOperand(right); + const leftOp = 'operand' in l ? l.operand : l.value; + if ('operand' in r) { + return { operator, left: leftOp, right: r.operand }; + } + return { operator, left: leftOp, value: r.value }; +} + +function foldArithmetic(operator: ArithOp, args: (FieldOrExpr | RightOperand)[]): ArithmeticExpression { + let acc = buildArithmetic(operator, args[0], args[1]); + for (let i = 2; i < args.length; i++) { + const r = resolveOperand(args[i]); + if ('operand' in r) { + acc = { operator, left: acc, right: r.operand }; + } else { + acc = { operator, left: acc, value: r.value }; + } + } + return acc; +} + +/** + * Constraint builder with `$`-prefixed field references and type-safe + * autocompletion via template literal types. + * + * ```typescript + * const c = new Constraint(); + * c.eq("$OS", "Mac") + * c.gt(c.mul("$Price", "$Qty"), 10000) + * c.sum("$A", "$B", "$C") + * ``` + */ +export class Constraint = ArrayObjectType> { + // -- comparison -- + eq(left: FieldOrExpr, right: FieldOrExpr | RightOperand): Expression { + return buildComparison('eq', left, right); + } + ne(left: FieldOrExpr, right: FieldOrExpr | RightOperand): Expression { + return buildComparison('ne', left, right); + } + gt(left: FieldOrExpr, right: FieldOrExpr | RightOperand): Expression { + return buildComparison('gt', left, right); + } + lt(left: FieldOrExpr, right: FieldOrExpr | RightOperand): Expression { + return buildComparison('lt', left, right); + } + gte(left: FieldOrExpr, right: FieldOrExpr | RightOperand): Expression { + return buildComparison('gte', left, right); + } + lte(left: FieldOrExpr, right: FieldOrExpr | RightOperand): Expression { + return buildComparison('lte', left, right); + } + in(left: FieldOrExpr, values: any[]): Expression { + const l = resolveOperand(left); + const leftOp = 'operand' in l ? l.operand : l.value; + return { operator: 'in', left: leftOp, values } as Expression; + } + + // -- logical -- + and(...conditions: Expression[]): Expression { + return { operator: 'and', conditions }; + } + or(...conditions: Expression[]): Expression { + return { operator: 'or', conditions }; + } + not(condition: Expression): Expression { + return { operator: 'not', condition }; + } + + // -- binary arithmetic -- + add(left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + return buildArithmetic('add', left, right); + } + sub(left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + return buildArithmetic('sub', left, right); + } + mul(left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + return buildArithmetic('mul', left, right); + } + div(left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + return buildArithmetic('div', left, right); + } + mod(left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + return buildArithmetic('mod', left, right); + } + pow(left: FieldOrExpr | RightOperand, right: FieldOrExpr | RightOperand): ArithmeticExpression { + return buildArithmetic('pow', left, right); + } + + // -- variadic arithmetic -- + sum(...args: (FieldOrExpr | RightOperand)[]): ArithmeticExpression { + if (args.length < 2) throw new Error('sum() requires at least 2 arguments'); + return foldArithmetic('add', args); + } + product(...args: (FieldOrExpr | RightOperand)[]): ArithmeticExpression { + if (args.length < 2) throw new Error('product() requires at least 2 arguments'); + return foldArithmetic('mul', args); + } + + // -- fn -- + fn(requires: (string & keyof T)[], evaluate: (row: { [K in keyof T]: any }) => boolean): Expression { + return { operator: 'fn', requires, evaluate } as Expression; + } + + // -- literal -- + val(value: any): ValWrapper { + return { __val: true, value }; + } +} diff --git a/typescript/src/types.ts b/typescript/src/types.ts index be5beda..4481334 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -48,7 +48,7 @@ export interface CriterionArgsType { }; export interface SubModelType { - keys: ScalarType[]; + fields: ScalarType[]; strength: number; }; @@ -61,43 +61,58 @@ export type PresetRowType = { [key: string]: any; [index: number]: any }; // --------------------------------------------------------------------------- /** - * A comparison condition. `field` supports dot notation for nested access - * (e.g. `"payment.method"`). `target` references another field for - * field-to-field comparisons. + * An operand is either a field reference (string, supports dot notation + * like `"payment.method"`) or an arithmetic expression. */ -export type ComparisonCondition = - | { operator: 'eq'; field: string; value: any } - | { operator: 'eq'; field: string; target: string } - | { operator: 'ne'; field: string; value: any } - | { operator: 'ne'; field: string; target: string } - | { operator: 'gt'; field: string; value: any } - | { operator: 'gt'; field: string; target: string } - | { operator: 'lt'; field: string; value: any } - | { operator: 'lt'; field: string; target: string } - | { operator: 'gte'; field: string; value: any } - | { operator: 'gte'; field: string; target: string } - | { operator: 'lte'; field: string; value: any } - | { operator: 'lte'; field: string; target: string } - | { operator: 'in'; field: string; values: any[] }; - -export type LogicalCondition = - | { operator: 'not'; condition: Condition } - | { operator: 'and'; conditions: Condition[] } - | { operator: 'or'; conditions: Condition[] }; +export type Operand = string | ArithmeticExpression; + +/** + * Arithmetic expressions compute a value from two operands. + * Both `left` and `right` can be field references or nested expressions. + * When `right` is omitted, `value` provides a literal operand. + */ +export type ArithmeticExpression = + | { operator: 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow'; left: Operand; right: Operand } + | { operator: 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow'; left: Operand; value: any }; + +/** + * A comparison condition. `left` is the first operand (field reference or + * expression). The second operand is either `right` (another field/expression) + * or `value` (a literal). For `in`, use `values` (an array of literals). + */ +export type ComparisonExpression = + | { operator: 'eq'; left: Operand; value: any } + | { operator: 'eq'; left: Operand; right: Operand } + | { operator: 'ne'; left: Operand; value: any } + | { operator: 'ne'; left: Operand; right: Operand } + | { operator: 'gt'; left: Operand; value: any } + | { operator: 'gt'; left: Operand; right: Operand } + | { operator: 'lt'; left: Operand; value: any } + | { operator: 'lt'; left: Operand; right: Operand } + | { operator: 'gte'; left: Operand; value: any } + | { operator: 'gte'; left: Operand; right: Operand } + | { operator: 'lte'; left: Operand; value: any } + | { operator: 'lte'; left: Operand; right: Operand } + | { operator: 'in'; left: Operand; values: any[] }; + +export type LogicalExpression = + | { operator: 'not'; condition: Expression } + | { operator: 'and'; conditions: Expression[] } + | { operator: 'or'; conditions: Expression[] }; /** * Escape hatch for constraints that cannot be expressed declaratively. * The engine cannot perform three-valued reasoning on these — when a * dependency key is missing the condition is treated as `null`. - * Provide `keys` so the engine knows when it is safe to call `evaluate`. + * Provide `requires` so the engine knows when it is safe to call `evaluate`. */ -export type CustomCondition = { - operator: 'custom'; - keys: string[]; +export type FnExpression = { + operator: 'fn'; + requires: string[]; evaluate: (row: { [key: string]: any }) => boolean; }; -export type Condition = ComparisonCondition | LogicalCondition | CustomCondition; +export type Expression = ComparisonExpression | LogicalExpression | FnExpression; /** * Custom comparison functions. Each key matches a comparison operator name. @@ -144,7 +159,7 @@ export interface OptionsType { * The top-level array is an implicit AND: every condition must be * satisfied for a row to be accepted. */ - constraints?: Condition[]; + constraints?: Expression[]; /** * Custom comparison functions. See `Comparer` for details. */ diff --git a/typescript/tsconfig.test.json b/typescript/tsconfig.test.json index a46a98e..1d3c0ea 100644 --- a/typescript/tsconfig.test.json +++ b/typescript/tsconfig.test.json @@ -3,5 +3,6 @@ "compilerOptions": { "rootDir": "." }, - "include": ["src"] + "include": ["src"], + "exclude": ["src/_bench.ts", "src/tmp", "node_modules", "dist"] } diff --git a/typescript/vite.config.ts b/typescript/vite.config.ts index 0284e98..30a2d95 100644 --- a/typescript/vite.config.ts +++ b/typescript/vite.config.ts @@ -8,6 +8,7 @@ export default defineConfig({ entry: { index: resolve(__dirname, 'src/index.ts'), pict: resolve(__dirname, 'src/pict/index.ts'), + shortcuts: resolve(__dirname, 'src/shortcuts/index.ts'), }, formats: ['es', 'cjs'], }, From 51fa10c4289e79456cb7aab486ee32034969ee6d Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 17:24:54 +0900 Subject: [PATCH 70/79] 3.0.0-rc.2 --- python/setup.cfg | 2 +- typescript/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/setup.cfg b/python/setup.cfg index d7c5ba0..182be52 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = covertable -version = 3.0.0rc1 +version = 3.0.0rc2 author = righ author_email = righ.m9@gmail.com url = https://covertable.walkframe.com diff --git a/typescript/package.json b/typescript/package.json index 1ec8ef3..3c5da4c 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "3.0.0-rc.1", + "version": "3.0.0-rc.2", "description": "Efficient TypeScript library for pairwise testing, generating minimal covering arrays with constraint support.", "homepage": "https://covertable.walkframe.com", "repository": { From 1e836f48a9673f4538aecb728b06fe6261f1198f Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 18:30:21 +0900 Subject: [PATCH 71/79] feat: use set for in-condition automatically --- docs/contents/advanced/index.mdx | 2 +- docs/contents/advanced/options.mdx | 15 +++++++++++++++ .../constraint.mdx} | 4 ++-- docs/contents/tools/pict-online.mdx | 8 ++++---- docs/contents/tools/pict.tsx | 4 ++-- docs/sidebars.ts | 7 ++++++- python/covertable/main.py | 17 +++++++++++++++-- typescript/src/controller.ts | 19 +++++++++++++++++-- typescript/src/evaluate.ts | 4 ++-- typescript/src/types.ts | 2 +- 10 files changed, 65 insertions(+), 17 deletions(-) rename docs/contents/{advanced/shortcuts.mdx => shortcuts/constraint.mdx} (99%) diff --git a/docs/contents/advanced/index.mdx b/docs/contents/advanced/index.mdx index b061ad5..d49d0ca 100644 --- a/docs/contents/advanced/index.mdx +++ b/docs/contents/advanced/index.mdx @@ -54,4 +54,4 @@ The `make` function accepts an options object as its second argument: | `salt` | `string \| number` | `""` | Value mixed into `sorters.hash` to control the ordering of pairs. | | `tolerance` | `number` | `0` | Tolerance used by `criteria.greedy` to trade optimality for speed. | -See [Options Detail](./options) for full documentation of each option, [PictModel](./pict) for the PICT-compatible model parser, or [Shortcuts](./shortcuts) for a concise constraint builder API. +See [Options Detail](./options) for full documentation of each option, [PictModel](./pict) for the PICT-compatible model parser, or [Constraint Shortcuts](/shortcuts/constraint) for a concise constraint builder API. diff --git a/docs/contents/advanced/options.mdx b/docs/contents/advanced/options.mdx index b29084d..61fb516 100644 --- a/docs/contents/advanced/options.mdx +++ b/docs/contents/advanced/options.mdx @@ -119,6 +119,21 @@ make(factors, { }); ``` +:::tip +Writing constraint objects by hand can be verbose. The [`Constraint` shortcut class](/shortcuts/constraint) provides a concise builder API: + +```typescript +import { Constraint } from "covertable/shortcuts"; +const c = new Constraint(); + +make(factors, { + constraints: [ + c.or(c.ne("$machine", "iPhone"), c.eq("$os", "iOS")), + ], +}); +``` +::: + ## `sorter` Determines the order in which combinations are generated. diff --git a/docs/contents/advanced/shortcuts.mdx b/docs/contents/shortcuts/constraint.mdx similarity index 99% rename from docs/contents/advanced/shortcuts.mdx rename to docs/contents/shortcuts/constraint.mdx index 86d9219..085482e 100644 --- a/docs/contents/advanced/shortcuts.mdx +++ b/docs/contents/shortcuts/constraint.mdx @@ -1,6 +1,6 @@ --- -sidebar_position: 5 -title: Shortcuts +sidebar_position: 1 +title: Constraint --- # Constraint Shortcuts diff --git a/docs/contents/tools/pict-online.mdx b/docs/contents/tools/pict-online.mdx index f97dda0..55fc8c9 100644 --- a/docs/contents/tools/pict-online.mdx +++ b/docs/contents/tools/pict-online.mdx @@ -11,16 +11,16 @@ import PictDemo from './pict'; A browser-based pairwise test case generator compatible with [Microsoft PICT](https://github.com/microsoft/pict) model format. Write your model, click Generate, and get optimized test combinations instantly — no installation required. -:::caution[PICT superset] -This tool uses CoverTable's model format, which is a **superset of Microsoft PICT**. It supports extensions such as arithmetic expressions (`[A] * [B] > 100`, `([A] + 1) * [B] <= 500`) and `#` comments in constraints. Models using these extensions may not run in the original PICT tool. -::: - :::info[Privacy] All processing runs entirely in your browser. No data is sent to any server. ::: +:::caution[PICT superset] +This tool uses CoverTable's model format, which is a **superset of Microsoft PICT**. It supports extensions such as arithmetic expressions (`[A] * [B] > 100`, `([A] + 1) * [B] <= 500`) and `#` comments in constraints. Models using these extensions may not run in the original PICT tool. +::: + --- ## How it works diff --git a/docs/contents/tools/pict.tsx b/docs/contents/tools/pict.tsx index a1607be..230ac03 100644 --- a/docs/contents/tools/pict.tsx +++ b/docs/contents/tools/pict.tsx @@ -233,7 +233,7 @@ const pictHighlightTheme = EditorView.baseTheme({ ".cm-pict-param-name": { color: "#4ec9b0", fontWeight: "bold" }, ".cm-pict-param-value": { color: "#9cdcfe" }, ".cm-pict-operator": { color: "#d4d4d4" }, - ".cm-pict-arithmetic": { color: "#d4d4d4", fontWeight: "bold" }, + ".cm-pict-arithmetic": { color: "#569cd6", fontWeight: "bold" }, ".cm-pict-sub-model": { color: "#dcdcaa" }, }); @@ -750,7 +750,7 @@ function PictDemoInner() { {model.subModels.map((sm, i) => ( - {sm.keys.join(", ")} + {sm.fields.join(", ")} {sm.strength} ))} diff --git a/docs/sidebars.ts b/docs/sidebars.ts index e836c2d..1611f2e 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -11,7 +11,12 @@ const sidebars: SidebarsConfig = { { type: 'category', label: 'Advanced', - items: ['advanced/index', 'advanced/options', 'advanced/pict', 'advanced/constraint-logic', 'advanced/shortcuts'], + items: ['advanced/index', 'advanced/options', 'advanced/pict', 'advanced/constraint-logic'], + }, + { + type: 'category', + label: 'Shortcuts', + items: ['shortcuts/constraint'], }, { type: 'category', diff --git a/python/covertable/main.py b/python/covertable/main.py index 9d7396d..71d77b1 100644 --- a/python/covertable/main.py +++ b/python/covertable/main.py @@ -76,13 +76,26 @@ def __init__(self, factors, strength=2, sorter=None, criterion=None, self._pruned_pairs = self._total_pairs - len(self.incomplete) self._num_all_chunks = len(self.incomplete) + @staticmethod + def _normalize_condition(cond): + """Convert ``values`` lists to sets for O(1) lookup in ``in`` conditions.""" + op = cond.get("operator") + if op == "in" and isinstance(cond.get("values"), list): + return {**cond, "values": set(cond["values"])} + if op in ("and", "or"): + return {**cond, "conditions": [Controller._normalize_condition(c) for c in cond["conditions"]]} + if op == "not": + return {**cond, "condition": Controller._normalize_condition(cond["condition"])} + return cond + def _resolve_constraints(self, constraints): """Build resolved constraints and per-key index.""" if not constraints: return for i, cond in enumerate(constraints): - keys = extract_keys(cond) - self._constraints.append({"condition": cond, "keys": keys}) + normalized = self._normalize_condition(cond) + keys = extract_keys(normalized) + self._constraints.append({"condition": normalized, "keys": keys}) for k in keys: if k not in self._constraints_by_key: self._constraints_by_key[k] = set() diff --git a/typescript/src/controller.ts b/typescript/src/controller.ts index db21812..b624258 100644 --- a/typescript/src/controller.ts +++ b/typescript/src/controller.ts @@ -144,11 +144,26 @@ export class Controller { } + /** Normalize `in` conditions: convert `values` arrays to Sets for O(1) lookup. */ + private static normalizeCondition(c: Expression): Expression { + if (c.operator === 'in' && Array.isArray((c as any).values)) { + return { ...c, values: new Set((c as any).values) } as any; + } + if (c.operator === 'and' || c.operator === 'or') { + return { ...c, conditions: c.conditions.map(Controller.normalizeCondition) } as any; + } + if (c.operator === 'not') { + return { ...c, condition: Controller.normalizeCondition(c.condition) } as any; + } + return c; + } + private resolveConstraints() { const constraints = this.options.constraints ?? []; for (let i = 0; i < constraints.length; i++) { - const keys = extractKeys(constraints[i]); - this.constraints.push({ condition: constraints[i], keys }); + const normalized = Controller.normalizeCondition(constraints[i]); + const keys = extractKeys(normalized); + this.constraints.push({ condition: normalized, keys }); for (const k of keys) { let set = this.constraintsByKey.get(k); if (!set) { diff --git a/typescript/src/evaluate.ts b/typescript/src/evaluate.ts index 8f49f06..2c5a264 100644 --- a/typescript/src/evaluate.ts +++ b/typescript/src/evaluate.ts @@ -94,7 +94,7 @@ const DEFAULT_COMPARER: Required = { lt: (a, b) => a < b, gte: (a, b) => a >= b, lte: (a, b) => a <= b, - in: (value, values) => values.includes(value), + in: (value, values) => values.has(value), }; /** @@ -151,7 +151,7 @@ export function evaluate( case 'in': { const v = resolveOperand(row, c.left); if (v === undefined) return null; - return (comparer.in ?? DEFAULT_COMPARER.in)(v, c.values); + return (comparer.in ?? DEFAULT_COMPARER.in)(v, c.values as unknown as Set); } // -- comparison -- diff --git a/typescript/src/types.ts b/typescript/src/types.ts index 4481334..81f10c8 100644 --- a/typescript/src/types.ts +++ b/typescript/src/types.ts @@ -133,7 +133,7 @@ export interface Comparer { lt?: (a: any, b: any) => boolean; gte?: (a: any, b: any) => boolean; lte?: (a: any, b: any) => boolean; - in?: (value: any, values: any[]) => boolean; + in?: (value: any, values: Set) => boolean; } // --------------------------------------------------------------------------- From ba20b6683d5109452798d17224ba28d0657241f6 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 19:36:53 +0900 Subject: [PATCH 72/79] update docs --- docs/contents/advanced/index.mdx | 57 ------------------ .../constraint-logic.mdx | 4 +- docs/contents/history/index.mdx | 2 +- docs/contents/history/migration.mdx | 21 ++++++- docs/contents/history/v3.mdx | 4 +- docs/contents/index.mdx | 10 +-- .../{advanced => reference}/options.mdx | 39 +++++++++--- .../contents/{advanced => reference}/pict.mdx | 20 +++--- .../{ => reference}/shortcuts/constraint.mdx | 0 docs/contents/tools/pict-online.mdx | 4 +- docs/docusaurus.config.ts | 8 +-- docs/sidebars.ts | 20 +++--- docs/static/img/favicon.ico | Bin 3626 -> 7314 bytes typescript/history.md | 38 ------------ 14 files changed, 87 insertions(+), 140 deletions(-) delete mode 100644 docs/contents/advanced/index.mdx rename docs/contents/{advanced => development}/constraint-logic.mdx (98%) rename docs/contents/{advanced => reference}/options.mdx (74%) rename docs/contents/{advanced => reference}/pict.mdx (96%) rename docs/contents/{ => reference}/shortcuts/constraint.mdx (100%) delete mode 100644 typescript/history.md diff --git a/docs/contents/advanced/index.mdx b/docs/contents/advanced/index.mdx deleted file mode 100644 index d49d0ca..0000000 --- a/docs/contents/advanced/index.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -sidebar_position: 1 -title: Advanced Usage ---- - -# Advanced Usage - -Although covertable works with a minimum number of arguments, several options are available. -This section shows how to use them in detail. - -## Type Inference with Object Factors - -When factors are specified as an object, results will also be in object form. You can use `SuggestRowType` to get full type inference: - -```typescript -import { make, SuggestRowType } from "covertable"; - -const machine = ["iPhone", "Pixel", "XPERIA", "ZenFone", "Galaxy"]; -const os = ["iOS", "Android"]; -const browser = ["FireFox", "Chrome", "Safari"]; - -const factors = { machine, os, browser }; - -const rows = make(factors, { - strength: 2, - constraints: [ - // iPhone ↔ iOS - { operator: 'or', conditions: [ - { operator: 'ne', left: 'machine', value: 'iPhone' }, - { operator: 'eq', left: 'os', value: 'iOS' }, - ]}, - { operator: 'or', conditions: [ - { operator: 'eq', left: 'machine', value: 'iPhone' }, - { operator: 'ne', left: 'os', value: 'iOS' }, - ]}, - ], -}); -``` - -## Options Reference - -The `make` function accepts an options object as its second argument: - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `strength` | `number` | `2` | Number of factors to be covered (N-wise). | -| `subModels` | `SubModelType[]` | `undefined` | Apply a different combination strength to a specific group of factors. | -| `weights` | `WeightsType` | `undefined` | Index-keyed weights that bias value selection during row completion. | -| `presets` | `PresetRowType[]` | `undefined` | Rows that must be included in the output. Equivalent to PICT's seeding feature. | -| `constraints` | `Expression[]` | `undefined` | Declarative constraints evaluated under three-valued logic. See [Constraint Logic](/advanced/constraint-logic). | -| `comparer` | `Comparer` | `undefined` | Custom comparison functions for constraint evaluation. | -| `sorter` | `Function` | `sorters.hash` | Determines the order of combinations. | -| `criterion` | `Function` | `criteria.greedy` | Determines the algorithm for generating combinations. | -| `salt` | `string \| number` | `""` | Value mixed into `sorters.hash` to control the ordering of pairs. | -| `tolerance` | `number` | `0` | Tolerance used by `criteria.greedy` to trade optimality for speed. | - -See [Options Detail](./options) for full documentation of each option, [PictModel](./pict) for the PICT-compatible model parser, or [Constraint Shortcuts](/shortcuts/constraint) for a concise constraint builder API. diff --git a/docs/contents/advanced/constraint-logic.mdx b/docs/contents/development/constraint-logic.mdx similarity index 98% rename from docs/contents/advanced/constraint-logic.mdx rename to docs/contents/development/constraint-logic.mdx index 74ffe4c..b5577d0 100644 --- a/docs/contents/advanced/constraint-logic.mdx +++ b/docs/contents/development/constraint-logic.mdx @@ -5,7 +5,7 @@ title: Constraint Logic # Constraint Logic -covertable v3 introduces declarative constraints with three-valued (Kleene) logic and forward checking. +CoverTable v3 introduces declarative constraints with three-valued (Kleene) logic and forward checking. This page explains how constraints are evaluated, propagated, and how coverage is guaranteed. ## Overview @@ -281,7 +281,7 @@ console.log(ctrl.stats); ## Coverage Guarantee -covertable guarantees **N-wise coverage for all feasible pairs**: +CoverTable guarantees **N-wise coverage for all feasible pairs**: ``` feasible pairs = totalPairs - prunedPairs diff --git a/docs/contents/history/index.mdx b/docs/contents/history/index.mdx index 571e6b7..0d21ec7 100644 --- a/docs/contents/history/index.mdx +++ b/docs/contents/history/index.mdx @@ -5,7 +5,7 @@ title: History # History -Release notes for each major version of covertable. +Release notes for each major version of CoverTable. - [v3.x](./v3) — Current major release with declarative constraints, forward checking, and full PICT compatibility - [v2.x](./v2) — Added PictConstraintsLexer, performance improvements, makeAsync diff --git a/docs/contents/history/migration.mdx b/docs/contents/history/migration.mdx index 610ccf4..aabfe45 100644 --- a/docs/contents/history/migration.mdx +++ b/docs/contents/history/migration.mdx @@ -51,8 +51,27 @@ make(factors, { ]}, ], }); + +// v3 — same thing with Constraint shortcuts +import { Constraint } from "covertable/shortcuts"; +const c = new Constraint(); + +make(factors, { + constraints: [ + c.or(c.ne("$machine", "iPhone"), c.eq("$os", "iOS")), + ], +}); + +// v3 — or wrap the original function with c.fn() +make(factors, { + constraints: [ + c.fn(["machine", "os"], (row) => !(row.machine === "iPhone" && row.os !== "iOS")), + ], +}); ``` +`c.fn()` is the quickest migration path — wrap the existing `preFilter` function as-is, just add the list of fields it depends on (`requires`). The engine will defer evaluation until those fields are set. + :::info[Why declarative?] Declarative constraints allow the engine to: - Evaluate under three-valued (Kleene) logic — `null` when a field is not yet set @@ -60,7 +79,7 @@ Declarative constraints allow the engine to: - Propagate constraint chains via forward checking - Detect unsolvable combinations early instead of silently dropping rows -See [Constraint Logic](/advanced/constraint-logic) for details. +See [Constraint Logic](/development/constraint-logic) for details. ::: ### Replacing `postFilter` diff --git a/docs/contents/history/v3.mdx b/docs/contents/history/v3.mdx index 91d6bb1..ef4dedf 100644 --- a/docs/contents/history/v3.mdx +++ b/docs/contents/history/v3.mdx @@ -12,9 +12,9 @@ Major release with breaking changes, declarative constraints, and full PICT-form - The `length` option has been renamed to `strength`. - The `seed` option (used by `sorters.hash`) has been renamed to `salt`. - The default export has been removed. Use `import { make } from "covertable"` instead of `import make from "covertable"`. -- `PictConstraintsLexer` is no longer exported. Use the new [`PictModel`](/advanced/pict) class instead. +- `PictConstraintsLexer` is no longer exported. Use the new [`PictModel`](/reference/pict) class instead. - `PictModel.errors` (`string[]`) has been replaced with `PictModel.issues` (`PictModelIssue[]`). Each issue carries `severity`, `source`, `index`, `line`, and `message`. -- `preFilter` and `postFilter` have been replaced by declarative `constraints`. See [Constraint Logic](/advanced/constraint-logic) and [Migration Guide](./migration). +- `preFilter` and `postFilter` have been replaced by declarative `constraints`. See [Constraint Logic](/development/constraint-logic) and [Migration Guide](./migration). ## Why replace `preFilter` with `constraints`? diff --git a/docs/contents/index.mdx b/docs/contents/index.mdx index 98d64e3..989104e 100644 --- a/docs/contents/index.mdx +++ b/docs/contents/index.mdx @@ -4,7 +4,7 @@ sidebar_position: 1 title: Getting Started --- -# covertable +# CoverTable

npm version @@ -13,7 +13,7 @@ title: Getting Started GitHub stars
-**covertable** is a powerful tool for generating pairwise (and N-wise) combinations of input factors, designed for both **Node.js** and **browser** environments. It makes it easy to create comprehensive test cases that cover all factor interactions while keeping the number of test cases minimal. +**CoverTable** is a powerful tool for generating pairwise (and N-wise) combinations of input factors, designed for both **Node.js** and **browser** environments. It makes it easy to create comprehensive test cases that cover all factor interactions while keeping the number of test cases minimal. :::tip[What is Pairwise Testing?] Pairwise testing is a combinatorial testing technique that generates test cases covering all possible pairs of input parameters. Instead of testing every combination (which can be enormous), pairwise testing ensures that every pair of factor values appears in at least one test case, dramatically reducing the number of required tests while maintaining high defect detection rates. @@ -111,7 +111,7 @@ console.log(ctrl.stats); // } ``` -See [Constraint Logic](/advanced/constraint-logic#statistics) for full details on each field. +See [Constraint Logic](/development/constraint-logic#statistics) for full details on each field. ## Async Generation @@ -142,8 +142,8 @@ ES2015 or later. The following features are used: ## Next Steps -- Learn about [**Advanced Usage**](./advanced) including constraints, sorters, criteria, sub-models, and weights -- Use the [**PictModel**](./advanced/pict) to parse and run full PICT-format models (parameters + constraints + sub-models + invalid values + weights) +- Learn about [**Options**](./reference/options) including constraints, sorters, criteria, sub-models, and weights +- Use the [**PictModel**](./reference/pict) to parse and run full PICT-format models (parameters + constraints + sub-models + invalid values + weights) - Try the [**Compatible PICT**](/tools/pict) tool - Check the [**History**](./history/) for release notes and [**Migration Guide**](./history/migration) diff --git a/docs/contents/advanced/options.mdx b/docs/contents/reference/options.mdx similarity index 74% rename from docs/contents/advanced/options.mdx rename to docs/contents/reference/options.mdx index 61fb516..96cab65 100644 --- a/docs/contents/advanced/options.mdx +++ b/docs/contents/reference/options.mdx @@ -1,9 +1,28 @@ --- -sidebar_position: 2 -title: Options Detail +sidebar_position: 1 +title: Options --- -# Options Detail +# Options + +The `make` function accepts an options object as its second argument: + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `strength` | `number` | `2` | Number of factors to be covered (N-wise). | +| `subModels` | `SubModelType[]` | `undefined` | Apply a different combination strength to a specific group of factors. | +| `weights` | `WeightsType` | `undefined` | Index-keyed weights that bias value selection during row completion. | +| `presets` | `PresetRowType[]` | `undefined` | Rows that must be included in the output. Equivalent to PICT's seeding feature. | +| `constraints` | `Expression[]` | `undefined` | Declarative constraints evaluated under three-valued logic. | +| `comparer` | `Comparer` | `undefined` | Custom comparison functions for constraint evaluation. | +| `sorter` | `Function` | `sorters.hash` | Determines the order of combinations. | +| `criterion` | `Function` | `criteria.greedy` | Determines the algorithm for generating combinations. | +| `salt` | `string \| number` | `""` | Value mixed into `sorters.hash` to control the ordering of pairs. | +| `tolerance` | `number` | `0` | Tolerance used by `criteria.greedy` to trade optimality for speed. | + +See also: [PictModel](./pict) for the PICT-compatible model parser, or [Constraint Shortcuts](/reference/shortcuts/constraint) for a concise constraint builder API. + +--- ## `strength` @@ -34,7 +53,7 @@ const factors = { make(factors, { strength: 2, subModels: [ - { keys: ["PLATFORM", "CPUS", "RAM"], strength: 3 }, + { fields: ["PLATFORM", "CPUS", "RAM"], strength: 3 }, ], }); ``` @@ -45,7 +64,7 @@ In this example: ## `weights` -`weights` biases the **completion phase** — the moment covertable picks a value to fill in a column once all required pairs have been satisfied. Higher-weighted values are tried first, so they tend to appear in more rows. +`weights` biases the **completion phase** — the moment CoverTable picks a value to fill in a column once all required pairs have been satisfied. Higher-weighted values are tried first, so they tend to appear in more rows. ```typescript import { make } from "covertable"; @@ -70,7 +89,7 @@ Weights only affect the **completion phase**. The pairwise (or N-wise) coverage ## `presets` -`presets` lets you specify rows that **must appear in the output**. covertable processes them before normal generation, so the pairs they cover are subtracted from the work that the generator has to do — often reducing the total number of generated rows. +`presets` lets you specify rows that **must appear in the output**. CoverTable processes them before normal generation, so the pairs they cover are subtracted from the work that the generator has to do — often reducing the total number of generated rows. ```typescript import { make } from "covertable"; @@ -100,12 +119,12 @@ make(factors, { | Row cannot be completed (e.g. constraints leave no valid filler) | Silently dropped | :::info[Equivalent to PICT's seeding (`/e:file`)] -PICT calls this feature **seeding** and reads the seed rows from a tab-separated file via the `/e:file.txt` CLI option. covertable's `presets` is the same concept, expressed as plain JavaScript objects so you can compose them programmatically. +PICT calls this feature **seeding** and reads the seed rows from a tab-separated file via the `/e:file.txt` CLI option. CoverTable's `presets` is the same concept, expressed as plain JavaScript objects so you can compose them programmatically. ::: ## `constraints` -Declarative constraints evaluated under Kleene three-valued logic. See [Constraint Logic](/advanced/constraint-logic) for full documentation. +Declarative constraints evaluated under Kleene three-valued logic. See [Constraint Logic](/development/constraint-logic) for full documentation. ```typescript make(factors, { @@ -120,7 +139,7 @@ make(factors, { ``` :::tip -Writing constraint objects by hand can be verbose. The [`Constraint` shortcut class](/shortcuts/constraint) provides a concise builder API: +Writing constraint objects by hand can be verbose. The [`Constraint` shortcut class](/reference/shortcuts/constraint) provides a concise builder API: ```typescript import { Constraint } from "covertable/shortcuts"; @@ -151,7 +170,7 @@ make(factors, { sorter: sorters.random }); ``` :::tip[Salt for Reproducibility] -When using `sorters.hash`, the `salt` option controls the ordering of unstored pairs. When the combination of factors and salt are the same, covertable **reproduces the same result set**. Changing the salt is the easiest way to explore alternative orderings without changing the input factors. +When using `sorters.hash`, the `salt` option controls the ordering of unstored pairs. When the combination of factors and salt are the same, CoverTable **reproduces the same result set**. Changing the salt is the easiest way to explore alternative orderings without changing the input factors. ::: :::info[Renamed from `seed`] diff --git a/docs/contents/advanced/pict.mdx b/docs/contents/reference/pict.mdx similarity index 96% rename from docs/contents/advanced/pict.mdx rename to docs/contents/reference/pict.mdx index 54b196d..19ab0db 100644 --- a/docs/contents/advanced/pict.mdx +++ b/docs/contents/reference/pict.mdx @@ -7,7 +7,7 @@ title: PictModel `PictModel` parses a complete PICT-format model — parameters, sub-models, and constraints — into a single object that can directly generate rows. It is exported from a separate entry point so it does not bloat the bundle of consumers who only need `make`. -:::caution PICT superset +:::warning[PICT superset] CoverTable's model format is a **superset of Microsoft PICT**. It extends the original syntax with features such as arithmetic expressions (`[A] * [B] > 100`, `([A] + 1) * [B] <= 500`), comment lines (`#`) in the constraint section, and the `~` negative-value prefix in output. @@ -165,11 +165,11 @@ Try the [**Compatible PICT**](/tools/pict) tool to experiment with the constrain ## Differences from the Original PICT -covertable's `PictModel` accepts PICT-format input, but the underlying engine works differently from the original PICT tool developed by Microsoft. +CoverTable's `PictModel` accepts PICT-format input, but the underlying engine works differently from the original PICT tool developed by Microsoft. ### Generation Algorithm -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Greedy strategy** | Picks the combination with the most uncovered (OPEN) slots in a bitvector, then selects a value that maximizes globally covered pairs | Scores each uncovered pair by how many other uncovered pairs it would cover when added to the current row | | **Value selection** | `PickValue()` maximizes `complete` (fully-bound combinations) then `totalZeros` (global coverage) | Greedy selects full pairs; remaining factors are filled by `close()` using depth-first backtracking | @@ -177,7 +177,7 @@ covertable's `PictModel` accepts PICT-format input, but the underlying engine wo ### Constraint Processing -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Approach** | Pre-compiles constraints into explicit exclusion sets before generation | Evaluates constraints at runtime using three-valued (Kleene) logic | | **Internal form** | `IF [A]="x" THEN [B]<>"y"` → exclusion `{A:"x", B:"y"}` | Constraints remain as expressions and are evaluated per candidate | @@ -188,7 +188,7 @@ covertable's `PictModel` accepts PICT-format input, but the underlying engine wo ### Seeding / Presets -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **API** | `PictAddSeed()` / CLI `-e seedfile` | `presets` option (list of partial-row dicts/objects) | | **Format** | Array of `(parameter, value_index)` tuples | Value dictionaries — e.g. `{ OS: "Win", Browser: "Chrome" }` | @@ -196,7 +196,7 @@ covertable's `PictModel` accepts PICT-format input, but the underlying engine wo ### Sub-models -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Structure** | Fully hierarchical — sub-models are independent `Model` instances combined via pseudo-parameters | Flat key-set partitioning with per-set strength | | **Nesting** | Sub-models can be nested arbitrarily | Single level only | @@ -204,28 +204,28 @@ covertable's `PictModel` accepts PICT-format input, but the underlying engine wo ### Weights -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Syntax** | `value (weight)` in model file / `valueWeights[]` in API | `weights` option — `{ factor: { valueIndex: weight } }` | | **Effect** | Influences tie-breaking in `PickValue()` and random-row generation | Influences only the `close()` (backtracking completion) phase — higher-weight values are tried first | ### Randomization and Determinism -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Default** | Deterministic (seed 0) | Deterministic (`hash` sorter with empty salt) | | **Randomize** | `-r [seed]` flag; uses `srand()`/`rand()` | Change `salt` for reproducible variation; use `random` sorter for non-deterministic output | ### Output and Streaming -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Output** | Batch only — all rows generated before any are returned (TSV or JSON from CLI; index array from C API) | Generator-based — rows yielded incrementally via `makeAsync()` / `make_async()` | | **Format** | Tab-separated table or JSON array of objects | Python `list`/`dict` rows; TypeScript typed arrays/objects with full type inference | ### Platform -| | Original PICT | covertable | +| | Original PICT | CoverTable | |---|---|---| | **Language** | C++ (with C-compatible API via `pictapi.h`) | Pure Python 3 + pure TypeScript — no native code, no compilation | | **Runtime** | Compiled binary; Windows, Linux, macOS | Python: pip install; TypeScript: npm install; also runs in browsers | diff --git a/docs/contents/shortcuts/constraint.mdx b/docs/contents/reference/shortcuts/constraint.mdx similarity index 100% rename from docs/contents/shortcuts/constraint.mdx rename to docs/contents/reference/shortcuts/constraint.mdx diff --git a/docs/contents/tools/pict-online.mdx b/docs/contents/tools/pict-online.mdx index 55fc8c9..0225af9 100644 --- a/docs/contents/tools/pict-online.mdx +++ b/docs/contents/tools/pict-online.mdx @@ -17,7 +17,7 @@ All processing runs entirely in your browser. No data is sent to any server. -:::caution[PICT superset] +:::warning[PICT superset] This tool uses CoverTable's model format, which is a **superset of Microsoft PICT**. It supports extensions such as arithmetic expressions (`[A] * [B] > 100`, `([A] + 1) * [B] <= 500`) and `#` comments in constraints. Models using these extensions may not run in the original PICT tool. ::: @@ -68,7 +68,7 @@ make({ machine, os, browser }, { ## Supported Syntax -`PictModel` supports the full PICT model file format. See the [PictModel reference](/advanced/pict) for the complete table. +`PictModel` supports the full PICT model file format. See the [PictModel reference](/reference/pict) for the complete table. ### Constraints diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 4963b46..07932ea 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -4,7 +4,7 @@ import type * as Preset from '@docusaurus/preset-classic'; import path from 'path'; const config: Config = { - title: 'covertable', + title: 'CoverTable', tagline: 'A flexible pairwise testing tool for generating covering arrays', favicon: 'img/favicon.ico', @@ -73,7 +73,7 @@ const config: Config = { respectPrefersColorScheme: true, }, navbar: { - title: 'covertable', + title: 'CoverTable', items: [ { href: 'https://www.npmjs.com/package/covertable', @@ -103,8 +103,8 @@ const config: Config = { to: '/', }, { - label: 'Advanced Usage', - to: '/advanced', + label: 'Reference', + to: '/reference', }, { label: 'Compatible PICT', diff --git a/docs/sidebars.ts b/docs/sidebars.ts index 1611f2e..4285368 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -10,18 +10,22 @@ const sidebars: SidebarsConfig = { }, { type: 'category', - label: 'Advanced', - items: ['advanced/index', 'advanced/options', 'advanced/pict', 'advanced/constraint-logic'], - }, - { - type: 'category', - label: 'Shortcuts', - items: ['shortcuts/constraint'], + label: 'Reference', + link: { type: 'generated-index', slug: '/reference' }, + items: [ + 'reference/options', + 'reference/pict', + { + type: 'category', + label: 'Shortcuts', + items: ['reference/shortcuts/constraint'], + }, + ], }, { type: 'category', label: 'Development', - items: ['development/typescript', 'development/python'], + items: ['development/typescript', 'development/python', 'development/constraint-logic'], }, { type: 'category', diff --git a/docs/static/img/favicon.ico b/docs/static/img/favicon.ico index c01d54bcd39a5f853428f3cd5aa0f383d963c484..1369afea08d1a9c9e724bf4e80926f03f880b2c4 100644 GIT binary patch literal 7314 zcmai&WmHt%+y4(e(hWBf14xHMgQC<>Lw5*BcZYO3fHcyLAP9(nv~+_wATgw*bce(M z694)A?*EJD#k1D4-<*A&z0O`|uWRk=`}tk~fB|3wq@)0PfPo_n08seP4E%3Ag$)40 zm;eBQ{2OW0bX7~N8$%02^m+XbP(_`1|Ytt~voEm>E$!}hyzbm2C#%Bo#tfaGQXqsg%rtCGd zjrYKs(>_#JbQ+~)WvTLMTRP1vw;wJbWghdXpC{~dhtTGYZC?iw10N^Krycn+5&IW8 zHbw%tEvt+A0Kj}@S-bP5O^ec{`BiD!c3vPe4|&iEOqm%QP-RbjqMVn=Q(BS+J$S89 zOZq%UVCzj=!q7Sxlru3fF4R%&|w z{Ku-x%uFdD~FAiAYM|(A$2FH~K zHH`K-QCV7)BA_nqmn`?wWEVPqS*fHCa@L+-Cd9+C_?1a9eX1y);?92 zE~EIhTP_R3BP8k`&sMd)*i=bKURs*m9t$Oxs zU_d`M3+0k?pxcsCn|%bt6OzpC`~0YyciuYF0Y2=v4yuCL%<#fwi_90Ax>uH#h=_p2<_;`^%0(?2AJNaNwx`0_;Ccl;Ls2sf}B|gR#SbiUaB3WB?wZB z%2f~b4G!k(8MPJ4L|mr?kl~R#(6Ph$qzcE54-V2`rKQK2FN3ZQx3&uJ??YCi&BY`F zZ??9!kY!RC85ywB!sg~?4h{~ZU!*M<1z2jqvpymJs!LOqtW3M>|ugz#h}QfHy5?9-?Ia5{SW_O7n3_V$CrLwOJz zIiYioZPtr--KioePdbHqr9p?s$G*?<-3p~N%8(ZUcWY}b*{Yaf7D|&K<#_0%m#(lm zbny1}_WO6Gj%CsV@rLXr;`WE{jQ!O(9OSAfUG9sMljHgM?BoSuwRlz?OF!Kh*YQr^K=>IeEd}-VM`^9f7DgaMiS9;yNWhj)-p; zIh^DD=Nwzw)*ilWRTlW*;GpxuO9_ddECxysEJh|K9a!8zv64;r@sHwiEZch{6mMan zWAlQd;!v3Mlk{^BcXuVO{Os&Ug;*IrOT?0_w`o*y1D-7=6}mICvn~rEe=n8tG$f3^ z{eDSoGP^W4SFXz)7#N5|BJY)ngUTDX5y6WO`YoobEQ9b%PRr+jm zbq6$0%{Vtr;j5W1;sr|2rz@GfO`CZUO)f(o&I@aqoLi_I-qi73O^>Q3rUiQ2R~hL_ zS(TNQX@c#PY8g&7%b!tf%p3DU`i{L~Ink6>!7Jx6nsAB4O4k_9**b1WOx^rJU*FsK z01FEldMiekoiy4g3?MEpj(pKxSTI}FkcH5M?KlMJPF&ycY-wz4gtBPyXO4}HJ(`fk z;Jl*-#1o&3i8Z&kI~&dH&q{?{|1ogqAc*fG>a?bu^Nruuz3TF4Ylv!t~uO`u_$ z53;4I5NkrQ1A08yh zk0iArj-XEv+H?|&EUYzM4t@e2DXUl@w;;KwXVfnRDXjI%?npIe(hnclPa6CmHSIr| z2l;PJn=^MEM+;xn|F3CAue>ORsg4jMN_A{btSao(oNqYm1qDJDBu`1T+g{BNT`>V} zw>V~37?R(wP2TGFCv?la#gK^d!=80cm#2?Lm=eg%zD{jF9gg>K2W0B&W#3sTbxvB7#bP6z z;BRQA$hV+jE*vn!rH?ojm}jAU1}*zvSwx|dkk5cTQA7i8d&e_M8QS%3X_Ni;=bM0b zTLcxYj@tTNnzroiFj;(Wf6{M;98y??%K|7_K_p&TDQWUk!2+UM9paGnsgKx7l@}ok z+HD=YYWgE+Gy+dnczZe_Jle#Yn+!s0#|@-Bb#u=4S_*!}V2|>grlsa@) z1g7+|aOKx8%<$!oKm%UtN6f9&XW7d-H!UUm&j$V6-B0fRqF4$O5)w@K6}cva`9`8& zkg*AVFdUHvnRbOR0FI40yP8${SYgk7kHljsFs`%uMFXdOh?u<}?t|0EPEH`QoYX?P z9`4c@4yw=QAm^D+UmIuGn+wP$&Zst|CKURvr}Ub?I4T5NJb z3iBb1U$1ClA7HYmwWt3hV>o)SRObw`+cxl0zT{p zbeN%c#1J}Ec*|2jaJyYtIlZSr8yEkCzPjtHN7$am^y`pol1%(61_DSyEGDToob9%F4QUfUSZ*FDPbL-8j*e_?ezN9p>idHYb63acxE& zF>rXgGx2eKeLWpkYFve`>^f!Y9RU~k|B($V0W7Nn4?;4jBnw&!3JTzBeZAMs`L1?_ zZk0Y_^Uu!C&U;oxlQB?sO(2B7=p9DlBjz;qGNEijH`K+2i>oVU_r}Ib%J37}?+`+d zs<*g9mbDAbZdl!ymzUkgxL3c>aHL-5|4Jf;!*&f*8&~ouswj}R!A~-Z^qJquYAOc; zfQX6B&d+mMu7z{FS5j41$LuDNx;5mbCX=LEuiS+F^!tNO11{UNBvK&MBLXUv~+U}VXJ4`V9ja@%ydU=ZnNcx?CGZD=2YLgaBz{zPpHm*_l@at;n zel$G4oL4-@gdept!3r2&g)pD-P!IW-BDT-GyhgIj;1QZmDSZ9SMM|Vl<53Zx)$Z`p zQZ@j6y3N;Eed8htOQXo$^N|rk;C3f+*O2!z6o_PF!H7*(9ARFT25p{QmuVOP<^eay z3=9kr8UjK?w58gvev2WEODij50{=vjp{_XV9N3C9U-`NQvryqjHcpEG-vUvtg4z99 zL%HMAI97`@Gom7Tm|?RuuSp2MF&Px5@%V!Z3vq`tUjScu_xEeMZvG%@2>Y%=LhfIW z6|UrbyYN3f)2>KUaDpTkeo^>UTTS-(T2y{Ym>8H9lTQ5ZQaWK7_iw zgq2RBkI^0!Th6`E*~`ph3EH~wg$x*@cCg{8&Q{fTW{F5n1~W$b>qZZCz_oinuz2=|6U%B z=7xH}dpy~ zTA9U;dZRMmhzJg)`;&NaVtp5K?x6QRjuikEp#&AiC5t$$9Lk4TtYxQ%_&u)8xJGX@ zsWuNKLkXs{LeJ%MB>CvB|9?| zSF^||d4?}EY8W{*@Q(swyWUsOhe$GpipUp14l?`oH zC41!S63zjPbY-{}oVetX?U;aqg!EUaI9(w>rFU(m`$b{GiP00UKMyc>>U)w_ekYrR z=Y=o+4}6hEuS@?IU)Tt?VgP_JstMaN~V3Hc<&=%`m3yZbT zYfzgb2?-)C9h+=XiS9;br$T&ueQ$!tN)%vk`S{cod0YNCMqOhW!We{;MzR z{l;P)SRzS-GNHW-g z&j<2HYkK`m#RE4teL|5`q*7cw)dZ@P^(>wi|J2T9RcCX4>S^DyVDh04|CRC4r?Mxl&bKg$Q}}$xk`ta>TNpa4VIHD z=Oc%y!asus__>Wmw}}khhD=;V!Zaqw)A}!FJEt)zww2&wkiDn0GGi zD%K51a+AxiRTglX62p!A0K*|*cn`*b2>8w16LDDZ-yS1SKdoDa0 zEg!JmA*N8w*b;aCvkxN-C=chyR<{E*uQg!=kr9ax=ou7bV`A{(RX$FS_TJP&Q>4Jp z%^7}v{s8)*e|~J%9V7W(HMuk9VKe_T3)eXo2NfMIH0!_+rFDsmXYKRz57pIGY}k0Q zpHqGq%W8a)x5cJ_IoR15i00xvE<5mEK?x|3yu1SMtEQ~64b(!bqq0Tdni^wwszO|b zm=<;vwso^rubTb6qK}1yN{wU7?TQOAG|0#E?JtC~<1MmoGNrO)Yxh1onhN*W{V29T zG^H@G#D%>ZcCI&Au?t0eWVe;hx1=*KGHr|swn<1xD0*jpD81cfhQy&c`uoYeh2MC& z-3uCO>X6ny6oXlxRVeYmP-@lo^EB;QpBl4{n~Br)#W<>gkb>=WgbnPD;rSbPQyBgM z)PF#LT-)iO{%B-)~DLd$7GxIfWA@~_1 z#l=X#(MngL(O6w`gRb9N3VB>xP^?~ldissI3#NP4lavk3 zaEv8^q3WScQa+yYKZR{=A0fN>Rznb5jN;z6E(_9k=riKyc>TT1N4Gv8{gB9Y@$7iG zlwO@SZ^=32j}G zF>&Q#7Sbz!T4^mAb8>SP6&1sy$MEnBs*DGwV=&5B(6B;0^^}+QXt71-Q)k_0xCi`7 zIW{uQLiz8YxZ;P!786&$ED3hl?k>_!)OC?|K2L1f539T@@Jb!&Kf)l9;Q=Cf zGxHGqK5>k{1d?Bj>bDS2yRaDx0`|D(-n-qet3l4t0}bApeO1y1e z4j?G+3b@#7a#_IKOTFm%JQBt|^pJ#c_J|;a7!N+a;KqbwnvB@`Fi%b^qpJRU6ap#@K^BZ1e75clj_p0l~u)k^%2ji zIIp2J=o5C9i5=6$#S7&`|rAC`6pb( z%j~pWsO3QEyQwMNz`*BMb=5zAqOBFqujr^K{Tef(qWxG@7)#BMBKS)%-y)C>h6kPW z;7M<8A~F|#{aQ^1dYn~M2SBv8+w*gXXi*XRfcym zh2GXSHl`zKp!lon#>U2IdsT#XmF}j&rfiH~sFE$r!7+hYUq>jLa|?rRA8EchT^rci zvQ;X;$9hYtqoae|*`Ym`^gS|>larhCvU#cK1CAl29a^Z~w-wChX8aQ|#saq%%+`>) zqqL`c{J8D!Q5()4TQCkIIyk$QJeLZ+zcnr>gx^>1>*@*I_DZmu)*bk;CB~odac|b5 zp>=O>uV)M|JSXVo3cBrdsLnQHE{SgApe>Bz$D`JLe(@Xx-lrYwvi+t8m0Ce2L+?bGH~M2Jf`fxWMYpKyrO>4pVq)8^)!XTtlnq(0$}()I z;!2~UqI!B{lw#4cb%8>ypyi`>h|$T(iHADwIw-{28vCb>#pUzw`fyNW#yJ)6xX%B~ z_Pe=4^26`w`aZkg{?^b*IJ`6|l%GU+Z-0NRfCysJ>b=_=Nx*VX!J*!5w#I>IxXY$a zh=_D>buGxw4%cyhk2MAo;7o_D1f%l5()bVwKX?18;^X795_F~pSL=}y5O|N+yt4S^ z_l*4+*5^JCbYiowAr^hP*N*V8!pB!K!02jyoErrt*ogWwBPAl=x|rtcreS_abgjcCKjgZXen&>F83^rN9aUy;#Y7i5bqtA{&6#&6itIrKNo`d*oRgBTHAm!edGb4ypO+Wdv#b>t7RC+{W)A#fMIkkC#qhH)ad{ct znn;JSb%(AG_7=%SqfMB=AXmj2XWBTAE6W8DH{lPnf3&DomIIGF64zBVG?J2%q6hg~ zvy@sZ1+PObp2a0w#w<;^wYVV$XNV#~qq?SG&=cO*!4Kgms zd;EJsvB!e}Y>hl`KkRT1Q*jUYlc!otyq+>Y%GYivq3V!%VYv8Z@plfu^VGt> z^cg0Hzh%oaKC0kF4%e-Lr)!=FV@G!5QsUfgHF}1rYceBq$DZ(}ox!^gr2P{8kRCKE zP(pSMZyyclMsicWmLf1s*KUb5=iVgXBvWbKaMf)a6?3e87H54|Y?<`LY#_KIRE=LV zp1?Q3W}5v&%rD1fUHZ`8aQ2yU?+3>Ky#@vHdcwImYwf$$>98T{#RPCsxzd3BkzQf` zxQqu>0l$2l*^ocMwXft<$?VFp8U+z4F-%KdF<1JAQ=++SUz`xAwnOb5{~+I&-F43- Qw(--%tpum~e_EOU2bVG9SO5S3 literal 3626 zcmb`Je@s(X6vrR`EK3%b%orErlDW({vnABqA zcfaS{d+xbU5JKp0*;0YOg+;Fl!eT)XRuapIwFLL`=imZCSon$`se`_<%@MB=M~KG+ z=EW^FL`w|Bo>*ktlaS^(fut!95`iG5u=SZ8nfDHO#GaTlH1-XG^;vsjUb^gWTVz0+ z^=WR1wv9-2oeR=_;fL0H7rNWqAzGtO(D;`~cX(RcN0w2v24Y8)6t`cS^_ghs`_ho? z{0ka~1Dgo8TfAP$r*ua?>$_V+kZ!-(TvEJ7O2f;Y#tezt$&R4 zLI}=-y@Z!grf*h3>}DUL{km4R>ya_I5Ag#{h_&?+HpKS!;$x3LC#CqUQ8&nM?X))Q zXAy2?`YL4FbC5CgJu(M&Q|>1st8XXLZ|5MgwgjP$m_2Vt0(J z&Gu7bOlkbGzGm2sh?X`){7w69Y$1#@P@7DF{ZE=4%T0NDS)iH`tiPSKpDNW)zmtn( zw;4$f>k)4$LBc>eBAaTZeCM2(iD+sHlj!qd z2GjRJ>f_Qes(+mnzdA^NH?^NB(^o-%Gmg$c8MNMq&`vm@9Ut;*&$xSD)PKH{wBCEC z4P9%NQ;n2s59ffMn8*5)5AAg4-93gBXBDX`A7S& zH-|%S3Wd%T79fk-e&l`{!?lve8_epXhE{d3Hn$Cg!t=-4D(t$cK~7f&4s?t7wr3ZP z*!SRQ-+tr|e1|hbc__J`k3S!rMy<0PHy&R`v#aJv?`Y?2{avK5sQz%=Us()jcNuZV z*$>auD4cEw>;t`+m>h?f?%VFJZj8D|Y1e_SjxG%J4{-AkFtT2+ZZS5UScS~%;dp!V>)7zi`w(xwSd*FS;Lml=f6hn#jq)2is4nkp+aTrV?)F6N z>DY#SU0IZ;*?Hu%tSj4edd~kYNHMFvS&5}#3-M;mBCOCZL3&;2obdG?qZ>rD|zC|Lu|sny76pn2xl|6sk~Hs{X9{8iBW zwiwgQt+@hi`FYMEhX2 hash sorter + greedy criterion. -- The `greedy` method is much faster than before. -- The `greedy` method now includes a `tolerance` option to balance speed and results. -- The sequential sorter was dropped. - - Due to the potential for huge numbers of combinations in TypeScript. - -## 1.1.x - -- The greedy sorter was improved in both implementations. - - Speed has been increased. - -## 1.0.x - -- First release 🎉 From 3870df04bdbc9a6ef41952c09a7d01c7417df706 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 20:00:45 +0900 Subject: [PATCH 73/79] fix: parameter color for demo --- docs/contents/tools/pict.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contents/tools/pict.tsx b/docs/contents/tools/pict.tsx index 230ac03..d550e6e 100644 --- a/docs/contents/tools/pict.tsx +++ b/docs/contents/tools/pict.tsx @@ -231,7 +231,7 @@ const pictHighlightTheme = EditorView.baseTheme({ ".cm-pict-negative": { color: "#f44747", textDecoration: "underline" }, ".cm-pict-weight": { color: "#b5cea8" }, ".cm-pict-param-name": { color: "#4ec9b0", fontWeight: "bold" }, - ".cm-pict-param-value": { color: "#9cdcfe" }, + ".cm-pict-param-value": { color: "#79c0d6" }, ".cm-pict-operator": { color: "#d4d4d4" }, ".cm-pict-arithmetic": { color: "#569cd6", fontWeight: "bold" }, ".cm-pict-sub-model": { color: "#dcdcaa" }, From 9ce6c9e06f65f123b20598bfe22ee4e914a80ac2 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 21:03:32 +0900 Subject: [PATCH 74/79] add a doc --- docs/contents/development/algorithm.mdx | 121 ++++++++++++++++++++++++ docs/sidebars.ts | 2 +- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 docs/contents/development/algorithm.mdx diff --git a/docs/contents/development/algorithm.mdx b/docs/contents/development/algorithm.mdx new file mode 100644 index 0000000..8eb4662 --- /dev/null +++ b/docs/contents/development/algorithm.mdx @@ -0,0 +1,121 @@ +--- +sidebar_position: 1 +title: Algorithm +--- + +# Algorithm: AETG vs IPOG + +CoverTable uses a **one-test-at-a-time greedy algorithm**. This was not designed after AETG specifically — it was a natural result of the implementation, which turned out to closely resemble the AETG (Automatic Efficient Test Generator) family. +This page explains the two major families of covering-array algorithms and where CoverTable fits. + +## Two Families of Covering-Array Algorithms + +Most N-wise test generation tools fall into one of two families: + +| | AETG family | IPOG family | +|---|---|---| +| **Strategy** | Build one complete row at a time | Start with a small array and extend it one parameter at a time | +| **Direction** | Horizontal — each iteration adds a row | Vertical — each iteration adds a column | +| **Origin** | Cohen et al., 1997 | Lei & Tai, 2002 | +| **Used by** | CoverTable, AETG, mAETG, ACTS (AETG mode) | ACTS (IPOG mode), Jenny, PICT | + +## AETG: One Row at a Time + +``` +while uncovered pairs remain: + row = {} + while row is not complete: + pick the pair/value that covers the most uncovered combinations + add it to row + emit row + mark covered pairs +``` + +**Advantages:** +- Conceptually simple — the unit of work is always "build a row" +- Natural fit for constraints — each candidate value can be checked against partial-row constraints before committing +- Streaming-friendly — rows can be yielded as soon as they are complete + +**Disadvantages:** +- The greedy scoring (counting how many uncovered pairs each candidate covers) can be expensive for large parameter spaces +- Tie-breaking and pair ordering significantly affect output size + +## IPOG: One Parameter at a Time + +``` +start with all N-way combinations of the first N parameters +for each remaining parameter P: + for each existing row: + extend with the value of P that covers the most new pairs + if uncovered pairs remain: + add new rows to cover them +``` + +**Advantages:** +- Efficient for many parameters with few values — the incremental extension avoids rescanning all pairs +- Tends to produce smaller arrays for high-parameter-count inputs + +**Disadvantages:** +- Adding a column to existing rows can conflict with constraints already satisfied +- The algorithm must handle "horizontal growth" (new rows) and "vertical growth" (extending rows) separately +- Not naturally streaming — the array is mutated in place across iterations + +## How CoverTable Works + +CoverTable's generation loop follows the AETG pattern with several enhancements: + +### Phase 1: Greedy Pair Selection + +The `greedy` criterion scans uncovered pairs and selects the one that would **remove the most entries from the uncovered set** when added to the current row. This is the AETG-style "maximize coverage" heuristic. + +The `simple` criterion skips this scoring and picks the first compatible uncovered pair. This is much faster but produces larger output. + +The `tolerance` parameter allows the greedy criterion to accept a "good enough" pair early, trading a small increase in output size for significant speedup. + +### Phase 2: Close (Backtracking Completion) + +After greedy selection fills some factors, the remaining unfilled factors are completed using **depth-first backtracking**. Values are tried in weight-descending order. At each step, constraint feasibility is checked via `storableCheck` and `forwardCheck`. + +This is where CoverTable diverges most from classic AETG: rather than greedily selecting every value, it lets the backtracking solver find a valid completion. This ensures constraint satisfaction without sacrificing coverage. + +### Complementary Pass + +After the main loop, some pairs may remain uncovered — for example, pairs that were incompatible with every row the greedy phase constructed. These leftover pairs are each set as the starting point of a new row, which is then completed via close. This ensures maximum coverage even when the greedy heuristic misses edge cases. + +```mermaid +flowchart LR + A[Uncovered pairs] --> B[Greedy selection] + B --> C[Close] + C --> D{Row complete?} + D -->|yes| E[Yield row] + D -->|no| B + E -->|pairs remain| A + E -->|all covered| F[Done] + A -->|greedy exhausted| G[Complementary pass] + G --> F +``` + +## Why CoverTable Resembles AETG + +CoverTable's algorithm was not modeled after AETG, but the row-by-row greedy approach turned out to be a natural fit for several reasons: + +1. **Constraint integration** — Three-valued evaluation and forward checking fit naturally into row-by-row construction. Each candidate pair is validated against the partial row before committing. IPOG's column extension would require re-validating entire rows after each extension. + +2. **Streaming output** — `makeAsync()` yields rows as they are completed. IPOG mutates existing rows when extending columns, making incremental output difficult. + +3. **Simplicity** — The "build one row, yield it, repeat" loop is straightforward to implement, test, and debug across both Python and TypeScript. + +4. **Deterministic ordering** — CoverTable's hash-based pair sorter produces deterministic output without a global RNG. IPOG's column-extension order is inherently tied to parameter declaration order, making it harder to control output variation via a simple salt. + +## Trade-offs in Practice + +| Scenario | AETG (CoverTable) | IPOG | +|---|---|---| +| Few parameters, many values (e.g. 10^20) | Greedy scoring is fast; good output size | Column extension adds many new rows | +| Many parameters, few values (e.g. 2^100) | Greedy scoring is expensive (many pairs) — use `simple` or `tolerance` | Incremental extension is efficient | +| Complex constraints | Forward checking prunes candidates during row construction | Must validate after column extension; may need row replacement | +| Streaming / progress reporting | Natural — yield per row | Difficult — rows are mutated across iterations | + +:::tip +For large parameter spaces where `greedy` is slow, use the `simple` criterion or set a positive `tolerance` to trade output size for speed. +::: diff --git a/docs/sidebars.ts b/docs/sidebars.ts index 4285368..2324487 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -25,7 +25,7 @@ const sidebars: SidebarsConfig = { { type: 'category', label: 'Development', - items: ['development/typescript', 'development/python', 'development/constraint-logic'], + items: ['development/algorithm', 'development/constraint-logic', 'development/typescript', 'development/python'], }, { type: 'category', From b61fca3a1d0ef365ca49ac55cb8627745146a3da Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 21:04:51 +0900 Subject: [PATCH 75/79] v3.0.0 --- python/setup.cfg | 2 +- typescript/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/setup.cfg b/python/setup.cfg index 182be52..1c547cd 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = covertable -version = 3.0.0rc2 +version = 3.0.0 author = righ author_email = righ.m9@gmail.com url = https://covertable.walkframe.com diff --git a/typescript/package.json b/typescript/package.json index 3c5da4c..7766642 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "covertable", - "version": "3.0.0-rc.2", + "version": "3.0.0", "description": "Efficient TypeScript library for pairwise testing, generating minimal covering arrays with constraint support.", "homepage": "https://covertable.walkframe.com", "repository": { From 9ec0ed54e843bde67483bfd07067829e887f55dc Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 21:18:42 +0900 Subject: [PATCH 76/79] fix: README --- README.md | 2 -- python/README.rst | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 560f465..a44b913 100644 --- a/README.md +++ b/README.md @@ -36,14 +36,12 @@ CoverTable is available in two implementations, with TypeScript as the primary f Works in both **Node.js** and **browsers** (ESM/CJS dual build). - [README](https://github.com/walkframe/covertable/blob/master/typescript/README.md) -- [History](https://github.com/walkframe/covertable/blob/master/typescript/history.md) ### Python [![PyPI Version](https://badge.fury.io/py/covertable.svg)](https://badge.fury.io/py/covertable) [![Build Status](https://github.com/walkframe/covertable/actions/workflows/python.yaml/badge.svg)](https://github.com/walkframe/covertable/actions/workflows/python.yaml) - [README](https://github.com/walkframe/covertable/blob/master/python/README.rst) -- [History](https://github.com/walkframe/covertable/blob/master/python/history.md) ## Documentation diff --git a/python/README.rst b/python/README.rst index bb48db4..83f69eb 100644 --- a/python/README.rst +++ b/python/README.rst @@ -90,7 +90,7 @@ Supported condition operators: - **Comparison**: ``eq``, ``ne``, ``gt``, ``lt``, ``gte``, ``lte``, ``in`` - **Logical**: ``and``, ``or``, ``not`` -- **Custom**: ``custom`` (escape hatch with ``fields`` and ``evaluate`` callable) +- **Custom**: ``fn`` (escape hatch with ``requires`` and ``evaluate`` callable) Field-to-field comparison uses ``right``: From d54bebf51c27d47b116686a0ccf61d5f09ce0691 Mon Sep 17 00:00:00 2001 From: righ Date: Sat, 18 Apr 2026 23:14:44 +0900 Subject: [PATCH 77/79] update doc --- docs/contents/tools/pict-online.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contents/tools/pict-online.mdx b/docs/contents/tools/pict-online.mdx index 0225af9..73bacf8 100644 --- a/docs/contents/tools/pict-online.mdx +++ b/docs/contents/tools/pict-online.mdx @@ -12,7 +12,7 @@ A browser-based pairwise test case generator compatible with [Microsoft PICT](ht Write your model, click Generate, and get optimized test combinations instantly — no installation required. :::info[Privacy] -All processing runs entirely in your browser. No data is sent to any server. +All processing runs entirely in your browser. No data is sent to any server. Your model text is saved in the browser's session storage so it persists across page reloads, but it is automatically cleared when you close the tab. ::: From 80b9a2f6be50ee01896e0d4fb2d050ca81bcdff0 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Apr 2026 02:28:31 +0900 Subject: [PATCH 78/79] feat: about, privacy policy --- docs/docusaurus.config.ts | 20 ++++++ docs/package.json | 1 + docs/pnpm-lock.yaml | 3 + .../src/components/HomepageFeatures/index.tsx | 71 ------------------- .../HomepageFeatures/styles.module.css | 11 --- docs/src/pages/about.mdx | 34 +++++++++ docs/src/pages/markdown-page.mdx | 7 -- docs/src/pages/privacy-policy.mdx | 44 ++++++++++++ 8 files changed, 102 insertions(+), 89 deletions(-) delete mode 100644 docs/src/components/HomepageFeatures/index.tsx delete mode 100644 docs/src/components/HomepageFeatures/styles.module.css create mode 100644 docs/src/pages/about.mdx delete mode 100644 docs/src/pages/markdown-page.mdx create mode 100644 docs/src/pages/privacy-policy.mdx diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 07932ea..6a92752 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -31,6 +31,12 @@ const config: Config = { }, plugins: [ + [ + '@docusaurus/plugin-google-tag-manager', + { + containerId: 'GTM-WZFTP5F2', + }, + ], function covertablePlugin() { return { name: 'covertable-webpack-plugin', @@ -67,6 +73,7 @@ const config: Config = { ], ], + themeConfig: { image: 'img/covertable-social-card.png', colorMode: { @@ -129,6 +136,19 @@ const config: Config = { }, ], }, + { + title: 'Legal', + items: [ + { + label: 'About', + to: '/about', + }, + { + label: 'Privacy Policy', + to: '/privacy-policy', + }, + ], + }, ], copyright: `Copyright © ${new Date().getFullYear()} walkframe. Built with Docusaurus.`, }, diff --git a/docs/package.json b/docs/package.json index e401859..294f830 100644 --- a/docs/package.json +++ b/docs/package.json @@ -20,6 +20,7 @@ "@codemirror/view": "^6.41.0", "@docusaurus/core": "3.10.0", "@docusaurus/faster": "3.10.0", + "@docusaurus/plugin-google-tag-manager": "3.10.0", "@docusaurus/preset-classic": "3.10.0", "@docusaurus/theme-common": "^3.10.0", "@docusaurus/theme-mermaid": "^3.10.0", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 61672dc..78df163 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@docusaurus/faster': specifier: 3.10.0 version: 3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + '@docusaurus/plugin-google-tag-manager': + specifier: 3.10.0 + version: 3.10.0(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) '@docusaurus/preset-classic': specifier: 3.10.0 version: 3.10.0(@algolia/client-search@5.50.1)(@docusaurus/faster@3.10.0(@docusaurus/types@3.10.0(@swc/core@1.15.24)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.24)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2) diff --git a/docs/src/components/HomepageFeatures/index.tsx b/docs/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index c2551fb..0000000 --- a/docs/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import type {ReactNode} from 'react'; -import clsx from 'clsx'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: ReactNode; -}; - -const FeatureList: FeatureItem[] = [ - { - title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. - - ), - }, - { - title: 'Focus on What Matters', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, - description: ( - <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. - - ), - }, - { - title: 'Powered by React', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, - description: ( - <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. - - ), - }, -]; - -function Feature({title, Svg, description}: FeatureItem) { - return ( -
-
- -
-
- {title} -

{description}

-
-
- ); -} - -export default function HomepageFeatures(): ReactNode { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/docs/src/components/HomepageFeatures/styles.module.css b/docs/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2..0000000 --- a/docs/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/docs/src/pages/about.mdx b/docs/src/pages/about.mdx new file mode 100644 index 0000000..0a3f31d --- /dev/null +++ b/docs/src/pages/about.mdx @@ -0,0 +1,34 @@ +--- +title: About +--- + +# About CoverTable + +CoverTable is an open-source **N-wise covering array generator** for combinatorial testing, available in both TypeScript and Python. + +## What is Combinatorial Testing? + +When software has multiple parameters, testing every possible combination is often impractical. Combinatorial testing (also known as pairwise testing) generates a minimal set of test cases that covers all N-wise interactions between parameter values. This approach dramatically reduces the number of test cases while maintaining high defect detection rates. + +## Features + +- **N-wise coverage** with configurable strength (pairwise by default) +- **Constraint support** with three-valued logic and forward checking +- **PICT-format compatibility** via `PictModel` +- **Streaming output** via generators for incremental processing +- **Deterministic results** controlled by a hash-based sorter and salt +- **Sub-model support** for different strengths across parameter groups +- **TypeScript and Python** implementations with the same algorithm + +## Project + +CoverTable is developed and maintained by [walkframe](https://github.com/walkframe). + +- Source code: [GitHub](https://github.com/walkframe/covertable) +- TypeScript package: [npm](https://www.npmjs.com/package/covertable) +- Python package: [PyPI](https://pypi.org/project/covertable/) +- License: Apache 2.0 + +## Contact + +For bug reports, feature requests, or questions, please open an issue on our [GitHub repository](https://github.com/walkframe/covertable/issues). diff --git a/docs/src/pages/markdown-page.mdx b/docs/src/pages/markdown-page.mdx deleted file mode 100644 index 9756c5b..0000000 --- a/docs/src/pages/markdown-page.mdx +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages. diff --git a/docs/src/pages/privacy-policy.mdx b/docs/src/pages/privacy-policy.mdx new file mode 100644 index 0000000..d418712 --- /dev/null +++ b/docs/src/pages/privacy-policy.mdx @@ -0,0 +1,44 @@ +--- +title: Privacy Policy +--- + +# Privacy Policy + +Last updated: April 19, 2026 + +## Overview + +This Privacy Policy describes how the CoverTable documentation site ("we", "us", or "our") at covertable.walkframe.com handles information when you visit our site. + +## Information We Collect + +### Automatically Collected Information + +When you visit our site, certain information may be collected automatically, including: + +- IP address +- Browser type and version +- Pages visited and time spent +- Referring website + +### Analytics and Tag Management + +This site uses Google Tag Manager and Google Analytics, services provided by Google LLC. Google Tag Manager is used to load and manage measurement tags, and Google Analytics is used to understand how visitors use the site. These tools may use cookies and similar technologies to collect information about your visit, including pages viewed, time spent on the site, referring website, approximate location derived from IP address, and device and browser type. + +For more information about how Google uses data, please visit [Google's Privacy & Terms](https://policies.google.com/technologies/partner-sites). You can opt out of Google Analytics tracking by installing the [Google Analytics Opt-out Browser Add-on](https://tools.google.com/dlpage/gaoptout). + +## Third-Party Links + +Our site contains links to external services such as GitHub, npm, and PyPI. We are not responsible for the privacy practices of these third-party sites. + +## Children's Privacy + +Our site is not directed at children under the age of 13. We do not knowingly collect personal information from children. + +## Changes to This Policy + +We may update this Privacy Policy from time to time. Changes will be posted on this page with an updated revision date. + +## Contact + +If you have any questions about this Privacy Policy, please contact us via our [GitHub repository](https://github.com/walkframe/covertable/issues). From 29230ec6ed01e9367563b7880f3bf67f2f693918 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 19 Apr 2026 04:57:46 +0900 Subject: [PATCH 79/79] fix: doc --- docs/contents/tools/pict-online.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contents/tools/pict-online.mdx b/docs/contents/tools/pict-online.mdx index 73bacf8..8af2449 100644 --- a/docs/contents/tools/pict-online.mdx +++ b/docs/contents/tools/pict-online.mdx @@ -42,7 +42,7 @@ IF [os] = "iOS" THEN [machine] = "iPhone"; const rows = model.make(); ``` -If you only want to apply constraints to factors you already have in code, you can pass `model.filter` directly to `make` as a `preFilter`: +If you only want to apply constraints to factors you already have in code, you can pass `model.constraints` to `make`: ```typescript import { make } from "covertable"; @@ -62,7 +62,7 @@ IF [os] = "iOS" THEN [machine] = "iPhone"; `); make({ machine, os, browser }, { - preFilter: model.filter, + constraints: model.constraints, }); ```